mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
cell: Fix various stencil test code-gen bugs
This commit is contained in:
parent
fa69a6e1bb
commit
fe40dae02d
1 changed files with 43 additions and 27 deletions
|
|
@ -199,52 +199,62 @@ emit_depth_test(struct pipe_depth_stencil_alpha_state *dsa,
|
|||
|
||||
/**
|
||||
* \note Emits a maximum of 5 instructions.
|
||||
*
|
||||
* \warning
|
||||
* Since \c out and \c in might be the same register, this routine cannot
|
||||
* generate code that uses \c out as a temporary.
|
||||
*/
|
||||
static void
|
||||
emit_stencil_op(struct spe_function *f,
|
||||
int out, int in, int mask, unsigned op, unsigned ref)
|
||||
{
|
||||
const int clamp = spe_allocate_available_register(f);
|
||||
const int tmp = spe_allocate_available_register(f);
|
||||
const int clamp_mask = spe_allocate_available_register(f);
|
||||
const int result = spe_allocate_available_register(f);
|
||||
|
||||
switch(op) {
|
||||
case PIPE_STENCIL_OP_KEEP:
|
||||
assert(0);
|
||||
case PIPE_STENCIL_OP_ZERO:
|
||||
spe_il(f, out, 0);
|
||||
spe_il(f, result, 0);
|
||||
break;
|
||||
case PIPE_STENCIL_OP_REPLACE:
|
||||
spe_il(f, out, ref);
|
||||
spe_il(f, result, ref);
|
||||
break;
|
||||
case PIPE_STENCIL_OP_INCR:
|
||||
spe_il(f, clamp, 0x0ff);
|
||||
spe_ai(f, out, in, 1);
|
||||
spe_cgti(f, tmp, out, clamp);
|
||||
spe_selb(f, out, out, clamp, tmp);
|
||||
spe_ai(f, result, in, 1);
|
||||
spe_clgti(f, clamp_mask, result, 0x0ff);
|
||||
spe_selb(f, result, result, clamp, clamp_mask);
|
||||
break;
|
||||
case PIPE_STENCIL_OP_DECR:
|
||||
spe_il(f, clamp, 0);
|
||||
spe_ai(f, out, in, -1);
|
||||
spe_cgti(f, tmp, out, clamp);
|
||||
spe_selb(f, out, clamp, out, tmp);
|
||||
spe_ai(f, result, in, -1);
|
||||
|
||||
/* If "(s-1) < 0" in signed arithemtic, then "(s-1) > MAX" in unsigned
|
||||
* arithmetic.
|
||||
*/
|
||||
spe_clgti(f, clamp_mask, result, 0x0ff);
|
||||
spe_selb(f, result, result, clamp, clamp_mask);
|
||||
break;
|
||||
case PIPE_STENCIL_OP_INCR_WRAP:
|
||||
spe_ai(f, out, in, 1);
|
||||
spe_ai(f, result, in, 1);
|
||||
break;
|
||||
case PIPE_STENCIL_OP_DECR_WRAP:
|
||||
spe_ai(f, out, in, -1);
|
||||
spe_ai(f, result, in, -1);
|
||||
break;
|
||||
case PIPE_STENCIL_OP_INVERT:
|
||||
spe_nor(f, out, in, in);
|
||||
spe_nor(f, result, in, in);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
spe_release_register(f, tmp);
|
||||
spe_release_register(f, clamp);
|
||||
spe_selb(f, out, in, result, mask);
|
||||
|
||||
spe_selb(f, out, in, out, mask);
|
||||
spe_release_register(f, result);
|
||||
spe_release_register(f, clamp_mask);
|
||||
spe_release_register(f, clamp);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -261,13 +271,13 @@ emit_stencil_op(struct spe_function *f,
|
|||
* \param stencil Register containing values from stencil buffer
|
||||
* \param depth_pass Register to store mask of fragments passing stencil test
|
||||
* and depth test
|
||||
*
|
||||
*
|
||||
* \note
|
||||
* Emits a maximum of 10 + (3 * 5) = 25 instructions.
|
||||
*/
|
||||
static int
|
||||
emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa,
|
||||
unsigned face,
|
||||
unsigned face,
|
||||
struct spe_function *f,
|
||||
int mask,
|
||||
int depth_mask,
|
||||
|
|
@ -284,14 +294,17 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa,
|
|||
const unsigned ref = (dsa->stencil[face].ref_value
|
||||
& dsa->stencil[face].value_mask);
|
||||
boolean complement = FALSE;
|
||||
int stored = spe_allocate_available_register(f);
|
||||
int stored;
|
||||
int tmp = spe_allocate_available_register(f);
|
||||
|
||||
|
||||
if ((dsa->stencil[face].func != PIPE_FUNC_NEVER)
|
||||
&& (dsa->stencil[face].func != PIPE_FUNC_ALWAYS)
|
||||
&& (dsa->stencil[face].value_mask != 0x0ff)) {
|
||||
stored = spe_allocate_available_register(f);
|
||||
spe_andi(f, stored, stencil, dsa->stencil[face].value_mask);
|
||||
} else {
|
||||
stored = stencil;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -332,7 +345,9 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa,
|
|||
break;
|
||||
}
|
||||
|
||||
spe_release_register(f, stored);
|
||||
if (stored != stencil) {
|
||||
spe_release_register(f, stored);
|
||||
}
|
||||
spe_release_register(f, tmp);
|
||||
|
||||
|
||||
|
|
@ -362,7 +377,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa,
|
|||
/* Conditionally emit code to update the stencil value under various
|
||||
* condititons. Note that there is no need to generate code under the
|
||||
* following circumstances:
|
||||
*
|
||||
*
|
||||
* - Stencil write mask is zero.
|
||||
* - For stencil-fail if the stencil test is ALWAYS
|
||||
* - For depth-fail if the stencil test is NEVER
|
||||
|
|
@ -425,7 +440,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa,
|
|||
spe_release_register(f, face_stencil);
|
||||
} else if (dsa->stencil[face].write_mask != 0x0ff) {
|
||||
int tmp = spe_allocate_available_register(f);
|
||||
|
||||
|
||||
spe_il(f, tmp, dsa->stencil[face].write_mask);
|
||||
spe_selb(f, stencil_src, stencil, stencil_src, tmp);
|
||||
|
||||
|
|
@ -492,12 +507,12 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa)
|
|||
if (front_stencil != back_stencil) {
|
||||
spe_selb(f, stencil, back_stencil, front_stencil, facing);
|
||||
}
|
||||
|
||||
if (back_stencil != stencil) {
|
||||
|
||||
if (back_stencil != stencil) {
|
||||
spe_release_register(f, back_stencil);
|
||||
}
|
||||
|
||||
if (front_stencil != stencil) {
|
||||
if (front_stencil != stencil) {
|
||||
spe_release_register(f, front_stencil);
|
||||
}
|
||||
|
||||
|
|
@ -505,10 +520,11 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa)
|
|||
|
||||
spe_release_register(f, back_depth_pass);
|
||||
} else {
|
||||
if (front_stencil != stencil) {
|
||||
if (front_stencil != stencil) {
|
||||
spe_or(f, stencil, front_stencil, front_stencil);
|
||||
spe_release_register(f, front_stencil);
|
||||
}
|
||||
spe_or(f, mask, front_depth_pass, front_depth_pass);
|
||||
}
|
||||
|
||||
spe_release_register(f, front_depth_pass);
|
||||
|
|
@ -997,7 +1013,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
|
|||
blend_color->color[3],
|
||||
frag[3], pixel[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (sF[0] == sF[3]) {
|
||||
src_factor[0] = src_factor[3];
|
||||
|
|
@ -1036,7 +1052,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
|
|||
frag, pixel, dst_factor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func[0] = b->rgb_func;
|
||||
func[1] = func[0];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue