cell_vbuf.c File Reference

Include dependency graph for cell_vbuf.c:

Go to the source code of this file.

Data Structures

struct  cell_vbuf_render
 Subclass of vbuf_render because we need a cell_context pointer in a few places. More...

Defines

#define ALLOW_INLINE_VERTS   1
 Vertex buffer code.

Functions

static struct cell_vbuf_rendercell_vbuf_render (struct vbuf_render *vbr)
 cast wrapper
static struct vertex_infocell_vbuf_get_vertex_info (struct vbuf_render *vbr)
static void * cell_vbuf_allocate_vertices (struct vbuf_render *vbr, ushort vertex_size, ushort nr_vertices)
static void cell_vbuf_release_vertices (struct vbuf_render *vbr, void *vertices, unsigned vertex_size, unsigned vertices_used)
static boolean cell_vbuf_set_primitive (struct vbuf_render *vbr, unsigned prim)
static void cell_vbuf_draw (struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
static void cell_vbuf_destroy (struct vbuf_render *vbr)
void cell_init_vbuf (struct cell_context *cell)
 Initialize the post-transform vertex buffer information for the given context.


Define Documentation

#define ALLOW_INLINE_VERTS   1

Vertex buffer code.

The draw module transforms vertices to window coords, etc. and emits the vertices into buffer supplied by this module. When a vertex buffer is full, or we flush, we'll send the vertex data to the SPUs.

Authors Brian Paul Allow vertex data to be inlined after RENDER command

Definition at line 49 of file cell_vbuf.c.


Function Documentation

void cell_init_vbuf ( struct cell_context cell  ) 

Initialize the post-transform vertex buffer information for the given context.

Definition at line 272 of file cell_vbuf.c.

References vbuf_render::allocate_vertices, assert, cell_vbuf_render::base, CALLOC_STRUCT, cell_vbuf_render::cell, CELL_BUFFER_SIZE, cell_vbuf_allocate_vertices(), cell_vbuf_destroy(), cell_vbuf_draw(), cell_vbuf_get_vertex_info(), cell_vbuf_release_vertices(), cell_vbuf_set_primitive(), vbuf_render::destroy, vbuf_render::draw, cell_context::draw, draw_vbuf_stage(), vbuf_render::get_vertex_info, vbuf_render::max_indices, vbuf_render::max_vertex_buffer_bytes, vbuf_render::release_vertices, vbuf_render::set_primitive, cell_context::vbuf, cell_context::vbuf_render, and cell_vbuf_render::vertex_buf.

00273 {
00274    assert(cell->draw);
00275 
00276    cell->vbuf_render = CALLOC_STRUCT(cell_vbuf_render);
00277 
00278    /* The max number of indexes is what can fix into a batch buffer,
00279     * minus the render and release-verts commands.
00280     */
00281    cell->vbuf_render->base.max_indices
00282       = (CELL_BUFFER_SIZE
00283          - sizeof(struct cell_command_render)
00284          - sizeof(struct cell_command_release_verts))
00285       / sizeof(ushort);
00286    cell->vbuf_render->base.max_vertex_buffer_bytes = CELL_BUFFER_SIZE;
00287 
00288    cell->vbuf_render->base.get_vertex_info = cell_vbuf_get_vertex_info;
00289    cell->vbuf_render->base.allocate_vertices = cell_vbuf_allocate_vertices;
00290    cell->vbuf_render->base.set_primitive = cell_vbuf_set_primitive;
00291    cell->vbuf_render->base.draw = cell_vbuf_draw;
00292    cell->vbuf_render->base.release_vertices = cell_vbuf_release_vertices;
00293    cell->vbuf_render->base.destroy = cell_vbuf_destroy;
00294 
00295    cell->vbuf_render->cell = cell;
00296 #if 1
00297    cell->vbuf_render->vertex_buf = ~0;
00298 #endif
00299 
00300    cell->vbuf = draw_vbuf_stage(cell->draw, &cell->vbuf_render->base);
00301 }

static void* cell_vbuf_allocate_vertices ( struct vbuf_render vbr,
ushort  vertex_size,
ushort  nr_vertices 
) [static]

Definition at line 85 of file cell_vbuf.c.

References assert, cell_vbuf_render::cell, cell_get_empty_buffer(), cell_vbuf_render(), cell_vbuf_render::vertex_buf, cell_vbuf_render::vertex_buffer, and cell_vbuf_render::vertex_size.

00087 {
00088    struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
00089    /*printf("Alloc verts %u * %u\n", vertex_size, nr_vertices);*/
00090 
00091    assert(cvbr->vertex_buf == ~0);
00092    cvbr->vertex_buf = cell_get_empty_buffer(cvbr->cell);
00093    cvbr->vertex_buffer = cvbr->cell->buffer[cvbr->vertex_buf];
00094    cvbr->vertex_size = vertex_size;
00095    return cvbr->vertex_buffer;
00096 }

static void cell_vbuf_destroy ( struct vbuf_render vbr  )  [static]

Definition at line 259 of file cell_vbuf.c.

References cell_vbuf_render::cell, cell_vbuf_render(), FREE, and cell_context::vbuf_render.

00260 {
00261    struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
00262    cvbr->cell->vbuf_render = NULL;
00263    FREE(cvbr);
00264 }

static void cell_vbuf_draw ( struct vbuf_render vbr,
const ushort indices,
uint  nr_indices 
) [static]

Definition at line 140 of file cell_vbuf.c.

References ALLOW_INLINE_VERTS, ASSERT, cell_vbuf_render::cell, cell_batch_alloc(), cell_batch_alloc_aligned(), cell_batch_free_space(), CELL_CMD_RENDER, cell_flush_int(), CELL_FLUSH_WAIT, cell_vbuf_render(), FALSE, cell_command_render::inline_verts, cell_command_render::min_index, cell_command_render::num_indexes, cell_command_render::num_verts, cell_command_render::opcode, PIPE_PRIM_TRIANGLES, cell_vbuf_render::prim, cell_command_render::prim_type, ROUNDUP8, vertex_info::size, TRUE, cell_vbuf_render::vertex_buf, cell_command_render::vertex_buf, cell_vbuf_render::vertex_buffer, cell_context::vertex_info, cell_command_render::vertex_size, cell_vbuf_render::vertex_size, cell_command_render::xmax, cell_command_render::xmin, cell_command_render::ymax, and cell_command_render::ymin.

00143 {
00144    struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
00145    struct cell_context *cell = cvbr->cell;
00146    float xmin, ymin, xmax, ymax;
00147    uint i;
00148    uint nr_vertices = 0, min_index = ~0;
00149    const void *vertices = cvbr->vertex_buffer;
00150    const uint vertex_size = cvbr->vertex_size;
00151 
00152    for (i = 0; i < nr_indices; i++) {
00153       if (indices[i] > nr_vertices)
00154          nr_vertices = indices[i];
00155       if (indices[i] < min_index)
00156          min_index = indices[i];
00157    }
00158    nr_vertices++;
00159 
00160 #if 0
00161    /*if (min_index > 0)*/
00162       printf("%s min_index = %u\n", __FUNCTION__, min_index);
00163 #endif
00164 
00165 #if 0
00166    printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u\n",
00167           nr_indices, nr_vertices);
00168    printf("  ");
00169    for (i = 0; i < nr_indices; i += 3) {
00170       printf("%u %u %u, ", indices[i+0], indices[i+1], indices[i+2]);
00171    }
00172    printf("\n");
00173 #elif 0
00174    printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u  indexes = [%u %u %u ...]\n",
00175           nr_indices, nr_vertices,
00176           indices[0], indices[1], indices[2]);
00177    printf("ind space = %u, vert space = %u, space = %u\n",
00178           nr_indices * 2,
00179           nr_vertices * 4 * cell->vertex_info.size,
00180           cell_batch_free_space(cell));
00181 #endif
00182 
00183    /* compute x/y bounding box */
00184    xmin = ymin = 1e50;
00185    xmax = ymax = -1e50;
00186    for (i = min_index; i < nr_vertices; i++) {
00187       const float *v = (float *) ((ubyte *) vertices + i * vertex_size);
00188       if (v[0] < xmin)
00189          xmin = v[0];
00190       if (v[0] > xmax)
00191          xmax = v[0];
00192       if (v[1] < ymin)
00193          ymin = v[1];
00194       if (v[1] > ymax)
00195          ymax = v[1];
00196    }
00197 #if 0
00198    printf("PPU Bounds %g, %g .. %g, %g\n", xmin, ymin, xmax, ymax);
00199    fflush(stdout);
00200 #endif
00201 
00202    if (cvbr->prim != PIPE_PRIM_TRIANGLES)
00203       return; /* only render tris for now */
00204 
00205    /* build/insert batch RENDER command */
00206    {
00207       const uint index_bytes = ROUNDUP8(nr_indices * 2);
00208       const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size;
00209       const uint batch_size = sizeof(struct cell_command_render) + index_bytes;
00210 
00211       struct cell_command_render *render
00212          = (struct cell_command_render *)
00213          cell_batch_alloc(cell, batch_size);
00214 
00215       render->opcode = CELL_CMD_RENDER;
00216       render->prim_type = cvbr->prim;
00217 
00218       render->num_indexes = nr_indices;
00219       render->min_index = min_index;
00220 
00221       /* append indices after render command */
00222       memcpy(render + 1, indices, nr_indices * 2);
00223 
00224       /* if there's room, append vertices after the indices, else leave
00225        * vertices in the original/separate buffer.
00226        */
00227       render->vertex_size = 4 * cell->vertex_info.size;
00228       render->num_verts = nr_vertices;
00229       if (ALLOW_INLINE_VERTS &&
00230           min_index == 0 &&
00231           vertex_bytes + 16 <= cell_batch_free_space(cell)) {
00232          /* vertex data inlined, after indices, at 16-byte boundary */
00233          void *dst = cell_batch_alloc_aligned(cell, vertex_bytes, 16);
00234          memcpy(dst, vertices, vertex_bytes);
00235          render->inline_verts = TRUE;
00236          render->vertex_buf = ~0;
00237       }
00238       else {
00239          /* vertex data in separate buffer */
00240          render->inline_verts = FALSE;
00241          ASSERT(cvbr->vertex_buf >= 0);
00242          render->vertex_buf = cvbr->vertex_buf;
00243       }
00244 
00245       render->xmin = xmin;
00246       render->ymin = ymin;
00247       render->xmax = xmax;
00248       render->ymax = ymax;
00249    }
00250 
00251 #if 0
00252    /* helpful for debug */
00253    cell_flush_int(cell, CELL_FLUSH_WAIT);
00254 #endif
00255 }

