brw_curbe.c File Reference

Include dependency graph for brw_curbe.c:

Go to the source code of this file.

Defines

#define FILE_DEBUG_FLAG   DEBUG_FALLBACKS

Functions

static void calculate_curbe_offsets (struct brw_context *brw)
void brw_upload_constant_buffer_state (struct brw_context *brw)
static void upload_constant_buffer (struct brw_context *brw)

Variables

struct brw_tracked_state brw_curbe_offsets
static float fixed_plane [6][4]
struct brw_tracked_state brw_constant_buffer


Define Documentation

#define FILE_DEBUG_FLAG   DEBUG_FALLBACKS

Definition at line 45 of file brw_curbe.c.


Function Documentation

void brw_upload_constant_buffer_state ( struct brw_context brw  ) 

Definition at line 142 of file brw_curbe.c.

References assert, brw_constant_buffer_state::bits0, BRW_CACHED_BATCH_STRUCT, CMD_CONST_BUFFER_STATE, brw_context::csize, brw_constant_buffer_state::header, header::length, brw_context::nr_cs_entries, brw_constant_buffer_state::nr_urb_entries, header::opcode, brw_context::urb, and brw_constant_buffer_state::urb_entry_size.

00143 {
00144    struct brw_constant_buffer_state cbs;
00145    memset(&cbs, 0, sizeof(cbs));
00146 
00147    /* It appears that this is the state packet for the CS unit, ie. the
00148     * urb entries detailed here are housed in the CS range from the
00149     * URB_FENCE command.
00150     */
00151    cbs.header.opcode = CMD_CONST_BUFFER_STATE;
00152    cbs.header.length = sizeof(cbs)/4 - 2;
00153 
00154    /* BRW_NEW_URB_FENCE */
00155    cbs.bits0.nr_urb_entries = brw->urb.nr_cs_entries;
00156    cbs.bits0.urb_entry_size = brw->urb.csize - 1;
00157 
00158    assert(brw->urb.nr_cs_entries);
00159    BRW_CACHED_BATCH_STRUCT(brw, &cbs);
00160 }

static void calculate_curbe_offsets ( struct brw_context brw  )  [static]

Definition at line 49 of file brw_curbe.c.

References align(), assert, brw_context::attribs, brw_state_flags::brw, brw_count_bits(), BRW_NEW_CURBE_OFFSETS, brw_context::clip_size, brw_context::clip_start, brw_context::curbe, DBG, brw_context::dirty, brw_vs_prog_data::max_const, brw_context::prog_data, brw_context::state, brw_context::total_size, brw_context::vs, brw_context::vs_size, brw_context::vs_start, brw_context::wm, brw_context::wm_size, and brw_context::wm_start.

