diff options
author | Brian <[email protected]> | 2008-01-02 18:53:33 -0700 |
---|---|---|
committer | Brian <[email protected]> | 2008-01-02 18:53:33 -0700 |
commit | de9f8e8b717aa4b4ab94af73be5aa70088cd6b81 (patch) | |
tree | 0ce4fc6110517e7ccdf5a3781663c80adfe516ae /src/mesa/pipe/cell/ppu | |
parent | da92ac01e80e8a83233b1d4a881503bfc2806a1a (diff) |
Cell: basic triangle rendering works.
The cell "render_stage" (last in the "draw" pipeline) emits vertices into
a buffer which is pulled by the SPUs in response to a "RENDER" command.
This is pretty much temporary/scaffold code for now.
Diffstat (limited to 'src/mesa/pipe/cell/ppu')
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_context.c | 5 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_context.h | 3 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_flush.c | 3 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_render.c | 73 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_render.h | 3 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_surface.c | 8 |
6 files changed, 92 insertions, 3 deletions
diff --git a/src/mesa/pipe/cell/ppu/cell_context.c b/src/mesa/pipe/cell/ppu/cell_context.c index 82b69ac33ed..fb89837a7cd 100644 --- a/src/mesa/pipe/cell/ppu/cell_context.c +++ b/src/mesa/pipe/cell/ppu/cell_context.c @@ -161,10 +161,13 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) { struct cell_context *cell; - cell = CALLOC_STRUCT(cell_context); + /* some fields need to be 16-byte aligned, so align the whole object */ + cell = (struct cell_context*) align_malloc(sizeof(struct cell_context), 16); if (!cell) return NULL; + memset(cell, 0, sizeof(*cell)); + cell->winsys = cws; cell->pipe.winsys = winsys; cell->pipe.destroy = cell_destroy_context; diff --git a/src/mesa/pipe/cell/ppu/cell_context.h b/src/mesa/pipe/cell/ppu/cell_context.h index 5f6f987d8f8..be985820d1c 100644 --- a/src/mesa/pipe/cell/ppu/cell_context.h +++ b/src/mesa/pipe/cell/ppu/cell_context.h @@ -34,6 +34,7 @@ #include "pipe/p_defines.h" #include "pipe/draw/draw_vertex.h" #include "cell_winsys.h" +#include "pipe/cell/common.h" struct cell_vertex_shader_state @@ -90,7 +91,7 @@ struct cell_context uint num_spus; - + struct cell_prim_buffer prim_buffer; }; diff --git a/src/mesa/pipe/cell/ppu/cell_flush.c b/src/mesa/pipe/cell/ppu/cell_flush.c index b1ff0e51cd4..47003bef184 100644 --- a/src/mesa/pipe/cell/ppu/cell_flush.c +++ b/src/mesa/pipe/cell/ppu/cell_flush.c @@ -29,6 +29,7 @@ #include "cell_context.h" #include "cell_flush.h" #include "cell_spu.h" +#include "cell_render.h" void @@ -39,6 +40,8 @@ cell_flush(struct pipe_context *pipe, unsigned flags) printf("%s\n", __FUNCTION__); + cell_flush_prim_buffer(cell); + /* Send CMD_FINISH to all SPUs */ for (i = 0; i < cell->num_spus; i++) { send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FINISH); diff --git a/src/mesa/pipe/cell/ppu/cell_render.c b/src/mesa/pipe/cell/ppu/cell_render.c index c7f0cf6be61..672406aa234 100644 --- a/src/mesa/pipe/cell/ppu/cell_render.c +++ b/src/mesa/pipe/cell/ppu/cell_render.c @@ -32,6 +32,7 @@ #include "cell_context.h" #include "cell_render.h" +#include "cell_spu.h" #include "pipe/p_util.h" #include "pipe/draw/draw_private.h" @@ -89,13 +90,85 @@ render_line(struct draw_stage *stage, struct prim_header *prim) } +/** Write a vertex into the prim buffer */ +static void +save_vertex(struct cell_prim_buffer *buf, uint pos, + const struct vertex_header *vert) +{ + uint attr, j; + + for (attr = 0; attr < 2; attr++) { + for (j = 0; j < 4; j++) { + buf->vertex[pos][attr][j] = vert->data[attr][j]; + } + } + + /* update bounding box */ + if (vert->data[0][0] < buf->xmin) + buf->xmin = vert->data[0][0]; + if (vert->data[0][0] > buf->xmax) + buf->xmax = vert->data[0][0]; + if (vert->data[0][1] < buf->ymin) + buf->ymin = vert->data[0][1]; + if (vert->data[0][1] > buf->ymax) + buf->ymax = vert->data[0][1]; +} + + static void render_tri(struct draw_stage *stage, struct prim_header *prim) { + struct render_stage *rs = render_stage(stage); + struct cell_context *cell = rs->cell; + struct cell_prim_buffer *buf = &cell->prim_buffer; + uint i; + printf("Cell render tri\n"); + + if (buf->num_verts + 3 > CELL_MAX_VERTS) { + cell_flush_prim_buffer(cell); + } + + i = buf->num_verts; + assert(i+2 <= CELL_MAX_VERTS); + save_vertex(buf, i+0, prim->v[0]); + save_vertex(buf, i+1, prim->v[1]); + save_vertex(buf, i+2, prim->v[2]); + buf->num_verts += 3; } +/** + * Send the a RENDER command to all SPUs to have them render the prims + * in the current prim_buffer. + */ +void +cell_flush_prim_buffer(struct cell_context *cell) +{ + uint i; + + if (cell->prim_buffer.num_verts == 0) + return; + + printf("*** Flushing prim buffer\n"); + for (i = 0; i < cell->num_spus; i++) { + struct cell_command_render *render = &cell_global.command[i].render; + render->prim_type = PIPE_PRIM_TRIANGLES; + render->num_verts = cell->prim_buffer.num_verts; + render->xmin = cell->prim_buffer.xmin; + render->ymin = cell->prim_buffer.ymin; + render->xmax = cell->prim_buffer.xmax; + render->ymax = cell->prim_buffer.ymax; + render->vertex_data = &cell->prim_buffer.vertex; + ASSERT_ALIGN16(render->vertex_data); + send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_RENDER); + } + + cell->prim_buffer.num_verts = 0; +} + + + static void render_destroy( struct draw_stage *stage ) { FREE( stage ); diff --git a/src/mesa/pipe/cell/ppu/cell_render.h b/src/mesa/pipe/cell/ppu/cell_render.h index d66e1bdb795..826dcbafeba 100644 --- a/src/mesa/pipe/cell/ppu/cell_render.h +++ b/src/mesa/pipe/cell/ppu/cell_render.h @@ -31,6 +31,9 @@ struct cell_context; struct draw_stage; +extern void +cell_flush_prim_buffer(struct cell_context *cell); + extern struct draw_stage *cell_draw_render_stage( struct cell_context *cell ); #endif /* CELL_RENDER_H */ diff --git a/src/mesa/pipe/cell/ppu/cell_surface.c b/src/mesa/pipe/cell/ppu/cell_surface.c index 185eeb26e85..c487d0439a4 100644 --- a/src/mesa/pipe/cell/ppu/cell_surface.c +++ b/src/mesa/pipe/cell/ppu/cell_surface.c @@ -51,8 +51,14 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, if (!ps->map) pipe_surface_map(ps); + if (pf_get_size(ps->format) != 4) { + printf("Cell: Skipping non 32bpp clear_surface\n"); + return; + } + for (i = 0; i < cell->num_spus; i++) { struct cell_command_framebuffer *fb = &cell_global.command[i].fb; + printf("%s %u start = 0x%x\n", __FUNCTION__, i, ps->map); fb->start = ps->map; fb->width = ps->width; fb->height = ps->height; @@ -66,7 +72,7 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_TILES); } -#if 1 +#if 0 /* XXX Draw a test triangle over the cleared surface */ for (i = 0; i < cell->num_spus; i++) { /* Same triangle data for all SPUs */ |