From c4ef36dec0aa5b8cd0293a6b12689bb68ad67ac5 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 28 Jan 2008 10:41:27 -0700 Subject: [PATCH] Cell: clean-up of render path Finally removed a number of unneeded flush commands. Vertex buffers are allocated from the general buffer pool, freed by SPUs when done. Still an occasional failed assertion (invalid batch buffer command)... --- src/mesa/pipe/cell/common.h | 12 +--- src/mesa/pipe/cell/ppu/cell_vbuf.c | 60 +++++----------- src/mesa/pipe/cell/spu/spu_main.c | 112 +++++------------------------ src/mesa/pipe/cell/spu/spu_main.h | 2 - 4 files changed, 38 insertions(+), 148 deletions(-) diff --git a/src/mesa/pipe/cell/common.h b/src/mesa/pipe/cell/common.h index 31637ed1cc8..d6e1dd4f7d5 100644 --- a/src/mesa/pipe/cell/common.h +++ b/src/mesa/pipe/cell/common.h @@ -68,7 +68,7 @@ * The low byte of a mailbox word contains the command opcode. * Remaining higher bytes are command specific. */ -#define CELL_CMD_OPCODE_MASK 0xf +#define CELL_CMD_OPCODE_MASK 0xff #define CELL_CMD_EXIT 1 #define CELL_CMD_CLEAR_SURFACE 2 @@ -113,10 +113,6 @@ struct cell_command_clear_surface } ALIGN16_ATTRIB; -#define CELL_MAX_VBUF_SIZE (16 * 1024) -#define CELL_MAX_VBUF_INDEXES 1024 - - struct cell_command_render { uint opcode; /**< CELL_CMD_RENDER */ @@ -125,14 +121,8 @@ struct cell_command_render uint vertex_size; /**< bytes per vertex */ uint dummy; /* XXX this dummy field works around a compiler bug */ uint num_indexes; -#if 0 - const void *vertex_data; -#else uint vertex_buf; /**< which cell->buffer[] contains the vertex data */ -#endif - 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 6e12e16fe0a..b2a25d767b7 100644 --- a/src/mesa/pipe/cell/ppu/cell_vbuf.c +++ b/src/mesa/pipe/cell/ppu/cell_vbuf.c @@ -39,9 +39,8 @@ #include "pipe/draw/draw_vbuf.h" -/** Allow prim indexes, verts to be inlined after RENDER command */ -#define ALLOW_INLINE_INDEXES 01 -#define ALLOW_INLINE_VERTS 0 +/** Allow vertex data to be inlined after RENDER command */ +#define ALLOW_INLINE_VERTS 1 /** @@ -52,12 +51,10 @@ struct cell_vbuf_render { struct vbuf_render base; struct cell_context *cell; - uint prim; - uint vertex_size; - void *vertex_buffer; -#if 1 - uint vertex_buf; -#endif + uint prim; /**< PIPE_PRIM_x */ + uint vertex_size; /**< in bytes */ + void *vertex_buffer; /**< just for debug, really */ + uint vertex_buf; /**< in [0, CELL_NUM_BUFFERS-1] */ }; @@ -84,15 +81,10 @@ cell_vbuf_allocate_vertices(struct vbuf_render *vbr, { struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); /*printf("Alloc verts %u * %u\n", vertex_size, nr_vertices);*/ -#if 0 - assert(!cvbr->vertex_buffer); - cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16); -#else + assert(cvbr->vertex_buf == ~0); cvbr->vertex_buf = cell_get_empty_buffer(cvbr->cell); cvbr->vertex_buffer = cvbr->cell->buffer[cvbr->vertex_buf]; - printf("%s vertex_buf = %u\n", __FUNCTION__, cvbr->vertex_buf); -#endif cvbr->vertex_size = vertex_size; return cvbr->vertex_buffer; } @@ -105,14 +97,13 @@ cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); struct cell_context *cell = cvbr->cell; - /*printf("Free verts %u * %u\n", vertex_size, vertices_used);*/ -#if 0 - align_free(vertices); -#else + /* printf("%s vertex_buf = %u count = %u\n", __FUNCTION__, cvbr->vertex_buf, vertices_used); + */ - { + /* Tell SPUs they can release the vert buf */ + if (cvbr->vertex_buf != ~0U) { struct cell_command_release_verts *release = (struct cell_command_release_verts *) cell_batch_alloc(cell, sizeof(struct cell_command_release_verts)); @@ -121,8 +112,7 @@ cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, } cvbr->vertex_buf = ~0; - cell_flush_int(&cell->pipe, 0x0);/*NEW*/ -#endif + cell_flush_int(&cell->pipe, 0x0); assert(vertices == cvbr->vertex_buffer); cvbr->vertex_buffer = NULL; @@ -166,7 +156,7 @@ cell_vbuf_draw(struct vbuf_render *vbr, printf("%u %u %u, ", indices[i+0], indices[i+1], indices[i+2]); } printf("\n"); -#elif 01 +#elif 0 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]); @@ -213,8 +203,6 @@ cell_vbuf_draw(struct vbuf_render *vbr, /* append indices after render command */ memcpy(render + 1, indices, nr_indices * 2); - render->inline_indexes = TRUE; - render->index_data = NULL; /* if there's room, append vertices after the indices, else leave * vertices in the original/separate buffer. @@ -222,30 +210,20 @@ cell_vbuf_draw(struct vbuf_render *vbr, 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; -#if 0 - render->vertex_data = NULL; -#else render->vertex_buf = ~0; -#endif } else { + /* vertex data in separate buffer */ render->inline_verts = FALSE; -#if 0 - render->vertex_data = vertices; - ASSERT_ALIGN16(render->vertex_data); -#else ASSERT(cvbr->vertex_buf >= 0); render->vertex_buf = cvbr->vertex_buf; -#endif } - render->xmin = xmin; render->ymin = ymin; render->xmax = xmax; @@ -253,7 +231,7 @@ cell_vbuf_draw(struct vbuf_render *vbr, } #if 0 - /* XXX this is temporary */ + /* helpful for debug */ cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT); #endif } @@ -279,17 +257,15 @@ cell_init_vbuf(struct cell_context *cell) cell->vbuf_render = CALLOC_STRUCT(cell_vbuf_render); -#if 0 - cell->vbuf_render->base.max_indices = CELL_MAX_VBUF_INDEXES; - cell->vbuf_render->base.max_vertex_buffer_bytes = CELL_MAX_VBUF_SIZE; -#else + /* The max number of indexes is what can fix into a batch buffer, + * minus the render and release-verts commands. + */ cell->vbuf_render->base.max_indices = (CELL_BUFFER_SIZE - sizeof(struct cell_command_render) - sizeof(struct cell_command_release_verts)) / sizeof(ushort); cell->vbuf_render->base.max_vertex_buffer_bytes = CELL_BUFFER_SIZE; -#endif cell->vbuf_render->base.get_vertex_info = cell_vbuf_get_vertex_info; cell->vbuf_render->base.allocate_vertices = cell_vbuf_allocate_vertices; diff --git a/src/mesa/pipe/cell/spu/spu_main.c b/src/mesa/pipe/cell/spu/spu_main.c index eb979718f85..5b50ec6953b 100644 --- a/src/mesa/pipe/cell/spu/spu_main.c +++ b/src/mesa/pipe/cell/spu/spu_main.c @@ -239,59 +239,45 @@ static void cmd_render(const struct cell_command_render *render, uint *pos_incr) { /* we'll DMA into these buffers */ - ubyte vertex_data[CELL_MAX_VBUF_SIZE] ALIGN16_ATTRIB; - ushort index_data[CELL_MAX_VBUF_INDEXES] ALIGN16_ATTRIB; + ubyte vertex_data[CELL_BUFFER_SIZE] 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 " - "inline_vert=%u inline_ind=%u\n", + "inline_vert=%u\n", spu.init.id, render->prim_type, render->num_verts, render->num_indexes, - render->inline_verts, - render->inline_indexes); + render->inline_verts); /* printf(" bound: %g, %g .. %g, %g\n", render->xmin, render->ymin, render->xmax, render->ymax); */ - /* - printf("SPU %u: indices at %p vertices at %p\n", - spu.init.id, - render->index_data, render->vertex_data); - */ } ASSERT(sizeof(*render) % 4 == 0); -#if 0 - ASSERT_ALIGN16(render->vertex_data); -#else -#endif - ASSERT_ALIGN16(render->index_data); + ASSERT(total_vertex_bytes % 16 == 0); + /* indexes are right after the render command in the batch buffer */ + indexes = (const ushort *) (render + 1); + *pos_incr = (render->num_indexes * 2 + 3) / 4; - /** - ** Get vertex, index buffers if not inlined - **/ - if (!render->inline_verts) { - void *src; - ASSERT(total_vertex_bytes % 16 == 0); - -#if 0 - src = render->vertex_data; -#else - spu.cur_vertex_buf = render->vertex_buf; - src = spu.init.buffers[render->vertex_buf]; -#endif + if (render->inline_verts) { + /* Vertices are right after indexes in batch buffer */ + vertices = (const ubyte *) (render + 1) + *pos_incr * 4; + *pos_incr = *pos_incr + total_vertex_bytes / 4; + } + else { + /* Begin DMA fetch of vertex buffer */ + void *src = spu.init.buffers[render->vertex_buf]; mfc_get(vertex_data, /* dest */ (unsigned int) src, total_vertex_bytes, /* size */ @@ -300,63 +286,11 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) 0 /* rid */); vertices = vertex_data; - } - - if (!render->inline_indexes) { - uint total_index_bytes; - - *pos_incr = 0; - - total_index_bytes = render->num_indexes * sizeof(ushort); - if (total_index_bytes < 16) - total_index_bytes = 16; - else - total_index_bytes = ROUNDUP16(total_index_bytes); - indexes = index_data; - - /* get index data from main memory */ - mfc_get(index_data, /* dest */ - (unsigned int) render->index_data, /* src */ - total_index_bytes, - 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; - - 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; - spu.cur_vertex_buf = ~0; - } + wait_on_mask(1 << TAG_VERTEX_BUFFER); } - /* 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); - -#if 0 - if (!render->inline_verts) { - printf("SPU %u: release vbuf %u\n", spu.init.id, render->vertex_buf); - release_buffer(render->vertex_buf); - } -#endif - /** ** find tiles which intersect the prim bounding box **/ @@ -372,7 +306,7 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) #endif /* make sure any pending clears have completed */ - wait_on_mask(1 << TAG_SURFACE_CLEAR); + wait_on_mask(1 << TAG_SURFACE_CLEAR); /* XXX temporary */ /** @@ -405,14 +339,6 @@ 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; - if (indexes[j] == 0xffff) { - printf("index[%u] = 0xffff\n", j); - } - - ASSERT(indexes[j] != 0xffff); - ASSERT(indexes[j+1] != 0xffff); - ASSERT(indexes[j+2] != 0xffff); - 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); @@ -450,8 +376,8 @@ cmd_release_verts(const struct cell_command_release_verts *release) { if (Debug) printf("SPU %u: RELEASE VERTS %u\n", - spu.init.id, spu.cur_vertex_buf); - ASSERT(spu.cur_vertex_buf == release->vertex_buf); + spu.init.id, release->vertex_buf); + ASSERT(release->vertex_buf != ~0U); release_buffer(release->vertex_buf); } diff --git a/src/mesa/pipe/cell/spu/spu_main.h b/src/mesa/pipe/cell/spu/spu_main.h index 68c7263b7f9..5bc5d9fa99d 100644 --- a/src/mesa/pipe/cell/spu/spu_main.h +++ b/src/mesa/pipe/cell/spu/spu_main.h @@ -65,8 +65,6 @@ struct spu_global /* XXX more state to come */ - uint cur_vertex_buf; - } ALIGN16_ATTRIB; -- 2.30.2