static struct vertex_info* cell_vbuf_get_vertex_info ( struct vbuf_render vbr  )  [static, read]

Definition at line 77 of file cell_vbuf.c.

References cell_vbuf_render::cell, cell_vbuf_render(), and cell_context::vertex_info.

00078 {
00079    struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
00080    return &cvbr->cell->vertex_info;
00081 }

static void cell_vbuf_release_vertices ( struct vbuf_render vbr,
void *  vertices,
unsigned  vertex_size,
unsigned  vertices_used 
) [static]

Definition at line 100 of file cell_vbuf.c.

References assert, cell_vbuf_render::cell, cell_batch_alloc(), CELL_CMD_RELEASE_VERTS, cell_flush_int(), cell_vbuf_render(), cell_command_release_verts::opcode, cell_command_release_verts::vertex_buf, cell_vbuf_render::vertex_buf, and cell_vbuf_render::vertex_buffer.

00102 {
00103    struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
00104    struct cell_context *cell = cvbr->cell;
00105 
00106    /*
00107    printf("%s vertex_buf = %u  count = %u\n",
00108           __FUNCTION__, cvbr->vertex_buf, vertices_used);
00109    */
00110 
00111    /* Tell SPUs they can release the vert buf */
00112    if (cvbr->vertex_buf != ~0U) {
00113       struct cell_command_release_verts *release
00114          = (struct cell_command_release_verts *)
00115          cell_batch_alloc(cell, sizeof(struct cell_command_release_verts));
00116       release->opcode = CELL_CMD_RELEASE_VERTS;
00117       release->vertex_buf = cvbr->vertex_buf;
00118    }
00119 
00120    cvbr->vertex_buf = ~0;
00121    cell_flush_int(cell, 0x0);
00122 
00123    assert(vertices == cvbr->vertex_buffer);
00124    cvbr->vertex_buffer = NULL;
00125 }

static struct cell_vbuf_render* cell_vbuf_render ( struct vbuf_render vbr  )  [static, read]

cast wrapper

Definition at line 69 of file cell_vbuf.c.

00070 {
00071    return (struct cell_vbuf_render *) vbr;
00072 }

static boolean cell_vbuf_set_primitive ( struct vbuf_render vbr,
unsigned  prim 
) [static]

Definition at line 130 of file cell_vbuf.c.

References cell_vbuf_render(), cell_vbuf_render::prim, and TRUE.

00131 {
00132    struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
00133    cvbr->prim = prim;
00134    /*printf("cell_set_prim %u\n", prim);*/
00135    return TRUE;
00136 }


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