From f60235e73a5260f92630ce472e06d8c5c00414fb Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 5 May 2011 20:54:36 +0200 Subject: [PATCH] r600g: Match alpha ref precision to color format precision. This fixes piglit fbo-alphatest-formats on Evergreen. Signed-off-by: Henri Verbeet --- src/gallium/drivers/r600/evergreen_state.c | 20 ++++++--- src/gallium/drivers/r600/r600_pipe.h | 10 ++++- src/gallium/drivers/r600/r600_state.c | 11 +++-- src/gallium/drivers/r600/r600_state_common.c | 44 +++++++++++++++----- 4 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index e325361b6c2..d60c153b482 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -143,14 +143,17 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx, static void *evergreen_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -190,6 +193,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -206,7 +210,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL); /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE, @@ -709,10 +712,17 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state /* we can only set the export size if any thing is snorm/unorm component is > 11 bits, if we aren't a float, sint or uint */ + /* FIXME: This should probably be the same for all CBs if we want + * useful alpha tests. */ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && - ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) + ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) { color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC); + rctx->export_16bpc = true; + } else { + rctx->export_16bpc = false; + } + rctx->alpha_ref_dirty = true; if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) { tile_type = rtex->tile_type; @@ -914,7 +924,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index ae2a57e1416..aa5ef4efb3b 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -97,6 +97,11 @@ struct r600_pipe_blend { unsigned cb_target_mask; }; +struct r600_pipe_dsa { + struct r600_pipe_state rstate; + unsigned alpha_ref; +}; + struct r600_vertex_element { unsigned count; @@ -186,6 +191,9 @@ struct r600_pipe_context { /* shader information */ unsigned sprite_coord_enable; bool flatshade; + bool export_16bpc; + unsigned alpha_ref; + bool alpha_ref_dirty; struct r600_textures_info ps_samplers; struct r600_pipe_fences fences; @@ -283,11 +291,11 @@ void *r600_create_vertex_elements(struct pipe_context *ctx, const struct pipe_vertex_element *elements); void r600_delete_vertex_element(struct pipe_context *ctx, void *state); void r600_bind_blend_state(struct pipe_context *ctx, void *state); +void r600_bind_dsa_state(struct pipe_context *ctx, void *state); void r600_bind_rs_state(struct pipe_context *ctx, void *state); void r600_delete_rs_state(struct pipe_context *ctx, void *state); void r600_sampler_view_destroy(struct pipe_context *ctx, struct pipe_sampler_view *state); -void r600_bind_state(struct pipe_context *ctx, void *state); void r600_delete_state(struct pipe_context *ctx, void *state); void r600_bind_vertex_elements(struct pipe_context *ctx, void *state); void *r600_create_shader_state(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 1c27f880751..90c5ba2b31e 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -199,14 +199,17 @@ static void *r600_create_blend_state(struct pipe_context *ctx, static void *r600_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -246,6 +249,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -262,7 +266,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E0_SPI_FOG_FUNC_SCALE, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); @@ -964,7 +967,7 @@ void r600_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index cf605e11ade..de1b811ce89 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -86,6 +86,21 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state) r600_context_pipe_state_set(&rctx->ctx, rstate); } +void r600_bind_dsa_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_dsa *dsa = state; + struct r600_pipe_state *rstate; + + if (state == NULL) + return; + rstate = &dsa->rstate; + rctx->states[rstate->id] = rstate; + rctx->alpha_ref = dsa->alpha_ref; + rctx->alpha_ref_dirty = true; + r600_context_pipe_state_set(&rctx->ctx, rstate); +} + void r600_bind_rs_state(struct pipe_context *ctx, void *state) { struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; @@ -131,17 +146,6 @@ void r600_sampler_view_destroy(struct pipe_context *ctx, FREE(resource); } -void r600_bind_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (state == NULL) - return; - rctx->states[rstate->id] = rstate; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - void r600_delete_state(struct pipe_context *ctx, void *state) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -316,6 +320,23 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state) free(shader); } +static void r600_update_alpha_ref(struct r600_pipe_context *rctx) +{ + unsigned alpha_ref = rctx->alpha_ref; + struct r600_pipe_state rstate; + + if (!rctx->alpha_ref_dirty) + return; + + rstate.nregs = 0; + if (rctx->export_16bpc) + alpha_ref &= ~0x1FFF; + r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); + + r600_context_pipe_state_set(&rctx->ctx, &rstate); + rctx->alpha_ref_dirty = false; +} + /* FIXME optimize away spi update when it's not needed */ static void r600_spi_update(struct r600_pipe_context *rctx, unsigned prim) { @@ -554,6 +575,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) return; } + r600_update_alpha_ref(rctx); r600_spi_update(rctx, draw.info.mode); mask = 0; -- 2.30.2