From b108bea6b44c1abc6d61e3e47096e5122de89cd1 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 1 Feb 2008 09:27:57 -0700 Subject: [PATCH] Cell: store current tile status in cur_tile_status_c/z, add TILE_STATUS_GETTING --- src/mesa/pipe/cell/spu/spu_render.c | 36 +++++++++++++---- src/mesa/pipe/cell/spu/spu_tile.c | 1 + src/mesa/pipe/cell/spu/spu_tile.h | 8 +++- src/mesa/pipe/cell/spu/spu_tri.c | 62 +++++++++++++++++++++++------ src/mesa/pipe/cell/spu/spu_tri.h | 2 +- 5 files changed, 87 insertions(+), 22 deletions(-) diff --git a/src/mesa/pipe/cell/spu/spu_render.c b/src/mesa/pipe/cell/spu/spu_render.c index f506095116b..ca54a103bdc 100644 --- a/src/mesa/pipe/cell/spu/spu_render.c +++ b/src/mesa/pipe/cell/spu/spu_render.c @@ -95,13 +95,15 @@ static INLINE void get_cz_tiles(uint tx, uint ty) { if (spu.depth_stencil.depth.enabled) { - if (tile_status_z[ty][tx] != TILE_STATUS_CLEAR) { + if (cur_tile_status_z != TILE_STATUS_CLEAR) { get_tile(tx, ty, &ztile, TAG_READ_TILE_Z, 1); + cur_tile_status_z = TILE_STATUS_GETTING; } } - if (tile_status[ty][tx] != TILE_STATUS_CLEAR) { + if (cur_tile_status_c != TILE_STATUS_CLEAR) { get_tile(tx, ty, &ctile, TAG_READ_TILE_COLOR, 0); + cur_tile_status_c = TILE_STATUS_GETTING; } } @@ -112,14 +114,24 @@ get_cz_tiles(uint tx, uint ty) static INLINE void put_cz_tiles(uint tx, uint ty) { - if (tile_status_z[ty][tx] == TILE_STATUS_DIRTY) { + if (cur_tile_status_z == TILE_STATUS_DIRTY) { + /* tile was modified and needs to be written back */ put_tile(tx, ty, &ztile, TAG_WRITE_TILE_Z, 1); - tile_status_z[ty][tx] = TILE_STATUS_DEFINED; + cur_tile_status_z = TILE_STATUS_DEFINED; + } + else if (cur_tile_status_z == TILE_STATUS_GETTING) { + /* tile was never used */ + cur_tile_status_z = TILE_STATUS_DEFINED; } - if (tile_status[ty][tx] == TILE_STATUS_DIRTY) { + if (cur_tile_status_c == TILE_STATUS_DIRTY) { + /* tile was modified and needs to be written back */ put_tile(tx, ty, &ctile, TAG_WRITE_TILE_COLOR, 0); - tile_status[ty][tx] = TILE_STATUS_DEFINED; + cur_tile_status_c = TILE_STATUS_DEFINED; + } + else if (cur_tile_status_c == TILE_STATUS_GETTING) { + /* tile was never used */ + cur_tile_status_c = TILE_STATUS_DEFINED; } } @@ -238,8 +250,13 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) if (!my_tile(tx, ty)) continue; + cur_tile_status_c = tile_status[ty][tx]; + cur_tile_status_z = tile_status_z[ty][tx]; + get_cz_tiles(tx, ty); + uint drawn = 0; + /* loop over tris */ for (j = 0; j < render->num_indexes; j += 3) { const float *v0, *v1, *v2; @@ -248,13 +265,18 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr) v1 = (const float *) (vertices + indexes[j+1] * vertex_size); v2 = (const float *) (vertices + indexes[j+2] * vertex_size); - tri_draw(v0, v1, v2, tx, ty); + drawn += tri_draw(v0, v1, v2, tx, ty); } + //printf("SPU %u: drew %u of %u\n", spu.init.id, drawn, render->num_indexes/3); + /* write color/z tiles back to main framebuffer, if dirtied */ put_cz_tiles(tx, ty); wait_put_cz_tiles(); /* XXX seems unnecessary... */ + + tile_status[ty][tx] = cur_tile_status_c; + tile_status_z[ty][tx] = cur_tile_status_z; } if (Debug) diff --git a/src/mesa/pipe/cell/spu/spu_tile.c b/src/mesa/pipe/cell/spu/spu_tile.c index ca1352f9f8d..aea4785bc2f 100644 --- a/src/mesa/pipe/cell/spu/spu_tile.c +++ b/src/mesa/pipe/cell/spu/spu_tile.c @@ -37,6 +37,7 @@ tile_t ztile ALIGN16_ATTRIB; ubyte tile_status[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; ubyte tile_status_z[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; +ubyte cur_tile_status_c, cur_tile_status_z; void diff --git a/src/mesa/pipe/cell/spu/spu_tile.h b/src/mesa/pipe/cell/spu/spu_tile.h index 18d1b3c1173..1f123a2b7b4 100644 --- a/src/mesa/pipe/cell/spu/spu_tile.h +++ b/src/mesa/pipe/cell/spu/spu_tile.h @@ -51,12 +51,16 @@ extern tile_t ztile ALIGN16_ATTRIB; #define TILE_STATUS_CLEAR 1 -#define TILE_STATUS_DEFINED 2 /**< defined pixel data */ -#define TILE_STATUS_DIRTY 3 /**< modified, but not put back yet */ +#define TILE_STATUS_DEFINED 2 /**< defined in FB, but not in local store */ +#define TILE_STATUS_CLEAN 3 /**< in local store, but not changed */ +#define TILE_STATUS_DIRTY 4 /**< modified locally, but not put back yet */ +#define TILE_STATUS_GETTING 5 /**< mfc_get() called but not yet arrived */ extern ubyte tile_status[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; extern ubyte tile_status_z[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; +extern ubyte cur_tile_status_c, cur_tile_status_z; + void get_tile(uint tx, uint ty, tile_t *tile, int tag, int zBuf); diff --git a/src/mesa/pipe/cell/spu/spu_tri.c b/src/mesa/pipe/cell/spu/spu_tri.c index 08b8bf0c9c7..a32878d9178 100644 --- a/src/mesa/pipe/cell/spu/spu_tri.c +++ b/src/mesa/pipe/cell/spu/spu_tri.c @@ -299,16 +299,23 @@ do_depth_test(int x, int y, unsigned int mask) zvals.v = eval_z((float) x, (float) y); - if (tile_status_z[setup.ty][setup.tx] == TILE_STATUS_CLEAR) { + if (cur_tile_status_c == TILE_STATUS_CLEAR) { /* now, _really_ clear the tile */ clear_z_tile(&ztile); + cur_tile_status_z = TILE_STATUS_DIRTY; } - else if (tile_status_z[setup.ty][setup.tx] != TILE_STATUS_DIRTY) { + +#if 0 + if (cur_tile_status_z == TILE_STATUS_CLEAR) { + /* now, _really_ clear the tile */ + clear_z_tile(&ztile); + } + else if (cur_tile_status_z != TILE_STATUS_DIRTY) { /* make sure we've got the tile from main mem */ wait_on_mask(1 << TAG_READ_TILE_Z); } - tile_status_z[setup.ty][setup.tx] = TILE_STATUS_DIRTY; - + cur_tile_status_z = TILE_STATUS_DIRTY; +#endif if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { zvals.v = spu_mul(zvals.v, zscale16.v); @@ -380,6 +387,9 @@ do_depth_test(int x, int y, unsigned int mask) } } + if (mask) + cur_tile_status_z = TILE_STATUS_DIRTY; + return mask; } @@ -397,15 +407,15 @@ do_depth_test_simd(int x, int y, vector unsigned int quadmask) zvals.v = eval_z((float) x, (float) y); - if (tile_status_z[setup.ty][setup.tx] == TILE_STATUS_CLEAR) { + if (cur_tile_status_z == TILE_STATUS_CLEAR) { /* now, _really_ clear the tile */ clear_z_tile(&ztile); } - else if (tile_status_z[setup.ty][setup.tx] != TILE_STATUS_DIRTY) { + else if (cur_tile_status_z != TILE_STATUS_DIRTY) { /* make sure we've got the tile from main mem */ wait_on_mask(1 << TAG_READ_TILE_Z); } - tile_status_z[setup.ty][setup.tx] = TILE_STATUS_DIRTY; + cur_tile_status_z = TILE_STATUS_DIRTY; /* XXX fetch Z value sooner to hide latency here */ zmask = spu_cmpgt(ztile.f4[ix][iy].v, zvals.v); @@ -462,15 +472,23 @@ emit_quad( int x, int y, mask_t mask ) if (mask) #endif { - if (tile_status[setup.ty][setup.tx] == TILE_STATUS_CLEAR) { + if (cur_tile_status_c == TILE_STATUS_CLEAR) { /* now, _really_ clear the tile */ clear_c_tile(&ctile); } - else if (tile_status[setup.ty][setup.tx] != TILE_STATUS_DIRTY) { + +#if 0 + if (cur_tile_status_c == TILE_STATUS_CLEAR) { + /* now, _really_ clear the tile */ + clear_c_tile(&ctile); + cur_tile_status_c = TILE_STATUS_DIRTY; + } + else if (cur_tile_status_c != TILE_STATUS_DIRTY) { /* make sure we've got the tile from main mem */ wait_on_mask(1 << TAG_READ_TILE_COLOR); } - tile_status[setup.ty][setup.tx] = TILE_STATUS_DIRTY; +#endif + cur_tile_status_c = TILE_STATUS_DIRTY; #if SIMD_Z if (spu_extract(mask, 0)) @@ -970,7 +988,7 @@ static void subtriangle( struct edge *eleft, * Draw triangle into tile at (tx, ty) (tile coords) * The tile data should have already been fetched. */ -void +boolean tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty) { setup.tx = tx; @@ -985,7 +1003,7 @@ tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty) if (!setup_sort_vertices((struct vertex_header *) v0, (struct vertex_header *) v1, (struct vertex_header *) v2)) { - return; /* totally clipped */ + return FALSE; /* totally clipped */ } setup_tri_coefficients(); @@ -999,6 +1017,24 @@ tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty) /* init_constant_attribs( setup ); */ + if (cur_tile_status_c == TILE_STATUS_GETTING) { + /* wait for mfc_get() to complete */ + wait_on_mask(1 << TAG_READ_TILE_COLOR); + cur_tile_status_c = TILE_STATUS_CLEAN; + } + + ASSERT(cur_tile_status_c != TILE_STATUS_DEFINED); + + if (spu.depth_stencil.depth.enabled) { + if (cur_tile_status_z == TILE_STATUS_GETTING) { + /* wait for mfc_get() to complete */ + wait_on_mask(1 << TAG_READ_TILE_Z); + cur_tile_status_z = TILE_STATUS_CLEAN; + } + ASSERT(cur_tile_status_z != TILE_STATUS_DEFINED); + } + + if (setup.oneoverarea < 0.0) { /* emaj on left: */ @@ -1013,4 +1049,6 @@ tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty) } flush_spans(); + + return TRUE; } diff --git a/src/mesa/pipe/cell/spu/spu_tri.h b/src/mesa/pipe/cell/spu/spu_tri.h index 86c42b63394..aa694dd7c93 100644 --- a/src/mesa/pipe/cell/spu/spu_tri.h +++ b/src/mesa/pipe/cell/spu/spu_tri.h @@ -30,7 +30,7 @@ #define SPU_TRI_H -extern void +extern boolean tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty); -- 2.30.2