Also, support 16 or 32-bit Z buffer at runtime.
really_clear_tiles(uint surfaceIndex)
{
const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
- uint i, j;
+ uint i;
if (surfaceIndex == 0) {
- for (i = 0; i < TILE_SIZE; i++)
- for (j = 0; j < TILE_SIZE; j++)
- ctile[i][j] = spu.fb.color_clear_value; /*0xff00ff;*/
+ clear_c_tile(ctile);
for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
uint tx = i % spu.fb.width_tiles;
}
}
else {
- for (i = 0; i < TILE_SIZE; i++)
- for (j = 0; j < TILE_SIZE; j++)
- ztile[i][j] = spu.fb.depth_clear_value;
+ clear_z_tile(&ztile);
for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
uint tx = i % spu.fb.width_tiles;
cmd_clear_surface(const struct cell_command_clear_surface *clear)
{
const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
- uint i, j;
+ uint i;
if (Debug)
printf("SPU %u: CLEAR SURF %u to 0x%08x\n", spu.init.id,
#endif
if (clear->surface == 0) {
- for (i = 0; i < TILE_SIZE; i++)
- for (j = 0; j < TILE_SIZE; j++)
- ctile[i][j] = clear->value;
+ spu.fb.color_clear_value = clear->value;
+ clear_c_tile(ctile);
}
else {
- for (i = 0; i < TILE_SIZE; i++)
- for (j = 0; j < TILE_SIZE; j++)
- ztile[i][j] = clear->value;
+ spu.fb.depth_clear_value = clear->value;
+ clear_z_tile(&ztile);
}
/*
if (clear->surface == 0)
put_tile(tx, ty, (uint *) ctile, TAG_SURFACE_CLEAR, 0);
else
- put_tile(tx, ty, (uint *) ztile, TAG_SURFACE_CLEAR, 1);
+ put_tile(tx, ty, (uint *) ztile.t32, TAG_SURFACE_CLEAR, 1);
/* XXX we don't want this here, but it fixes bad tile results */
}
*/
if (spu.depth_stencil.depth.enabled) {
if (tile_status_z[ty][tx] != TILE_STATUS_CLEAR) {
- get_tile(tx, ty, (uint *) ztile, TAG_READ_TILE_Z, 1);
+ get_tile(tx, ty, (uint *) ztile.t32, TAG_READ_TILE_Z, 1);
}
}
}
if (spu.depth_stencil.depth.enabled) {
if (tile_status_z[ty][tx] == TILE_STATUS_DIRTY) {
- put_tile(tx, ty, (uint *) ztile, TAG_WRITE_TILE_Z, 1);
+ put_tile(tx, ty, (uint *) ztile.t32, TAG_WRITE_TILE_Z, 1);
tile_status_z[ty][tx] = TILE_STATUS_DEFINED;
}
}
spu.fb.width_tiles = (spu.fb.width + TILE_SIZE - 1) / TILE_SIZE;
spu.fb.height_tiles = (spu.fb.height + TILE_SIZE - 1) / TILE_SIZE;
- if (cmd->depth_format == PIPE_FORMAT_Z16_UNORM) {
- ASSERT(ZSIZE == 2);
- }
- else if (cmd->depth_format == PIPE_FORMAT_Z32_UNORM) {
- ASSERT(ZSIZE == 4);
- }
-
+ if (spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM)
+ spu.fb.zsize = 4;
+ else if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM)
+ spu.fb.zsize = 2;
+ else
+ spu.fb.zsize = 0;
}
#include "pipe/cell/common.h"
#include "pipe/p_state.h"
-/** XXX temp bytes/z value */
-#define ZSIZE 2
struct spu_framebuffer {
void *color_start; /**< addr of color surface in main memory */
uint color_clear_value;
uint depth_clear_value;
+
+ uint zsize; /**< 0, 2 or 4 bytes per Z */
} ALIGN16_ATTRIB;
}
-void
+extern void
wait_on_mask(unsigned tag);
+static INLINE void
+memset16(ushort *d, ushort value, uint count)
+{
+ uint i;
+ for (i = 0; i < count; i++)
+ d[i] = value;
+}
+
+
+static INLINE void
+memset32(uint *d, uint value, uint count)
+{
+ uint i;
+ for (i = 0; i < count; i++)
+ d[i] = value;
+}
+
+
#endif /* SPU_MAIN_H */
uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-#if ZSIZE == 2
-ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-#else
-uint ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-#endif
+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;
get_tile(uint tx, uint ty, uint *tile, int tag, int zBuf)
{
const uint offset = ty * spu.fb.width_tiles + tx;
- const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? ZSIZE : 4);
+ const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? spu.fb.zsize : 4);
const ubyte *src = zBuf ? spu.fb.depth_start : spu.fb.color_start;
src += offset * bytesPerTile;
put_tile(uint tx, uint ty, const uint *tile, int tag, int zBuf)
{
const uint offset = ty * spu.fb.width_tiles + tx;
- const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? ZSIZE : 4);
+ const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? spu.fb.zsize : 4);
ubyte *dst = zBuf ? spu.fb.depth_start : spu.fb.color_start;
dst += offset * bytesPerTile;
0 /* rid */);
}
-
-void
-clear_tile(uint tile[TILE_SIZE][TILE_SIZE], uint value)
-{
- uint i, j;
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile[i][j] = value;
- }
- }
-}
-
-void
-clear_tile_z(
-#if ZSIZE == 2
- ushort tile[TILE_SIZE][TILE_SIZE],
-#else
- uint tile[TILE_SIZE][TILE_SIZE],
-#endif
- uint value)
-{
- uint i, j;
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile[i][j] = value;
- }
- }
-}
-
#define MAX_HEIGHT 1024
+typedef union {
+ ushort t16[TILE_SIZE][TILE_SIZE];
+ uint t32[TILE_SIZE][TILE_SIZE];
+} tile_t;
+
+
extern uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-#if ZSIZE == 2
-extern ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-#else
-extern uint ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-#endif
+extern tile_t ztile ALIGN16_ATTRIB;
#define TILE_STATUS_CLEAR 1
void
put_tile(uint tx, uint ty, const uint *tile, int tag, int zBuf);
-void
-clear_tile(uint tile[TILE_SIZE][TILE_SIZE], uint value);
-void
-clear_tile_z(
-#if ZSIZE == 2
- ushort tile[TILE_SIZE][TILE_SIZE],
-#else
- uint tile[TILE_SIZE][TILE_SIZE],
-#endif
- uint value);
+
+static INLINE void
+clear_c_tile(uint tile[TILE_SIZE][TILE_SIZE])
+{
+ memset32((uint*) tile, spu.fb.color_clear_value, TILE_SIZE * TILE_SIZE);
+}
+
+
+static INLINE void
+clear_z_tile(tile_t *ztile)
+{
+ if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
+ memset16((ushort*) ztile->t16,
+ spu.fb.depth_clear_value,
+ TILE_SIZE * TILE_SIZE);
+ }
+ else {
+ memset32((uint*) ztile->t32,
+ spu.fb.depth_clear_value,
+ TILE_SIZE * TILE_SIZE);
+ }
+}
#endif /* SPU_TILE_H */
int ix = x - setup->cliprect_minx;
int iy = y - setup->cliprect_miny;
float zvals[4];
- float zscale = 65535.0;
-
- if (ZSIZE == 2) {
- ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM);
- }
- else {
- ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM);
- }
- ASSERT(sizeof(ztile[0][0]) == ZSIZE);
-
eval_z(setup, (float) x, (float) y, zvals);
if (tile_status_z[setup->ty][setup->tx] == TILE_STATUS_CLEAR) {
/* now, _really_ clear the tile */
- clear_tile_z(ztile, spu.fb.depth_clear_value);
+ clear_z_tile(&ztile);
}
else {
/* make sure we've got the tile from main mem */
tile_status_z[setup->ty][setup->tx] = TILE_STATUS_DIRTY;
- if (mask & MASK_TOP_LEFT) {
- uint z = (uint) (zvals[0] * zscale);
- if (z < ztile[iy][ix])
- ztile[iy][ix] = z;
- else
- mask &= ~MASK_TOP_LEFT;
- }
+ if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
+ const float zscale = 65535.0;
+ if (mask & MASK_TOP_LEFT) {
+ uint z = (uint) (zvals[0] * zscale);
+ if (z < ztile.t16[iy][ix])
+ ztile.t16[iy][ix] = z;
+ else
+ mask &= ~MASK_TOP_LEFT;
+ }
- if (mask & MASK_TOP_RIGHT) {
- uint z = (uint) (zvals[1] * zscale);
- if (z < ztile[iy][ix+1])
- ztile[iy][ix+1] = z;
- else
- mask &= ~MASK_TOP_RIGHT;
- }
+ if (mask & MASK_TOP_RIGHT) {
+ uint z = (uint) (zvals[1] * zscale);
+ if (z < ztile.t16[iy][ix+1])
+ ztile.t16[iy][ix+1] = z;
+ else
+ mask &= ~MASK_TOP_RIGHT;
+ }
- if (mask & MASK_BOTTOM_LEFT) {
- uint z = (uint) (zvals[2] * zscale);
- if (z < ztile[iy+1][ix])
- ztile[iy+1][ix] = z;
- else
- mask &= ~MASK_BOTTOM_LEFT;
+ if (mask & MASK_BOTTOM_LEFT) {
+ uint z = (uint) (zvals[2] * zscale);
+ if (z < ztile.t16[iy+1][ix])
+ ztile.t16[iy+1][ix] = z;
+ else
+ mask &= ~MASK_BOTTOM_LEFT;
+ }
+
+ if (mask & MASK_BOTTOM_RIGHT) {
+ uint z = (uint) (zvals[3] * zscale);
+ if (z < ztile.t16[iy+1][ix+1])
+ ztile.t16[iy+1][ix+1] = z;
+ else
+ mask &= ~MASK_BOTTOM_RIGHT;
+ }
}
+ else {
+ const float zscale = (float) 0xffffffff;
+ ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM);
+ if (mask & MASK_TOP_LEFT) {
+ uint z = (uint) (zvals[0] * zscale);
+ if (z < ztile.t32[iy][ix])
+ ztile.t32[iy][ix] = z;
+ else
+ mask &= ~MASK_TOP_LEFT;
+ }
- if (mask & MASK_BOTTOM_RIGHT) {
- uint z = (uint) (zvals[3] * zscale);
- if (z < ztile[iy+1][ix+1])
- ztile[iy+1][ix+1] = z;
- else
- mask &= ~MASK_BOTTOM_RIGHT;
+ if (mask & MASK_TOP_RIGHT) {
+ uint z = (uint) (zvals[1] * zscale);
+ if (z < ztile.t32[iy][ix+1])
+ ztile.t32[iy][ix+1] = z;
+ else
+ mask &= ~MASK_TOP_RIGHT;
+ }
+
+ if (mask & MASK_BOTTOM_LEFT) {
+ uint z = (uint) (zvals[2] * zscale);
+ if (z < ztile.t32[iy+1][ix])
+ ztile.t32[iy+1][ix] = z;
+ else
+ mask &= ~MASK_BOTTOM_LEFT;
+ }
+
+ if (mask & MASK_BOTTOM_RIGHT) {
+ uint z = (uint) (zvals[3] * zscale);
+ if (z < ztile.t32[iy+1][ix+1])
+ ztile.t32[iy+1][ix+1] = z;
+ else
+ mask &= ~MASK_BOTTOM_RIGHT;
+ }
}
return mask;
if (mask) {
if (tile_status[setup->ty][setup->tx] == TILE_STATUS_CLEAR) {
/* now, _really_ clear the tile */
- clear_tile(ctile, spu.fb.color_clear_value);
+ clear_c_tile(ctile);
}
else {
/* make sure we've got the tile from main mem */