Cell: implemement basic Z testing

Also, improve some surface clearing code
This commit is contained in:
Brian 2008-01-09 14:10:59 -07:00
parent 934468296c
commit abee68a722
6 changed files with 124 additions and 51 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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",

View file

@ -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;

View file

@ -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
}