00050 {
00051    /* CACHE_NEW_WM_PROG */
00052    unsigned nr_fp_regs = align(brw->wm.prog_data->max_const, 16);
00053 
00054    /* BRW_NEW_VERTEX_PROGRAM */
00055    unsigned nr_vp_regs = align(brw->vs.prog_data->max_const, 16);
00056    unsigned nr_clip_regs = 0;
00057    unsigned total_regs;
00058 
00059 #if 0
00060    /* BRW_NEW_CLIP ? */
00061    if (brw->attribs.Transform->ClipPlanesEnabled) {
00062       unsigned nr_planes = 6 + brw_count_bits(brw->attribs.Transform->ClipPlanesEnabled);
00063       nr_clip_regs = align(nr_planes * 4, 16);
00064    }
00065 #endif
00066 
00067 
00068    total_regs = nr_fp_regs + nr_vp_regs + nr_clip_regs;
00069 
00070    /* This can happen - what to do?  Probably rather than falling
00071     * back, the best thing to do is emit programs which code the
00072     * constants as immediate values.  Could do this either as a static
00073     * cap on WM and VS, or adaptively.
00074     *
00075     * Unfortunately, this is currently dependent on the results of the
00076     * program generation process (in the case of wm), so this would
00077     * introduce the need to re-generate programs in the event of a
00078     * curbe allocation failure.
00079     */
00080    /* Max size is 32 - just large enough to
00081     * hold the 128 parameters allowed by
00082     * the fragment and vertex program
00083     * api's.  It's not clear what happens
00084     * when both VP and FP want to use 128
00085     * parameters, though.
00086     */
00087    assert(total_regs <= 32);
00088 
00089    /* Lazy resize:
00090     */
00091    if (nr_fp_regs > brw->curbe.wm_size ||
00092        nr_vp_regs > brw->curbe.vs_size ||
00093        nr_clip_regs != brw->curbe.clip_size ||
00094        (total_regs < brw->curbe.total_size / 4 &&
00095         brw->curbe.total_size > 16)) {
00096 
00097       unsigned reg = 0;
00098 
00099       /* Calculate a new layout:
00100        */
00101       reg = 0;
00102       brw->curbe.wm_start = reg;
00103       brw->curbe.wm_size = nr_fp_regs; reg += nr_fp_regs;
00104       brw->curbe.clip_start = reg;
00105       brw->curbe.clip_size = nr_clip_regs; reg += nr_clip_regs;
00106       brw->curbe.vs_start = reg;
00107       brw->curbe.vs_size = nr_vp_regs; reg += nr_vp_regs;
00108       brw->curbe.total_size = reg;
00109 
00110 #if 0
00111       if (0)
00112          DBG("curbe wm %d+%d clip %d+%d vs %d+%d\n",
00113                       brw->curbe.wm_start,
00114                       brw->curbe.wm_size,
00115                       brw->curbe.clip_start,
00116                       brw->curbe.clip_size,
00117                       brw->curbe.vs_start,
00118                       brw->curbe.vs_size );
00119 #endif
00120 
00121       brw->state.dirty.brw |= BRW_NEW_CURBE_OFFSETS;
00122    }
00123 }

static void upload_constant_buffer ( struct brw_context brw  )  [static]

Definition at line 176 of file brw_curbe.c.

References assert, brw_context::attribs, brw_constant_buffer::bits0, BRW_BATCH_STRUCT, BRW_CONSTANT_BUFFER, BRW_GS_POOL, brw_pool_alloc(), brw_mem_pool::buffer, pipe_constant_buffer::buffer, brw_constant_buffer::buffer_address, brw_constant_buffer::buffer_length, pipe_winsys::buffer_map, brw_winsys::buffer_subdata_typed, pipe_winsys::buffer_unmap, brw_context::Clip, brw_context::clip_size, brw_context::clip_start, CMD_CONST_BUFFER, brw_context::Constants, brw_context::curbe, debug_printf(), brw_context::gs_offset, brw_constant_buffer::header, brw_vs_prog_data::imm_buf, brw_context::last_buf, brw_context::last_bufsz, brw_constant_buffer::length, brw_vs_prog_data::max_const, pipe_clip_state::nr, brw_vs_prog_data::num_consts, brw_vs_prog_data::num_imm, offset(), brw_constant_buffer::opcode, brw_context::pipe, brw_context::pool, brw_context::prog_data, pipe_constant_buffer::size, brw_context::total_size, pipe_clip_state::ucp, brw_constant_buffer::valid, brw_context::vs, brw_context::vs_size, brw_context::vs_start, brw_context::winsys, pipe_context::winsys, brw_context::wm, brw_context::wm_size, and brw_context::wm_start.

