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)...
This commit is contained in:
Brian 2008-01-28 10:41:27 -07:00
parent 7024019d4e
commit 5b5ec94663
4 changed files with 40 additions and 150 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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,62 +286,10 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
0 /* rid */);
vertices = vertex_data;
wait_on_mask(1 << TAG_VERTEX_BUFFER);
}
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 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);
}

View file

@ -65,8 +65,6 @@ struct spu_global
/* XXX more state to come */
uint cur_vertex_buf;
} ALIGN16_ATTRIB;