summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/cell/ppu
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-01-02 18:53:33 -0700
committerBrian <brian.paul@tungstengraphics.com>2008-01-02 18:53:33 -0700
commitde9f8e8b717aa4b4ab94af73be5aa70088cd6b81 (patch)
tree0ce4fc6110517e7ccdf5a3781663c80adfe516ae /src/mesa/pipe/cell/ppu
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')
-rw-r--r--src/mesa/pipe/cell/ppu/cell_context.c5
-rw-r--r--src/mesa/pipe/cell/ppu/cell_context.h3
-rw-r--r--src/mesa/pipe/cell/ppu/cell_flush.c3
-rw-r--r--src/mesa/pipe/cell/ppu/cell_render.c73
-rw-r--r--src/mesa/pipe/cell/ppu/cell_render.h3
-rw-r--r--src/mesa/pipe/cell/ppu/cell_surface.c8
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 82b69ac33e..fb89837a7c 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 5f6f987d8f..be985820d1 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 b1ff0e51cd..47003bef18 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 c7f0cf6be6..672406aa23 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 d66e1bdb79..826dcbafeb 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 185eeb26e8..c487d0439a 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 */