diff options
-rw-r--r-- | src/gallium/drivers/cell/ppu/cell_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/cell/ppu/cell_gen_fragment.c | 50 | ||||
-rw-r--r-- | src/gallium/drivers/cell/ppu/cell_pipe_state.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/cell/ppu/cell_state_per_fragment.c | 18 |
4 files changed, 54 insertions, 29 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 905cd5db390..a77cc5b9067 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -114,6 +114,7 @@ struct cell_context struct spe_function logic_op; struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; struct pipe_buffer *constants[2]; struct pipe_framebuffer_state framebuffer; diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c index 0dab34075da..b58fe3764b0 100644 --- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c @@ -1175,7 +1175,8 @@ gen_colormask(struct spe_function *f, */ static void gen_stencil_test(struct spe_function *f, - const struct pipe_stencil_state *state, + const struct pipe_stencil_state *state, + const unsigned ref_value, uint stencil_max_value, int fragment_mask_reg, int fbS_reg, @@ -1189,7 +1190,7 @@ gen_stencil_test(struct spe_function *f, case PIPE_FUNC_EQUAL: if (state->valuemask == stencil_max_value) { /* stencil_pass = fragment_mask & (s == reference) */ - spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, state->ref_value); + spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1197,7 +1198,7 @@ gen_stencil_test(struct spe_function *f, uint tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1206,7 +1207,7 @@ gen_stencil_test(struct spe_function *f, case PIPE_FUNC_NOTEQUAL: if (state->valuemask == stencil_max_value) { /* stencil_pass = fragment_mask & ~(s == reference) */ - spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, state->ref_value); + spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1214,7 +1215,7 @@ gen_stencil_test(struct spe_function *f, int tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1223,7 +1224,7 @@ gen_stencil_test(struct spe_function *f, case PIPE_FUNC_LESS: if (state->valuemask == stencil_max_value) { /* stencil_pass = fragment_mask & (reference < s) */ - spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, state->ref_value); + spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1231,7 +1232,7 @@ gen_stencil_test(struct spe_function *f, int tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1246,7 +1247,7 @@ gen_stencil_test(struct spe_function *f, * treats its operands as unsigned - no sign extension. */ int tmp_reg = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->ref_value); + spe_load_uint(f, tmp_reg, ref_value); spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_reg); @@ -1255,7 +1256,7 @@ gen_stencil_test(struct spe_function *f, /* stencil_pass = fragment_mask & ((reference&mask) > (s&mask)) */ int tmp_reg = spe_allocate_available_register(f); int tmp_masked_stencil = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->valuemask & state->ref_value); + spe_load_uint(f, tmp_reg, state->valuemask & ref_value); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); @@ -1269,7 +1270,7 @@ gen_stencil_test(struct spe_function *f, /* stencil_pass = fragment_mask & (reference >= s) * = fragment_mask & ~(s > reference) */ spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, - state->ref_value); + ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1277,7 +1278,7 @@ gen_stencil_test(struct spe_function *f, int tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1289,7 +1290,7 @@ gen_stencil_test(struct spe_function *f, * = fragment_mask & ~(reference > s) */ /* As above, we have to do this by loading a register */ int tmp_reg = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->ref_value); + spe_load_uint(f, tmp_reg, ref_value); spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_reg); @@ -1298,7 +1299,7 @@ gen_stencil_test(struct spe_function *f, /* stencil_pass = fragment_mask & ~((reference&mask) > (s&mask)) */ int tmp_reg = spe_allocate_available_register(f); int tmp_masked_stencil = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->ref_value & state->valuemask); + spe_load_uint(f, tmp_reg, ref_value & state->valuemask); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); @@ -1453,6 +1454,7 @@ gen_stencil_values(struct spe_function *f, static void gen_get_stencil_values(struct spe_function *f, const struct pipe_stencil_state *stencil, + const unsigned ref_value, const uint depth_enabled, int fbS_reg, int *fail_reg, @@ -1488,7 +1490,7 @@ gen_get_stencil_values(struct spe_function *f, } else { *fail_reg = spe_allocate_available_register(f); - gen_stencil_values(f, stencil->fail_op, stencil->ref_value, + gen_stencil_values(f, stencil->fail_op, ref_value, 0xff, fbS_reg, *fail_reg); } @@ -1501,7 +1503,7 @@ gen_get_stencil_values(struct spe_function *f, } else { *zfail_reg = spe_allocate_available_register(f); - gen_stencil_values(f, stencil->zfail_op, stencil->ref_value, + gen_stencil_values(f, stencil->zfail_op, ref_value, 0xff, fbS_reg, *zfail_reg); } @@ -1516,7 +1518,7 @@ gen_get_stencil_values(struct spe_function *f, } else { *zpass_reg = spe_allocate_available_register(f); - gen_stencil_values(f, stencil->zpass_op, stencil->ref_value, + gen_stencil_values(f, stencil->zpass_op, ref_value, 0xff, fbS_reg, *zpass_reg); } } @@ -1528,7 +1530,8 @@ gen_get_stencil_values(struct spe_function *f, */ static boolean gen_stencil_depth_test(struct spe_function *f, - const struct pipe_depth_stencil_alpha_state *dsa, + const struct pipe_depth_stencil_alpha_state *dsa, + const struct pipe_stencil_ref *stencil_ref, const uint facing, const int mask_reg, const int fragZ_reg, const int fbZ_reg, const int fbS_reg) @@ -1542,6 +1545,7 @@ gen_stencil_depth_test(struct spe_function *f, boolean need_to_writemask_stencil_values; struct pipe_stencil_state *stencil; + unsigned stencil_ref_value; /* Registers. We may or may not actually allocate these, depending * on whether the state values indicate that we need them. @@ -1579,9 +1583,11 @@ gen_stencil_depth_test(struct spe_function *f, */ if (facing == CELL_FACING_BACK && dsa->stencil[1].enabled) { stencil = &dsa->stencil[1]; + ref_value = stencil_ref->ref_value[1]; } else { stencil = &dsa->stencil[0]; + ref_value = stencil_ref->ref_value[0]; } /* Calculate the writemask. If the writemask is trivial (either @@ -1641,7 +1647,7 @@ gen_stencil_depth_test(struct spe_function *f, */ spe_comment(f, 0, "Running basic stencil test"); stencil_pass_reg = spe_allocate_available_register(f); - gen_stencil_test(f, stencil, 0xff, mask_reg, fbS_reg, stencil_pass_reg); + gen_stencil_test(f, stencil, ref_value, 0xff, mask_reg, fbS_reg, stencil_pass_reg); /* Generate code that, given the mask of valid fragments and the * mask of valid fragments that passed the stencil test, computes @@ -1678,7 +1684,7 @@ gen_stencil_depth_test(struct spe_function *f, spe_comment(f, 0, facing == CELL_FACING_FRONT ? "Computing front-facing stencil values" : "Computing back-facing stencil values"); - gen_get_stencil_values(f, stencil, dsa->depth.enabled, fbS_reg, + gen_get_stencil_values(f, stencil, ref_value, dsa->depth.enabled, fbS_reg, &stencil_fail_values, &stencil_pass_depth_fail_values, &stencil_pass_depth_pass_values); } @@ -1818,6 +1824,7 @@ gen_stencil_depth_test(struct spe_function *f, static void gen_depth_stencil(struct cell_context *cell, const struct pipe_depth_stencil_alpha_state *dsa, + const struct pipe_stencil_ref *stencil_ref, struct spe_function *f, uint facing, int mask_reg, @@ -1940,7 +1947,7 @@ gen_depth_stencil(struct cell_context *cell, * gen_stencil_depth_test() function must ignore the * fbZ_reg register if depth is not enabled. */ - write_depth_stencil = gen_stencil_depth_test(f, dsa, facing, + write_depth_stencil = gen_stencil_depth_test(f, dsa, stencil_ref, facing, mask_reg, fragZ_reg, fbZ_reg, fbS_reg); } @@ -2029,6 +2036,7 @@ cell_gen_fragment_function(struct cell_context *cell, struct spe_function *f) { const struct pipe_depth_stencil_alpha_state *dsa = cell->depth_stencil; + const struct pipe_stencil_ref *stencil_ref = &cell->stencil_ref; const struct pipe_blend_state *blend = cell->blend; const struct pipe_blend_color *blend_color = &cell->blend_color; const enum pipe_format color_format = cell->framebuffer.cbufs[0]->format; @@ -2101,7 +2109,7 @@ cell_gen_fragment_function(struct cell_context *cell, /* generate depth and/or stencil test code */ if (dsa->depth.enabled || dsa->stencil[0].enabled) { - gen_depth_stencil(cell, dsa, f, + gen_depth_stencil(cell, dsa, stencil_ref, f, facing, mask_reg, depth_tile_reg, diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 3259c58687c..3d8b4409c75 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -113,6 +113,19 @@ cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *dsa) static void +cell_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->stencil_ref = *stencil_ref; + + cell->dirty |= CELL_NEW_DEPTH_STENCIL; +} + +static void cell_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) { @@ -397,6 +410,7 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state; cell->pipe.set_blend_color = cell_set_blend_color; + cell->pipe.set_stencil_ref = cell_set_stencil_ref; cell->pipe.set_clip_state = cell_set_clip_state; cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 21af7ed1c3f..07be5e92ea7 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -282,6 +282,7 @@ emit_stencil_op(struct spe_function *f, */ static int emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, + struct pipe_stencil_ref *sr, unsigned face, struct spe_function *f, int mask, @@ -296,7 +297,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, int stencil_pass = spe_allocate_available_register(f); int face_stencil = spe_allocate_available_register(f); int stencil_src = stencil; - const unsigned ref = (dsa->stencil[face].ref_value + const unsigned ref = (sr->ref_value[face] & dsa->stencil[face].valuemask); boolean complement = FALSE; int stored; @@ -406,7 +407,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, emit_stencil_op(f, face_stencil, stencil_src, stencil_fail, dsa->stencil[face].fail_op, - dsa->stencil[face].ref_value); + sr->ref_value[face]); stencil_src = face_stencil; } @@ -421,7 +422,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, emit_stencil_op(f, face_stencil, stencil_src, depth_fail, dsa->stencil[face].zfail_op, - dsa->stencil[face].ref_value); + sr->ref_value[face]); stencil_src = face_stencil; } @@ -429,7 +430,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, && (dsa->stencil[face].zpass_op != PIPE_STENCIL_OP_KEEP)) { emit_stencil_op(f, face_stencil, stencil_src, depth_pass, dsa->stencil[face].zpass_op, - dsa->stencil[face].ref_value); + sr->ref_value[face]); stencil_src = face_stencil; } } @@ -463,7 +464,8 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, void -cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) +cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa, + struct pipe_stencil_ref *sr) { struct pipe_depth_stencil_alpha_state *const dsa = &cdsa->base; struct spe_function *const f = &cdsa->code; @@ -499,13 +501,13 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) if (dsa->stencil[0].enabled) { const int front_depth_pass = spe_allocate_available_register(f); - int front_stencil = emit_stencil_test(dsa, 0, f, mask, + int front_stencil = emit_stencil_test(dsa, sr, 0, f, mask, depth_mask, depth_complement, stencil, front_depth_pass); if (dsa->stencil[1].enabled) { const int back_depth_pass = spe_allocate_available_register(f); - int back_stencil = emit_stencil_test(dsa, 1, f, mask, + int back_stencil = emit_stencil_test(dsa, sr, 1, f, mask, depth_mask, depth_complement, stencil, back_depth_pass); @@ -579,7 +581,7 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) dsa->stencil[i].zfail_op, dsa->stencil[i].zpass_op); printf("# ref value / value mask / write mask: %02x %02x %02x\n", - dsa->stencil[i].ref_value, + sr->ref_value[i], dsa->stencil[i].valuemask, dsa->stencil[i].writemask); } |