From 87a8a339d7c8973168ffb5e5506f7ec4b3a524ba Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 26 Jan 2008 19:38:16 -0700 Subject: Cell: added support for inlined vertex buffers. Small prims are now self-contained in batch buffers when space allows. --- src/mesa/pipe/cell/common.h | 1 + src/mesa/pipe/cell/ppu/cell_vbuf.c | 40 ++++++++++++++++------- src/mesa/pipe/cell/spu/spu_main.c | 66 ++++++++++++++++++++++---------------- 3 files changed, 68 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/mesa/pipe/cell/common.h b/src/mesa/pipe/cell/common.h index bdde166630..0b63ed39be 100644 --- a/src/mesa/pipe/cell/common.h +++ b/src/mesa/pipe/cell/common.h @@ -128,6 +128,7 @@ struct cell_command_render const ushort *index_data; float xmin, ymin, xmax, ymax; boolean inline_indexes; + boolean inline_verts; } ALIGN16_ATTRIB; diff --git a/src/mesa/pipe/cell/ppu/cell_vbuf.c b/src/mesa/pipe/cell/ppu/cell_vbuf.c index 59a4a2b6e9..ee572b3a51 100644 --- a/src/mesa/pipe/cell/ppu/cell_vbuf.c +++ b/src/mesa/pipe/cell/ppu/cell_vbuf.c @@ -39,8 +39,9 @@ #include "pipe/draw/draw_vbuf.h" -/** Allow render indexes to be inlined after RENDER command */ -#define ALLOW_INLINING 1 +/** Allow prim indexes, verts to be inlined after RENDER command */ +#define ALLOW_INLINE_INDEXES 1 +#define ALLOW_INLINE_VERTS 1 /** @@ -127,8 +128,10 @@ cell_vbuf_draw(struct vbuf_render *vbr, printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u indexes = [%u %u %u ...]\n", nr_indices, nr_vertices, indices[0], indices[1], indices[2]); - printf("ind space = %u, space = %u\n", - nr_indices * 2, cell_batch_free_space(cell)); + printf("ind space = %u, vert space = %u, space = %u\n", + nr_indices * 2, + nr_vertices * 4 * cell->vertex_info.size, + cell_batch_free_space(cell)); #endif /* compute x/y bounding box */ @@ -151,7 +154,8 @@ cell_vbuf_draw(struct vbuf_render *vbr, /* build/insert batch RENDER command */ { - const uint index_bytes = (nr_indices * 2 + 3) & ~0x3; + const uint index_bytes = ROUNDUP4(nr_indices * 2); + const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size; struct cell_command_render *render = (struct cell_command_render *) @@ -159,14 +163,8 @@ cell_vbuf_draw(struct vbuf_render *vbr, render->opcode = CELL_CMD_RENDER; render->prim_type = cvbr->prim; - render->num_verts = nr_vertices; - render->vertex_size = 4 * cell->vertex_info.size; - render->vertex_data = vertices; - ASSERT_ALIGN16(render->vertex_data); - render->num_indexes = nr_indices; - - if (ALLOW_INLINING && + if (ALLOW_INLINE_INDEXES && index_bytes <= cell_batch_free_space(cell)) { /* indices inlined, right after render cmd */ void *dst = cell_batch_alloc(cell, index_bytes); @@ -181,6 +179,24 @@ cell_vbuf_draw(struct vbuf_render *vbr, ASSERT_ALIGN16(render->index_data); } + render->vertex_size = 4 * cell->vertex_info.size; + render->num_verts = nr_vertices; + if (ALLOW_INLINE_VERTS && + render->inline_indexes && + vertex_bytes <= cell_batch_free_space(cell)) { + /* vertex data inlined, after indices */ + void *dst = cell_batch_alloc(cell, vertex_bytes); + memcpy(dst, vertices, vertex_bytes); + render->inline_verts = TRUE; + render->vertex_data = NULL; + } + else { + render->inline_verts = FALSE; + render->vertex_data = vertices; + ASSERT_ALIGN16(render->vertex_data); + } + + render->xmin = xmin; render->ymin = ymin; render->xmax = xmax; diff --git a/src/mesa/pipe/cell/spu/spu_main.c b/src/mesa/pipe/cell/spu/spu_main.c index 92be0b4a4a..0c83900a18 100644 --- a/src/mesa/pipe/cell/spu/spu_main.c +++ b/src/mesa/pipe/cell/spu/spu_main.c @@ -216,16 +216,21 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) ubyte vertex_data[CELL_MAX_VBUF_SIZE] ALIGN16_ATTRIB; ushort index_data[CELL_MAX_VBUF_INDEXES] ALIGN16_ATTRIB; const uint vertex_size = render->vertex_size; /* in bytes */ + const uint total_vertex_bytes = render->num_verts * vertex_size; + const ubyte *vertices; const ushort *indexes; + uint mask; uint i, j; if (Debug) { - printf("SPU %u: RENDER prim %u, num_vert=%u num_ind=%u inlined=%u\n", + printf("SPU %u: RENDER prim %u, num_vert=%u num_ind=%u " + "inline_vert=%u inline_ind=%u\n", spu.init.id, render->prim_type, render->num_verts, render->num_indexes, + render->inline_verts, render->inline_indexes); /* @@ -237,43 +242,28 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) render->index_data, render->vertex_data); } + ASSERT(sizeof(*render) % 4 == 0); ASSERT_ALIGN16(render->vertex_data); ASSERT_ALIGN16(render->index_data); /** - ** Get vertices + ** Get vertex, index buffers if not inlined **/ - { - const uint total_vertex_bytes = render->num_verts * vertex_size; - + if (!render->inline_verts) { ASSERT(total_vertex_bytes % 16 == 0); - /* get vertex data from main memory */ mfc_get(vertex_data, /* dest */ (unsigned int) render->vertex_data, /* src */ total_vertex_bytes, /* size */ TAG_VERTEX_BUFFER, 0, /* tid */ 0 /* rid */); - } - - /** - ** Get indexes - **/ - if (render->inline_indexes) { - /* indexes are right after the render command in the batch buffer */ - ASSERT(sizeof(*render) % 4 == 0); - indexes = (ushort *) (render + 1); - - *pos_incr = (render->num_indexes * 2 + 3) / 4; - - /* wait for vertex data */ - wait_on_mask_all(1 << TAG_VERTEX_BUFFER); + vertices = vertex_data; } - else { - /* indexes are in separate buffer */ + + if (!render->inline_indexes) { uint total_index_bytes; *pos_incr = 0; @@ -293,12 +283,34 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) TAG_INDEX_BUFFER, 0, /* tid */ 0 /* rid */); + } + + + /** + ** Get pointers to inlined indexes, verts, if present + **/ + if (render->inline_indexes) { + /* indexes are right after the render command in the batch buffer */ + indexes = (ushort *) (render + 1); + *pos_incr = (render->num_indexes * 2 + 3) / 4; - wait_on_mask_all((1 << TAG_VERTEX_BUFFER) | - (1 << TAG_INDEX_BUFFER)); + if (render->inline_verts) { + /* vertices are after indexes, if inlined */ + vertices = (const ubyte *) (render + 1) + *pos_incr * 4; + *pos_incr = *pos_incr + total_vertex_bytes / 4; + } } + /* wait for vertex and/or index buffers if not inlined */ + mask = 0x0; + if (!render->inline_verts) + mask |= (1 << TAG_VERTEX_BUFFER); + if (!render->inline_indexes) + mask |= (1 << TAG_INDEX_BUFFER); + wait_on_mask_all(mask); + + /** ** find tiles which intersect the prim bounding box **/ @@ -347,9 +359,9 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) for (j = 0; j < render->num_indexes; j += 3) { const float *v0, *v1, *v2; - v0 = (const float *) (vertex_data + indexes[j+0] * vertex_size); - v1 = (const float *) (vertex_data + indexes[j+1] * vertex_size); - v2 = (const float *) (vertex_data + indexes[j+2] * vertex_size); + v0 = (const float *) (vertices + indexes[j+0] * vertex_size); + v1 = (const float *) (vertices + indexes[j+1] * vertex_size); + v2 = (const float *) (vertices + indexes[j+2] * vertex_size); tri_draw(v0, v1, v2, tx, ty); } -- cgit v1.2.3