From abee68a7220e5ee16216caf22841ad934fb37334 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 9 Jan 2008 14:10:59 -0700 Subject: [PATCH] Cell: implemement basic Z testing Also, improve some surface clearing code --- src/mesa/pipe/cell/common.h | 17 +++++----- src/mesa/pipe/cell/ppu/cell_spu.c | 3 +- src/mesa/pipe/cell/ppu/cell_surface.c | 47 +++++++++++++------------- src/mesa/pipe/cell/spu/main.c | 44 ++++++++++++++++--------- src/mesa/pipe/cell/spu/main.h | 2 +- src/mesa/pipe/cell/spu/tri.c | 62 +++++++++++++++++++++++++++++++++-- 6 files changed, 124 insertions(+), 51 deletions(-) diff --git a/src/mesa/pipe/cell/common.h b/src/mesa/pipe/cell/common.h index dff0b1f8ec6..4c770f5c322 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 15b89682fa4..a7dbf24dd8f 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 62e0febc0c2..1e1548c8b61 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 9580281971a..1552452ab79 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 c22679c5d99..5e0516d0c15 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 36599297b98..58fca2e34a4 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 } -- 2.11.0