00177 {
00178    struct brw_mem_pool *pool = &brw->pool[BRW_GS_POOL];
00179    unsigned sz = brw->curbe.total_size;
00180    unsigned bufsz = sz * sizeof(float);
00181    float *buf;
00182    unsigned i;
00183 
00184 
00185    if (sz == 0) {
00186       struct brw_constant_buffer cb;
00187       cb.header.opcode = CMD_CONST_BUFFER;
00188       cb.header.length = sizeof(cb)/4 - 2;
00189       cb.header.valid = 0;
00190       cb.bits0.buffer_length = 0;
00191       cb.bits0.buffer_address = 0;
00192       BRW_BATCH_STRUCT(brw, &cb);
00193 
00194       if (brw->curbe.last_buf) {
00195          free(brw->curbe.last_buf);
00196          brw->curbe.last_buf = NULL;
00197          brw->curbe.last_bufsz  = 0;
00198       }
00199 
00200       return;
00201    }
00202 
00203    buf = (float *)malloc(bufsz);
00204 
00205    memset(buf, 0, bufsz);
00206 
00207    if (brw->curbe.wm_size) {
00208       unsigned offset = brw->curbe.wm_start * 16;
00209 
00210       /* First the constant buffer constants:
00211        */
00212       
00213       /* Then any internally generated constants: 
00214        */
00215       for (i = 0; i < brw->wm.prog_data->nr_internal_consts; i++)
00216          buf[offset + i] = brw->wm.prog_data->internal_const[i];
00217 
00218       assert(brw->wm.prog_data->max_const == 
00219              brw->wm.prog_data->nr_internal_consts);
00220    }
00221 
00222 
00223    /* The clipplanes are actually delivered to both CLIP and VS units.
00224     * VS uses them to calculate the outcode bitmasks.
00225     */
00226    if (brw->curbe.clip_size) {
00227       unsigned offset = brw->curbe.clip_start * 16;
00228       unsigned j;
00229 
00230       /* If any planes are going this way, send them all this way:
00231        */
00232       for (i = 0; i < 6; i++) {
00233          buf[offset + i * 4 + 0] = fixed_plane[i][0];
00234          buf[offset + i * 4 + 1] = fixed_plane[i][1];
00235          buf[offset + i * 4 + 2] = fixed_plane[i][2];
00236          buf[offset + i * 4 + 3] = fixed_plane[i][3];
00237       }
00238 
00239       /* Clip planes: BRW_NEW_CLIP:
00240        */
00241       for (j = 0; j < brw->attribs.Clip.nr; j++) {
00242          buf[offset + i * 4 + 0] = brw->attribs.Clip.ucp[j][0];
00243          buf[offset + i * 4 + 1] = brw->attribs.Clip.ucp[j][1];
00244          buf[offset + i * 4 + 2] = brw->attribs.Clip.ucp[j][2];
00245          buf[offset + i * 4 + 3] = brw->attribs.Clip.ucp[j][3];
00246          i++;
00247       }
00248    }
00249 
00250 
00251    if (brw->curbe.vs_size) {
00252       unsigned offset = brw->curbe.vs_start * 16;
00253       /*unsigned nr = vp->max_const;*/
00254       const struct pipe_constant_buffer *cbuffer = brw->attribs.Constants[0];
00255       struct pipe_winsys *ws = brw->pipe.winsys;
00256       /* FIXME: buffer size is num_consts + num_immediates */
00257       if (brw->vs.prog_data->num_consts) {
00258          /* map the vertex constant buffer and copy to curbe: */
00259          void *data = ws->buffer_map(ws, cbuffer->buffer, 0);
00260          /* FIXME: this is wrong. the cbuffer->size currently
00261           * represents size of consts + immediates. so if we'll
00262           * have both we'll copy over the end of the buffer
00263           * with the subsequent memcpy */
00264          memcpy(&buf[offset], data, cbuffer->size);
00265          ws->buffer_unmap(ws, cbuffer->buffer);
00266          offset += cbuffer->size;
00267       }
00268       /*immediates*/
00269       if (brw->vs.prog_data->num_imm) {
00270          memcpy(&buf[offset], brw->vs.prog_data->imm_buf,
00271                 brw->vs.prog_data->num_imm * 4 * sizeof(float));
00272       }
00273    }
00274 
00275    if (1) {
00276       for (i = 0; i < sz; i+=4)
00277          debug_printf("curbe %d.%d: %f %f %f %f\n", i/8, i&4,
00278                       buf[i+0], buf[i+1], buf[i+2], buf[i+3]);
00279 
00280       debug_printf("last_buf %p buf %p sz %d/%d cmp %d\n",
00281                    brw->curbe.last_buf, buf,
00282                    bufsz, brw->curbe.last_bufsz,
00283                    brw->curbe.last_buf ? memcmp(buf, brw->curbe.last_buf, bufsz) : -1);
00284    }
00285 
00286    if (brw->curbe.last_buf &&
00287        bufsz == brw->curbe.last_bufsz &&
00288        memcmp(buf, brw->curbe.last_buf, bufsz) == 0) {
00289       free(buf);
00290 /*       return; */
00291    }
00292    else {
00293       if (brw->curbe.last_buf)
00294          free(brw->curbe.last_buf);
00295       brw->curbe.last_buf = buf;
00296       brw->curbe.last_bufsz = bufsz;
00297 
00298 
00299       if (!brw_pool_alloc(pool,
00300                           bufsz,
00301                           1 << 6,
00302                           &brw->curbe.gs_offset)) {
00303          debug_printf("out of GS memory for curbe\n");
00304          assert(0);
00305          return;
00306       }
00307 
00308 
00309       /* Copy data to the buffer:
00310        */
00311       brw->winsys->buffer_subdata_typed(brw->winsys,
00312                                         pool->buffer, 
00313                                         brw->curbe.gs_offset, 
00314                                         bufsz, 
00315                                         buf,
00316                                         BRW_CONSTANT_BUFFER );
00317    }
00318 
00319    /* TODO: only emit the constant_buffer packet when necessary, ie:
00320       - contents have changed
00321       - offset has changed
00322       - hw requirements due to other packets emitted.
00323    */
00324    {
00325       struct brw_constant_buffer cb;
00326 
00327       memset(&cb, 0, sizeof(cb));
00328 
00329       cb.header.opcode = CMD_CONST_BUFFER;
00330       cb.header.length = sizeof(cb)/4 - 2;
00331       cb.header.valid = 1;
00332       cb.bits0.buffer_length = sz - 1;
00333       cb.bits0.buffer_address = brw->curbe.gs_offset >> 6;
00334 
00335       /* Because this provokes an action (ie copy the constants into the
00336        * URB), it shouldn't be shortcircuited if identical to the
00337        * previous time - because eg. the urb destination may have
00338        * changed, or the urb contents different to last time.
00339        *
00340        * Note that the data referred to is actually copied internally,
00341        * not just used in place according to passed pointer.
00342        *
00343        * It appears that the CS unit takes care of using each available
00344        * URB entry (Const URB Entry == CURBE) in turn, and issuing
00345        * flushes as necessary when doublebuffering of CURBEs isn't
00346        * possible.
00347        */
00348       BRW_BATCH_STRUCT(brw, &cb);
00349    }
00350 }


Variable Documentation

struct brw_tracked_state brw_constant_buffer

Initial value:

 {
   .dirty = {
      .brw  = ( 0x10  |
                0x1000  |
                0x10000  | 
                0x20000  | 
                0x40000 ),
      .cache = ( (1<<BRW_WM_PROG) )
   },
   .update = upload_constant_buffer
}

Definition at line 358 of file brw_curbe.c.

struct brw_tracked_state brw_curbe_offsets

Initial value:

 {
   .dirty = {
      .brw  = ( 0x10  |
                0x4000 ),
      .cache =  (1<<BRW_WM_PROG) 
   },
   .update = calculate_curbe_offsets
}

Definition at line 126 of file brw_curbe.c.

float fixed_plane[6][4] [static]

Initial value:

 {
   { 0,    0,   -1, 1 },
   { 0,    0,    1, 1 },
   { 0,   -1,    0, 1 },
   { 0,    1,    0, 1 },
   {-1,    0,    0, 1 },
   { 1,    0,    0, 1 }
}

Definition at line 163 of file brw_curbe.c.


Generated on Tue Sep 29 06:25:36 2009 for Gallium3D by  doxygen 1.5.4