summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/cell/spu
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/spu
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/spu')
-rw-r--r--src/mesa/pipe/cell/spu/main.c95
-rw-r--r--src/mesa/pipe/cell/spu/main.h13
-rw-r--r--src/mesa/pipe/cell/spu/tri.c21
-rw-r--r--src/mesa/pipe/cell/spu/tri.h4
4 files changed, 119 insertions, 14 deletions
diff --git a/src/mesa/pipe/cell/spu/main.c b/src/mesa/pipe/cell/spu/main.c
index cc5eddb0f5..183397a5ff 100644
--- a/src/mesa/pipe/cell/spu/main.c
+++ b/src/mesa/pipe/cell/spu/main.c
@@ -37,6 +37,7 @@
#include "main.h"
#include "tri.h"
#include "pipe/cell/common.h"
+#include "pipe/p_defines.h"
/*
helpful headers:
@@ -48,6 +49,8 @@ volatile struct cell_init_info init;
struct framebuffer fb;
+uint tile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
+
int DefaultTag;
@@ -62,12 +65,12 @@ wait_on_mask(unsigned tag)
void
-get_tile(const struct framebuffer *fb, uint tx, uint ty, uint *tile)
+get_tile(const struct framebuffer *fb, uint tx, uint ty, uint *tile,
+ int tag)
{
uint offset = ty * fb->width_tiles + tx;
uint bytesPerTile = TILE_SIZE * TILE_SIZE * 4;
ubyte *src = (ubyte *) fb->start + offset * bytesPerTile;
- int tag = DefaultTag;
assert(tx < fb->width_tiles);
assert(ty < fb->height_tiles);
@@ -85,12 +88,12 @@ get_tile(const struct framebuffer *fb, uint tx, uint ty, uint *tile)
}
void
-put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile)
+put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile,
+ int tag)
{
uint offset = ty * fb->width_tiles + tx;
uint bytesPerTile = TILE_SIZE * TILE_SIZE * 4;
ubyte *dst = (ubyte *) fb->start + offset * bytesPerTile;
- int tag = DefaultTag;
assert(tx < fb->width_tiles);
assert(ty < fb->height_tiles);
@@ -100,7 +103,7 @@ put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile)
tile, (unsigned int) dst, bytesPerTile);
*/
mfc_put((void *) tile, /* src in local memory */
- (unsigned int) dst, /* dst in main mory */
+ (unsigned int) dst, /* dst in main memory */
bytesPerTile,
tag,
0, /* tid */
@@ -119,15 +122,19 @@ clear_tiles(const struct cell_command_clear_tiles *clear)
for (i = 0; i < TILE_SIZE * TILE_SIZE; i++)
tile[i] = clear->value;
+ /*
printf("SPU: %s num=%d w=%d h=%d\n",
__FUNCTION__, num_tiles, fb.width_tiles, fb.height_tiles);
+ */
+
for (i = init.id; i < num_tiles; i += init.num_spus) {
uint tx = i % fb.width_tiles;
uint ty = i / fb.width_tiles;
- put_tile(&fb, tx, ty, tile);
+ put_tile(&fb, tx, ty, tile, DefaultTag);
/* XXX we don't want this here, but it fixes bad tile results */
wait_on_mask(1 << DefaultTag);
}
+
}
@@ -155,6 +162,76 @@ triangle(const struct cell_command_triangle *tri)
+static void
+render(const struct cell_command_render *render)
+{
+ const uint num_tiles = fb.width_tiles * fb.height_tiles;
+ struct cell_prim_buffer prim_buffer ALIGN16_ATTRIB;
+ int tag = DefaultTag;
+ uint i, j;
+
+ /*
+ printf("SPU %u: RENDER buffer dst=%p src=%p size=%d\n",
+ init.id,
+ &prim_buffer, render->vertex_data, (int)sizeof(prim_buffer));
+ */
+
+ ASSERT_ALIGN16(render->vertex_data);
+ ASSERT_ALIGN16(&prim_buffer);
+
+ /* get vertex data from main memory */
+ mfc_get(&prim_buffer, /* dest */
+ (unsigned int) render->vertex_data, /* src */
+ sizeof(prim_buffer), /* bytes */
+ tag,
+ 0, /* tid */
+ 0 /* rid */);
+ wait_on_mask( 1 << tag ); /* XXX temporary */
+
+ /* loop over tiles */
+ for (i = init.id; i < num_tiles; i += init.num_spus) {
+ uint tx = i % fb.width_tiles;
+ uint ty = i / fb.width_tiles;
+
+ get_tile(&fb, tx, ty, (uint *) tile, DefaultTag);
+ wait_on_mask(1 << DefaultTag); /* XXX temporary */
+
+ assert(render->prim_type == PIPE_PRIM_TRIANGLES);
+
+ /* loop over tris */
+ for (j = 0; j < render->num_verts; j += 3) {
+ struct prim_header prim;
+
+ /*
+ printf(" %u: Triangle %g,%g %g,%g %g,%g\n",
+ init.id,
+ prim_buffer.vertex[j*3+0][0][0],
+ prim_buffer.vertex[j*3+0][0][1],
+ prim_buffer.vertex[j*3+1][0][0],
+ prim_buffer.vertex[j*3+1][0][1],
+ prim_buffer.vertex[j*3+2][0][0],
+ prim_buffer.vertex[j*3+2][0][1]);
+ */
+
+ /* pos */
+ COPY_4V(prim.v[0].data[0], prim_buffer.vertex[j+0][0]);
+ COPY_4V(prim.v[1].data[0], prim_buffer.vertex[j+1][0]);
+ COPY_4V(prim.v[2].data[0], prim_buffer.vertex[j+2][0]);
+
+ /* color */
+ COPY_4V(prim.v[0].data[1], prim_buffer.vertex[j+0][1]);
+ COPY_4V(prim.v[1].data[1], prim_buffer.vertex[j+1][1]);
+ COPY_4V(prim.v[2].data[1], prim_buffer.vertex[j+2][1]);
+
+ draw_triangle(&prim, tx, ty);
+ }
+
+ put_tile(&fb, tx, ty, (uint *) tile, DefaultTag);
+ wait_on_mask(1 << DefaultTag); /* XXX temp */
+ }
+}
+
+
/**
* Temporary/simple main loop for SPEs: Get a command, execute it, repeat.
*/
@@ -215,6 +292,12 @@ main_loop(void)
printf("SPU %u: TRIANGLE\n", init.id);
triangle(&cmd.tri);
break;
+ case CELL_CMD_RENDER:
+ printf("SPU %u: RENDER %u verts, prim %u\n",
+ init.id, cmd.render.num_verts, cmd.render.prim_type);
+ render(&cmd.render);
+ break;
+
case CELL_CMD_FINISH:
printf("SPU %u: FINISH\n", init.id);
/* wait for all outstanding DMAs to finish */
diff --git a/src/mesa/pipe/cell/spu/main.h b/src/mesa/pipe/cell/spu/main.h
index 8c2796387f..47ce4be4b4 100644
--- a/src/mesa/pipe/cell/spu/main.h
+++ b/src/mesa/pipe/cell/spu/main.h
@@ -37,13 +37,16 @@
extern volatile struct cell_init_info init;
struct framebuffer {
- void *start;
- uint width, height;
+ void *start; /**< addr of surface in main memory */
+ uint width, height; /**< size in pixels */
uint width_tiles, height_tiles; /**< width and height in tiles */
};
+/* XXX Collect these globals in a struct: */
+
extern struct framebuffer fb;
+extern uint tile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
extern int DefaultTag;
@@ -52,10 +55,12 @@ void
wait_on_mask(unsigned tag);
void
-get_tile(const struct framebuffer *fb, uint tx, uint ty, uint *tile);
+get_tile(const struct framebuffer *fb, uint tx, uint ty, uint *tile,
+ int tag);
void
-put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile);
+put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile,
+ int tag);
#endif /* MAIN_H */
diff --git a/src/mesa/pipe/cell/spu/tri.c b/src/mesa/pipe/cell/spu/tri.c
index cd648db360..ce759a5647 100644
--- a/src/mesa/pipe/cell/spu/tri.c
+++ b/src/mesa/pipe/cell/spu/tri.c
@@ -74,8 +74,6 @@
static int cliprect_minx, cliprect_maxx, cliprect_miny, cliprect_maxy;
-static uint tile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-
#endif
@@ -879,11 +877,26 @@ draw_triangle(struct prim_header *tri, uint tx, uint ty)
cliprect_maxx = (tx + 1) * TILE_SIZE;
cliprect_maxy = (ty + 1) * TILE_SIZE;
- get_tile(&fb, tx, ty, (uint *) tile);
+ get_tile(&fb, tx, ty, (uint *) tile, DefaultTag);
wait_on_mask(1 << DefaultTag);
setup_tri(tri);
- put_tile(&fb, tx, ty, (uint *) tile);
+ put_tile(&fb, tx, ty, (uint *) tile, DefaultTag);
wait_on_mask(1 << DefaultTag);
}
+
+
+void
+tri_draw(struct prim_header *tri, uint tx, uint ty)
+{
+ /* set clipping bounds to tile bounds */
+ cliprect_minx = tx * TILE_SIZE;
+ cliprect_miny = ty * TILE_SIZE;
+ cliprect_maxx = (tx + 1) * TILE_SIZE;
+ cliprect_maxy = (ty + 1) * TILE_SIZE;
+
+ setup_tri(tri);
+}
+
+
diff --git a/src/mesa/pipe/cell/spu/tri.h b/src/mesa/pipe/cell/spu/tri.h
index dc66ad0f47..576030579f 100644
--- a/src/mesa/pipe/cell/spu/tri.h
+++ b/src/mesa/pipe/cell/spu/tri.h
@@ -49,4 +49,8 @@ extern void
draw_triangle(struct prim_header *tri, uint tx, uint ty);
+extern void
+tri_draw(struct prim_header *tri, uint tx, uint ty);
+
+
#endif /* TRI_H */