summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/cell/ppu
diff options
context:
space:
mode:
authorRobert Ellison <[email protected]>2008-10-30 15:24:23 -0600
committerRobert Ellison <[email protected]>2008-10-30 15:24:52 -0600
commit711f8a1dd94e2e1e715615d947e03015ef972326 (patch)
tree4365c6e97f3705b754714702dbbe2cff2ccac53b /src/gallium/drivers/cell/ppu
parent157ddc14183807834068687f02c67b66acf9effa (diff)
CELL: stencil bug fixes
Two definitive bugs in stenciling were fixed. The first, reversed registers in the generated Select Bytes (selb) instruction, caused the stenciling INCR and DECR operations to fail dramatically, putting new values in where old values were supposed to be and vice versa. The second caused stencil tiles to not be read and written from main memory by the SPUs. A per-spu flag, spu.read_depth, was used to indicate whether the SPU should be reading depth tiles, and was set only when depth was enabled. A second flag, spu.read_stencil, was set when stenciling was enabled, but never referenced. As stenciling and depth are in the same tiles on the Cell, and there is no corresponding TAG_WRITE_TILE_STENCIL to complement TAG_WRITE_TILE_COLOR and TAG_WRITE_TILE_Z, I fixed this by eliminating the unused "spu.read_stencil", renaming "spu.read_depth" to "spu.read_depth_stencil", and setting it if either stenciling or depth is enabled. I also added an optimization to the fragment ops generation code, that avoids calculating stencil values and/or stencil writemask when the stencil operations are all KEEP.
Diffstat (limited to 'src/gallium/drivers/cell/ppu')
-rw-r--r--src/gallium/drivers/cell/ppu/cell_gen_fragment.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
index 4e1e53ecdc7..8e4dd824043 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
@@ -1282,7 +1282,7 @@ gen_stencil_values(struct spe_function *f, unsigned int stencil_op,
/* Add Word Immediate computes rT = rA + 10-bit signed immediate */
spe_ai(f, newS_reg, fbS_reg, 1);
/* Select from the current value or the new value based on the equality test */
- spe_selb(f, newS_reg, fbS_reg, newS_reg, equals_reg);
+ spe_selb(f, newS_reg, newS_reg, fbS_reg, equals_reg);
spe_release_register(f, equals_reg);
break;
@@ -1295,7 +1295,7 @@ gen_stencil_values(struct spe_function *f, unsigned int stencil_op,
/* Add Word Immediate with a (-1) value works */
spe_ai(f, newS_reg, fbS_reg, -1);
/* Select from the current value or the new value based on the equality test */
- spe_selb(f, newS_reg, fbS_reg, newS_reg, equals_reg);
+ spe_selb(f, newS_reg, newS_reg, fbS_reg, equals_reg);
spe_release_register(f, equals_reg);
break;
@@ -1534,15 +1534,28 @@ gen_stencil_depth_test(struct spe_function *f,
* meaning that we have to calculate the stencil values but do not
* need to mask them), we can avoid generating code. Don't forget
* that we need to consider backfacing stencil, if enabled.
+ *
+ * Note that if the backface stencil is *not* enabled, the backface
+ * stencil will have the same values as the frontface stencil.
*/
- if (dsa->stencil[0].write_mask == 0x0 && (!dsa->stencil[1].enabled || dsa->stencil[1].write_mask == 0x00)) {
- /* Trivial: don't need to calculate stencil values, and don't need to
- * write them back to the framebuffer.
+ if (dsa->stencil[0].fail_op == PIPE_STENCIL_OP_KEEP &&
+ dsa->stencil[0].zfail_op == PIPE_STENCIL_OP_KEEP &&
+ dsa->stencil[0].zpass_op == PIPE_STENCIL_OP_KEEP &&
+ dsa->stencil[1].fail_op == PIPE_STENCIL_OP_KEEP &&
+ dsa->stencil[1].zfail_op == PIPE_STENCIL_OP_KEEP &&
+ dsa->stencil[1].zpass_op == PIPE_STENCIL_OP_KEEP) {
+ /* No changes to any stencil values */
+ need_to_calculate_stencil_values = false;
+ need_to_writemask_stencil_values = false;
+ }
+ else if (dsa->stencil[0].write_mask == 0x0 && dsa->stencil[1].write_mask == 0x0) {
+ /* All changes are writemasked out, so no need to calculate
+ * what those changes might be, and no need to write anything back.
*/
need_to_calculate_stencil_values = false;
need_to_writemask_stencil_values = false;
}
- else if (dsa->stencil[0].write_mask == 0xff && (!dsa->stencil[1].enabled || dsa->stencil[1].write_mask == 0xff)) {
+ else if (dsa->stencil[0].write_mask == 0xff && dsa->stencil[1].write_mask == 0xff) {
/* Still trivial, but a little less so. We need to write the stencil
* values, but we don't need to mask them.
*/