From cc030da4284b6c965d2b72c68a875b3210a4b286 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 6 Jan 2013 01:47:24 +0100 Subject: [PATCH] r300g: simplify DSA state, add ability to patch FG_ALPHA_FUNC while emitting Preparation for MSAA and alpha-to-coverage. --- src/gallium/drivers/r300/r300_context.h | 22 ++----- src/gallium/drivers/r300/r300_emit.c | 23 +++---- src/gallium/drivers/r300/r300_state.c | 80 +++++++++---------------- 3 files changed, 46 insertions(+), 79 deletions(-) diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 5f9c2493cec..cddd91d7ab8 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -98,8 +98,6 @@ struct r300_dsa_state { /* This is actually a command buffer with named dwords. */ uint32_t cb_begin; - uint32_t alpha_function; /* R300_FG_ALPHA_FUNC: 0x4bd4 */ - uint32_t cb_reg_seq; uint32_t z_buffer_control; /* R300_ZB_CNTL: 0x4f00 */ uint32_t z_stencil_control; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */ uint32_t stencil_ref_mask; /* R300_ZB_STENCILREFMASK: 0x4f08 */ @@ -108,21 +106,11 @@ struct r300_dsa_state { uint32_t cb_reg1; uint32_t alpha_value; /* R500_FG_ALPHA_VALUE: 0x4be0 */ - /* The same, but for FP16 alpha test. */ - uint32_t cb_begin_fp16; - uint32_t alpha_function_fp16; /* R300_FG_ALPHA_FUNC: 0x4bd4 */ - uint32_t cb_reg_seq_fp16; - uint32_t z_buffer_control_fp16; /* R300_ZB_CNTL: 0x4f00 */ - uint32_t z_stencil_control_fp16; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */ - uint32_t stencil_ref_mask_fp16; /* R300_ZB_STENCILREFMASK: 0x4f08 */ - uint32_t cb_reg_fp16; - uint32_t stencil_ref_bf_fp16; /* R500_ZB_STENCILREFMASK_BF: 0x4fd4 */ - uint32_t cb_reg1_fp16; - uint32_t alpha_value_fp16; /* R500_FG_ALPHA_VALUE: 0x4be0 */ - - /* The second command buffer disables zbuffer reads and writes. */ - uint32_t cb_zb_no_readwrite[10]; - uint32_t cb_fp16_zb_no_readwrite[10]; + /* Same, but without ZB reads and writes. */ + uint32_t cb_zb_no_readwrite[8]; /* ZB not bound */ + + /* Emitted separately: */ + uint32_t alpha_function; /* Whether a two-sided stencil is enabled. */ boolean two_sided; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 51c14b43e41..1b9de40afaa 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -79,19 +79,22 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state) struct r300_dsa_state* dsa = (struct r300_dsa_state*)state; struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)r300->fb_state.state; + boolean is_r500 = r300->screen->caps.is_r500; CS_LOCALS(r300); + uint32_t alpha_func = dsa->alpha_function; - if (fb->zsbuf) { - if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) - WRITE_CS_TABLE(&dsa->cb_begin_fp16, size); - else - WRITE_CS_TABLE(&dsa->cb_begin, size); - } else { - if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) - WRITE_CS_TABLE(dsa->cb_fp16_zb_no_readwrite, size); - else - WRITE_CS_TABLE(dsa->cb_zb_no_readwrite, size); + /* Choose the alpha ref value between 8-bit (FG_ALPHA_FUNC.AM_VAL) and + * 16-bit (FG_ALPHA_VALUE). */ + if (is_r500 && (alpha_func & R300_FG_ALPHA_FUNC_ENABLE)) { + if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) { + alpha_func |= R500_FG_ALPHA_FUNC_FP16_ENABLE; + } else { + alpha_func |= R500_FG_ALPHA_FUNC_8BIT; + } } + + OUT_CS_REG(R300_FG_ALPHA_FUNC, alpha_func); + WRITE_CS_TABLE(fb->zsbuf ? &dsa->cb_begin : dsa->cb_zb_no_readwrite, size-2); } static void get_rc_constant_state( diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 29e28b4dfb1..a5f96831081 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -565,33 +565,37 @@ r300_set_sample_mask(struct pipe_context *pipe, * This contains the depth buffer, stencil buffer, alpha test, and such. * On the Radeon, depth and stencil buffer setup are intertwined, which is * the reason for some of the strange-looking assignments across registers. */ -static void* - r300_create_dsa_state(struct pipe_context* pipe, - const struct pipe_depth_stencil_alpha_state* state) +static void* r300_create_dsa_state(struct pipe_context* pipe, + const struct pipe_depth_stencil_alpha_state* state) { - struct r300_capabilities *caps = &r300_screen(pipe->screen)->caps; + boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500; struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); CB_LOCALS; + uint32_t alpha_value_fp16 = 0; + uint32_t z_buffer_control = 0; + uint32_t z_stencil_control = 0; + uint32_t stencil_ref_mask = 0; + uint32_t stencil_ref_bf = 0; dsa->dsa = *state; /* Depth test setup. - separate write mask depth for decomp flush */ if (state->depth.writemask) { - dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; + z_buffer_control |= R300_Z_WRITE_ENABLE; } if (state->depth.enabled) { - dsa->z_buffer_control |= R300_Z_ENABLE; + z_buffer_control |= R300_Z_ENABLE; - dsa->z_stencil_control |= + z_stencil_control |= (r300_translate_depth_stencil_function(state->depth.func) << R300_Z_FUNC_SHIFT); } /* Stencil buffer setup. */ if (state->stencil[0].enabled) { - dsa->z_buffer_control |= R300_STENCIL_ENABLE; - dsa->z_stencil_control |= + z_buffer_control |= R300_STENCIL_ENABLE; + z_stencil_control |= (r300_translate_depth_stencil_function(state->stencil[0].func) << R300_S_FRONT_FUNC_SHIFT) | (r300_translate_stencil_op(state->stencil[0].fail_op) << @@ -601,15 +605,15 @@ static void* (r300_translate_stencil_op(state->stencil[0].zfail_op) << R300_S_FRONT_ZFAIL_OP_SHIFT); - dsa->stencil_ref_mask = + stencil_ref_mask = (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) | (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT); if (state->stencil[1].enabled) { dsa->two_sided = TRUE; - dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; - dsa->z_stencil_control |= + z_buffer_control |= R300_STENCIL_FRONT_BACK; + z_stencil_control |= (r300_translate_depth_stencil_function(state->stencil[1].func) << R300_S_BACK_FUNC_SHIFT) | (r300_translate_stencil_op(state->stencil[1].fail_op) << @@ -619,12 +623,12 @@ static void* (r300_translate_stencil_op(state->stencil[1].zfail_op) << R300_S_BACK_ZFAIL_OP_SHIFT); - dsa->stencil_ref_bf = + stencil_ref_bf = (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) | (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT); - if (caps->is_r500) { - dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK; + if (is_r500) { + z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK; } else { dsa->two_sided_stencil_ref = (state->stencil[0].valuemask != state->stencil[1].valuemask || @@ -640,53 +644,25 @@ static void* R300_FG_ALPHA_FUNC_ENABLE; dsa->alpha_function |= float_to_ubyte(state->alpha.ref_value); - dsa->alpha_value = util_float_to_half(state->alpha.ref_value); - - if (caps->is_r500) { - dsa->alpha_function_fp16 = dsa->alpha_function | - R500_FG_ALPHA_FUNC_FP16_ENABLE; - dsa->alpha_function |= R500_FG_ALPHA_FUNC_8BIT; - } + alpha_value_fp16 = util_float_to_half(state->alpha.ref_value); } - BEGIN_CB(&dsa->cb_begin, 10); - OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function); - OUT_CB_REG_SEQ(R300_ZB_CNTL, 3); - OUT_CB(dsa->z_buffer_control); - OUT_CB(dsa->z_stencil_control); - OUT_CB(dsa->stencil_ref_mask); - OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); - OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value); - END_CB; - - BEGIN_CB(&dsa->cb_begin_fp16, 10); - OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function_fp16); + BEGIN_CB(&dsa->cb_begin, 8); OUT_CB_REG_SEQ(R300_ZB_CNTL, 3); - OUT_CB(dsa->z_buffer_control); - OUT_CB(dsa->z_stencil_control); - OUT_CB(dsa->stencil_ref_mask); - OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); - OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value); - END_CB; - - BEGIN_CB(dsa->cb_zb_no_readwrite, 10); - OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function); - OUT_CB_REG_SEQ(R300_ZB_CNTL, 3); - OUT_CB(0); - OUT_CB(0); - OUT_CB(0); - OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0); - OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value); + OUT_CB(z_buffer_control); + OUT_CB(z_stencil_control); + OUT_CB(stencil_ref_mask); + OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, stencil_ref_bf); + OUT_CB_REG(R500_FG_ALPHA_VALUE, alpha_value_fp16); END_CB; - BEGIN_CB(dsa->cb_fp16_zb_no_readwrite, 10); - OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function_fp16); + BEGIN_CB(dsa->cb_zb_no_readwrite, 8); OUT_CB_REG_SEQ(R300_ZB_CNTL, 3); OUT_CB(0); OUT_CB(0); OUT_CB(0); OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0); - OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value); + OUT_CB_REG(R500_FG_ALPHA_VALUE, alpha_value_fp16); END_CB; return (void*)dsa; -- 2.30.2