summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-01-09 14:10:59 -0700
committerBrian <brian.paul@tungstengraphics.com>2008-01-09 17:50:37 -0700
commitabee68a7220e5ee16216caf22841ad934fb37334 (patch)
tree93fae779d4cbb11e4611b5ad3ca78ee1215d85db
parent934468296c33a04125e42e5d0f8747f65405a393 (diff)
Cell: implemement basic Z testing
Also, improve some surface clearing code
-rw-r--r--src/mesa/pipe/cell/common.h17
-rw-r--r--src/mesa/pipe/cell/ppu/cell_spu.c3
-rw-r--r--src/mesa/pipe/cell/ppu/cell_surface.c47
-rw-r--r--src/mesa/pipe/cell/spu/main.c44
-rw-r--r--src/mesa/pipe/cell/spu/main.h2
-rw-r--r--src/mesa/pipe/cell/spu/tri.c62
6 files changed, 124 insertions, 51 deletions
diff --git a/src/mesa/pipe/cell/common.h b/src/mesa/pipe/cell/common.h
index dff0b1f8ec..4c770f5c32 100644
--- a/src/mesa/pipe/cell/common.h
+++ b/src/mesa/pipe/cell/common.h
@@ -47,11 +47,11 @@
#define TILE_SIZE 32
-#define CELL_CMD_EXIT 1
-#define CELL_CMD_FRAMEBUFFER 2
-#define CELL_CMD_CLEAR_TILES 3
-#define CELL_CMD_FINISH 5
-#define CELL_CMD_RENDER 6
+#define CELL_CMD_EXIT 1
+#define CELL_CMD_FRAMEBUFFER 2
+#define CELL_CMD_CLEAR_SURFACE 3
+#define CELL_CMD_FINISH 4
+#define CELL_CMD_RENDER 5
/**
@@ -66,10 +66,11 @@ struct cell_command_framebuffer
/**
- * Clear framebuffer tiles to given value/color.
+ * Clear framebuffer to the given value/color.
*/
-struct cell_command_clear_tiles
+struct cell_command_clear_surface
{
+ uint surface; /**< Temporary: 0=color, 1=Z */
uint value;
} ALIGN16_ATTRIB;
@@ -87,7 +88,7 @@ struct cell_command_render
struct cell_command
{
struct cell_command_framebuffer fb;
- struct cell_command_clear_tiles clear;
+ struct cell_command_clear_surface clear;
struct cell_command_render render;
} ALIGN16_ATTRIB;
diff --git a/src/mesa/pipe/cell/ppu/cell_spu.c b/src/mesa/pipe/cell/ppu/cell_spu.c
index 15b89682fa..a7dbf24dd8 100644
--- a/src/mesa/pipe/cell/ppu/cell_spu.c
+++ b/src/mesa/pipe/cell/ppu/cell_spu.c
@@ -176,7 +176,8 @@ test_spus(struct cell_context *cell)
for (i = 0; i < cell->num_spus; i++) {
cell_global.command[i].clear.value = 0xff880044; /* XXX */
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_TILES);
+ cell_global.command[i].clear.surface = 0;
+ send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE);
}
finish_all(cell->num_spus);
diff --git a/src/mesa/pipe/cell/ppu/cell_surface.c b/src/mesa/pipe/cell/ppu/cell_surface.c
index 62e0febc0c..1e1548c8b6 100644
--- a/src/mesa/pipe/cell/ppu/cell_surface.c
+++ b/src/mesa/pipe/cell/ppu/cell_surface.c
@@ -47,42 +47,43 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
{
struct cell_context *cell = cell_context(pipe);
uint i;
+ uint surfIndex;
if (!ps->map)
pipe_surface_map(ps);
- if (pf_get_size(ps->format) != 4) {
- printf("Cell: Skipping non 32bpp clear_surface\n");
- return;
+ if (ps == cell->framebuffer.zbuf) {
+ surfIndex = 1;
}
-#if 0
- 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->color_start = ps->map;
- fb->width = ps->width;
- fb->height = ps->height;
- fb->color_format = ps->format;
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FRAMEBUFFER);
+ else {
+ surfIndex = 0;
}
-#endif
+
+ printf("Clear surf %u\n", surfIndex);
for (i = 0; i < cell->num_spus; i++) {
#if 1
uint clr = clearValue;
- /* XXX debug: clear color varied per-SPU to visualize tiles */
- if ((clr & 0xff) == 0)
- clr |= 64 + i * 8;
- if ((clr & 0xff00) == 0)
- clr |= (64 + i * 8) << 8;
- if ((clr & 0xff0000) == 0)
- clr |= (64 + i * 8) << 16;
- if ((clr & 0xff000000) == 0)
- clr |= (64 + i * 8) << 24;
+ if (surfIndex == 0) {
+ /* XXX debug: clear color varied per-SPU to visualize tiles */
+ if ((clr & 0xff) == 0)
+ clr |= 64 + i * 8;
+ if ((clr & 0xff00) == 0)
+ clr |= (64 + i * 8) << 8;
+ if ((clr & 0xff0000) == 0)
+ clr |= (64 + i * 8) << 16;
+ if ((clr & 0xff000000) == 0)
+ clr |= (64 + i * 8) << 24;
+ }
cell_global.command[i].clear.value = clr;
#else
cell_global.command[i].clear.value = clearValue;
#endif
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_TILES);
+ cell_global.command[i].clear.surface = surfIndex;
+ send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE);
}
+
+ /* XXX temporary */
+ cell_flush(&cell->pipe, 0x0);
+
}
diff --git a/src/mesa/pipe/cell/spu/main.c b/src/mesa/pipe/cell/spu/main.c
index 9580281971..1552452ab7 100644
--- a/src/mesa/pipe/cell/spu/main.c
+++ b/src/mesa/pipe/cell/spu/main.c
@@ -50,7 +50,7 @@ volatile struct cell_init_info init;
struct framebuffer fb;
uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-uint ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
+ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
int DefaultTag;
@@ -70,7 +70,7 @@ get_tile(const struct framebuffer *fb, uint tx, uint ty, uint *tile,
int tag, int zBuf)
{
const uint offset = ty * fb->width_tiles + tx;
- const uint bytesPerTile = TILE_SIZE * TILE_SIZE * 4;
+ const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? 2 : 4);
const ubyte *src = zBuf ? fb->depth_start : fb->color_start;
src += offset * bytesPerTile;
@@ -96,7 +96,7 @@ put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile,
int tag, int zBuf)
{
const uint offset = ty * fb->width_tiles + tx;
- const uint bytesPerTile = TILE_SIZE * TILE_SIZE * 4;
+ const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? 2 : 4);
ubyte *dst = zBuf ? fb->depth_start : fb->color_start;
dst += offset * bytesPerTile;
@@ -119,15 +119,22 @@ put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile,
static void
-clear_tiles(const struct cell_command_clear_tiles *clear)
+clear_surface(const struct cell_command_clear_surface *clear)
{
uint num_tiles = fb.width_tiles * fb.height_tiles;
uint i, j;
int tag = init.id;
- for (i = 0; i < TILE_SIZE; i++)
- for (j = 0; j < TILE_SIZE; j++)
- ctile[i][j] = clear->value;
+ if (clear->surface == 0) {
+ for (i = 0; i < TILE_SIZE; i++)
+ for (j = 0; j < TILE_SIZE; j++)
+ ctile[i][j] = clear->value;
+ }
+ else {
+ for (i = 0; i < TILE_SIZE; i++)
+ for (j = 0; j < TILE_SIZE; j++)
+ ztile[i][j] = clear->value;
+ }
/*
printf("SPU: %s num=%d w=%d h=%d\n",
@@ -137,7 +144,10 @@ clear_tiles(const struct cell_command_clear_tiles *clear)
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, (uint *) ctile, tag, 0);
+ if (clear->surface == 0)
+ put_tile(&fb, tx, ty, (uint *) ctile, tag, 0);
+ else
+ put_tile(&fb, tx, ty, (uint *) ztile, tag, 1);
/* XXX we don't want this here, but it fixes bad tile results */
wait_on_mask(1 << tag);
}
@@ -227,7 +237,7 @@ render(const struct cell_command_render *render)
get_tile(&fb, tx, ty, (uint *) ctile, tag, 0);
wait_on_mask(1 << tag); /* XXX temporary */
- if (fb.depth_format == PIPE_FORMAT_Z32_UNORM) {
+ if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
get_tile(&fb, tx, ty, (uint *) ztile, tag+1, 1);
wait_on_mask(1 << (tag+1)); /* XXX temporary */
}
@@ -265,7 +275,7 @@ render(const struct cell_command_render *render)
put_tile(&fb, tx, ty, (uint *) ctile, tag, 0);
wait_on_mask(1 << tag); /* XXX temp */
- if (fb.depth_format == PIPE_FORMAT_Z32_UNORM) {
+ if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
put_tile(&fb, tx, ty, (uint *) ztile, tag+1, 1);
wait_on_mask(1 << (tag+1)); /* XXX temporary */
}
@@ -313,11 +323,14 @@ main_loop(void)
exitFlag = 1;
break;
case CELL_CMD_FRAMEBUFFER:
- printf("SPU %u: FRAMEBUFFER: %d x %d at %p, format 0x%x\n", init.id,
+ printf("SPU %u: FRAMEBUFFER: %d x %d at %p, cformat 0x%x zformat 0x%x\n",
+ init.id,
cmd.fb.width,
cmd.fb.height,
cmd.fb.color_start,
- cmd.fb.color_format);
+ cmd.fb.color_format,
+ cmd.fb.depth_format);
+ printf("Z16 = 0x%x\n", PIPE_FORMAT_Z16_UNORM);
fb.color_start = cmd.fb.color_start;
fb.depth_start = cmd.fb.depth_start;
fb.color_format = cmd.fb.color_format;
@@ -331,9 +344,10 @@ main_loop(void)
init.id, fb.width_tiles, fb.height_tiles);
*/
break;
- case CELL_CMD_CLEAR_TILES:
- printf("SPU %u: CLEAR to 0x%08x\n", init.id, cmd.clear.value);
- clear_tiles(&cmd.clear);
+ case CELL_CMD_CLEAR_SURFACE:
+ printf("SPU %u: CLEAR SURF %u to 0x%08x\n", init.id,
+ cmd.clear.surface, cmd.clear.value);
+ clear_surface(&cmd.clear);
break;
case CELL_CMD_RENDER:
printf("SPU %u: RENDER %u verts, prim %u\n",
diff --git a/src/mesa/pipe/cell/spu/main.h b/src/mesa/pipe/cell/spu/main.h
index c22679c5d9..5e0516d0c1 100644
--- a/src/mesa/pipe/cell/spu/main.h
+++ b/src/mesa/pipe/cell/spu/main.h
@@ -50,7 +50,7 @@ struct framebuffer {
extern struct framebuffer fb;
extern uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-extern uint ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
+extern ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
extern int DefaultTag;
diff --git a/src/mesa/pipe/cell/spu/tri.c b/src/mesa/pipe/cell/spu/tri.c
index 36599297b9..58fca2e34a 100644
--- a/src/mesa/pipe/cell/spu/tri.c
+++ b/src/mesa/pipe/cell/spu/tri.c
@@ -227,6 +227,22 @@ eval_coeff( struct setup_stage *setup, uint slot,
}
+static INLINE void
+eval_z( struct setup_stage *setup,
+ float x, float y, float result[4])
+{
+ uint slot = 0;
+ uint i = 2;
+ const float *dadx = setup->coef[slot].dadx;
+ const float *dady = setup->coef[slot].dady;
+
+ result[QUAD_TOP_LEFT] = setup->coef[slot].a0[i] + x * dadx[i] + y * dady[i];
+ result[QUAD_TOP_RIGHT] = result[0] + dadx[i];
+ result[QUAD_BOTTOM_LEFT] = result[0] + dady[i];
+ result[QUAD_BOTTOM_RIGHT] = result[0] + dadx[i] + dady[i];
+}
+
+
static INLINE uint
pack_color(const float color[4])
{
@@ -263,9 +279,48 @@ emit_quad( struct setup_stage *setup, int x, int y, unsigned mask )
int ix = x - cliprect_minx;
int iy = y - cliprect_miny;
float colors[4][4];
+ uint z;
eval_coeff(setup, 1, (float) x, (float) y, colors);
+
+ if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
+ float zvals[4];
+ eval_z(setup, (float) x, (float) y, zvals);
+
+ if (mask & MASK_TOP_LEFT) {
+ z = (uint) (zvals[0] * 65535.0);
+ if (z < ztile[iy][ix])
+ ztile[iy][ix] = z;
+ else
+ mask &= ~MASK_TOP_LEFT;
+ }
+
+ if (mask & MASK_TOP_RIGHT) {
+ z = (uint) (zvals[1] * 65535.0);
+ if (z < ztile[iy][ix+1])
+ ztile[iy][ix+1] = z;
+ else
+ mask &= ~MASK_TOP_RIGHT;
+ }
+
+ if (mask & MASK_BOTTOM_LEFT) {
+ z = (uint) (zvals[2] * 65535.0);
+ if (z < ztile[iy+1][ix])
+ ztile[iy+1][ix] = z;
+ else
+ mask &= ~MASK_BOTTOM_LEFT;
+ }
+
+ if (mask & MASK_BOTTOM_RIGHT) {
+ z = (uint) (zvals[3] * 65535.0);
+ if (z < ztile[iy+1][ix+1])
+ ztile[iy+1][ix+1] = z;
+ else
+ mask &= ~MASK_BOTTOM_RIGHT;
+ }
+ }
+
if (mask & MASK_TOP_LEFT)
ctile[iy][ix] = pack_color(colors[QUAD_TOP_LEFT]);
if (mask & MASK_TOP_RIGHT)
@@ -512,10 +567,10 @@ static void const_coeff( struct setup_stage *setup,
* for a triangle.
*/
static void tri_linear_coeff( struct setup_stage *setup,
- unsigned slot )
+ uint slot, uint firstComp, uint lastComp )
{
uint i;
- for (i = 0; i < 4; i++) {
+ for (i = firstComp; i < lastComp; i++) {
float botda = setup->vmid->data[slot][i] - setup->vmin->data[slot][i];
float majda = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
@@ -637,7 +692,8 @@ static void setup_tri_coefficients( struct setup_stage *setup )
}
}
#else
- tri_linear_coeff(setup, 1); /* slot 1 = color */
+ tri_linear_coeff(setup, 0, 2, 3); /* slot 0, z */
+ tri_linear_coeff(setup, 1, 0, 4); /* slot 1, color */
#endif
}