aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe/cell/ppu/cell_render.c
diff options
context:
space:
mode:
authorBrian <[email protected]>2008-01-02 18:53:33 -0700
committerBrian <[email protected]>2008-01-02 18:53:33 -0700
commitde9f8e8b717aa4b4ab94af73be5aa70088cd6b81 (patch)
tree0ce4fc6110517e7ccdf5a3781663c80adfe516ae /src/mesa/pipe/cell/ppu/cell_render.c
parentda92ac01e80e8a83233b1d4a881503bfc2806a1a (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/cell_render.c')
-rw-r--r--src/mesa/pipe/cell/ppu/cell_render.c73
1 files changed, 73 insertions, 0 deletions
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 );