diff options
Diffstat (limited to 'src/gallium/drivers/i965/brw_pipe_depth.c')
-rw-r--r-- | src/gallium/drivers/i965/brw_pipe_depth.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/gallium/drivers/i965/brw_pipe_depth.c b/src/gallium/drivers/i965/brw_pipe_depth.c new file mode 100644 index 00000000000..e010d76e0d3 --- /dev/null +++ b/src/gallium/drivers/i965/brw_pipe_depth.c @@ -0,0 +1,172 @@ + +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "brw_context.h" +#include "brw_defines.h" + +/* XXX: Fixme - include this to get IZ_ defines + */ +#include "brw_wm.h" + +static unsigned brw_translate_compare_func(unsigned func) +{ + switch (func) { + case PIPE_FUNC_NEVER: + return BRW_COMPAREFUNCTION_NEVER; + case PIPE_FUNC_LESS: + return BRW_COMPAREFUNCTION_LESS; + case PIPE_FUNC_LEQUAL: + return BRW_COMPAREFUNCTION_LEQUAL; + case PIPE_FUNC_GREATER: + return BRW_COMPAREFUNCTION_GREATER; + case PIPE_FUNC_GEQUAL: + return BRW_COMPAREFUNCTION_GEQUAL; + case PIPE_FUNC_NOTEQUAL: + return BRW_COMPAREFUNCTION_NOTEQUAL; + case PIPE_FUNC_EQUAL: + return BRW_COMPAREFUNCTION_EQUAL; + case PIPE_FUNC_ALWAYS: + return BRW_COMPAREFUNCTION_ALWAYS; + default: + assert(0); + return BRW_COMPAREFUNCTION_ALWAYS; + } +} + +static unsigned translate_stencil_op(unsigned op) +{ + switch (op) { + case PIPE_STENCIL_OP_KEEP: + return BRW_STENCILOP_KEEP; + case PIPE_STENCIL_OP_ZERO: + return BRW_STENCILOP_ZERO; + case PIPE_STENCIL_OP_REPLACE: + return BRW_STENCILOP_REPLACE; + case PIPE_STENCIL_OP_INCR: + return BRW_STENCILOP_INCRSAT; + case PIPE_STENCIL_OP_DECR: + return BRW_STENCILOP_DECRSAT; + case PIPE_STENCIL_OP_INCR_WRAP: + return BRW_STENCILOP_INCR; + case PIPE_STENCIL_OP_DECR_WRAP: + return BRW_STENCILOP_DECR; + case PIPE_STENCIL_OP_INVERT: + return BRW_STENCILOP_INVERT; + default: + assert(0); + return BRW_STENCILOP_ZERO; + } +} + +static void create_bcc_state( struct brw_depth_stencil_state *zstencil, + const struct pipe_depth_stencil_alpha_state *templ ) +{ + if (templ->stencil[0].enabled) { + zstencil->cc0.stencil_enable = 1; + zstencil->cc0.stencil_func = + brw_translate_compare_func(templ->stencil[0].func); + zstencil->cc0.stencil_fail_op = + translate_stencil_op(templ->stencil[0].fail_op); + zstencil->cc0.stencil_pass_depth_fail_op = + translate_stencil_op(templ->stencil[0].zfail_op); + zstencil->cc0.stencil_pass_depth_pass_op = + translate_stencil_op(templ->stencil[0].zpass_op); + zstencil->cc1.stencil_ref = templ->stencil[0].ref_value; + zstencil->cc1.stencil_write_mask = templ->stencil[0].writemask; + zstencil->cc1.stencil_test_mask = templ->stencil[0].valuemask; + + if (templ->stencil[1].enabled) { + zstencil->cc0.bf_stencil_enable = 1; + zstencil->cc0.bf_stencil_func = + brw_translate_compare_func(templ->stencil[1].func); + zstencil->cc0.bf_stencil_fail_op = + translate_stencil_op(templ->stencil[1].fail_op); + zstencil->cc0.bf_stencil_pass_depth_fail_op = + translate_stencil_op(templ->stencil[1].zfail_op); + zstencil->cc0.bf_stencil_pass_depth_pass_op = + translate_stencil_op(templ->stencil[1].zpass_op); + zstencil->cc1.bf_stencil_ref = templ->stencil[1].ref_value; + zstencil->cc2.bf_stencil_write_mask = templ->stencil[1].writemask; + zstencil->cc2.bf_stencil_test_mask = templ->stencil[1].valuemask; + } + + zstencil->cc0.stencil_write_enable = (zstencil->cc1.stencil_write_mask || + zstencil->cc2.bf_stencil_write_mask); + } + + + if (templ->alpha.enabled) { + zstencil->cc3.alpha_test = 1; + zstencil->cc3.alpha_test_func = brw_translate_compare_func(templ->alpha.func); + zstencil->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; + zstencil->cc7.alpha_ref.ub[0] = float_to_ubyte(templ->alpha.ref_value); + } + + if (templ->depth.enabled) { + zstencil->cc2.depth_test = 1; + zstencil->cc2.depth_test_function = brw_translate_compare_func(templ->depth.func); + zstencil->cc2.depth_write_enable = templ->depth.writemask; + } +} + +static void create_wm_iz_state( struct brw_depth_stencil_state *zstencil ) +{ + if (zstencil->cc3.alpha_test) + zstencil->iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT; + + if (zstencil->cc2.depth_test) + zstencil->iz_lookup |= IZ_DEPTH_TEST_ENABLE_BIT; + + if (zstencil->cc2.depth_write_enable) + zstencil->iz_lookup |= IZ_DEPTH_WRITE_ENABLE_BIT; + + if (zstencil->cc0.stencil_enable) + zstencil->iz_lookup |= IZ_STENCIL_TEST_ENABLE_BIT; + + if (zstencil->cc0.stencil_write_enable) + zstencil->iz_lookup |= IZ_STENCIL_WRITE_ENABLE_BIT; + +} + + +static void * +brw_create_depth_stencil_state( struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *templ ) +{ + struct brw_depth_stencil_state *zstencil = CALLOC_STRUCT(brw_depth_stencil_state); + + create_bcc_state( zstencil, templ ); + create_wm_iz_state( zstencil ); + + return (void *)zstencil; +} + + +static void brw_bind_depth_stencil_state(struct pipe_context *pipe, + void *cso) +{ + struct brw_context *brw = brw_context(pipe); + brw->curr.zstencil = (const struct brw_depth_stencil_state *)cso; + brw->state.dirty.mesa |= PIPE_NEW_DEPTH_STENCIL_ALPHA; +} + +static void brw_delete_depth_stencil_state(struct pipe_context *pipe, + void *cso) +{ + struct brw_context *brw = brw_context(pipe); + assert((const void *)cso != (const void *)brw->curr.zstencil); + FREE(cso); +} + + +void brw_pipe_depth_stencil_init( struct brw_context *brw ) +{ + brw->base.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; + brw->base.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; + brw->base.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; +} + +void brw_pipe_depth_stencil_cleanup( struct brw_context *brw ) +{ +} |