diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c index db9a484fc06..934a739121c 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c @@ -431,8 +431,7 @@ etna_emit_state(struct etna_context *ctx) } if (unlikely(dirty & (ETNA_DIRTY_ZSA | ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_SHADER))) { /*01400*/ EMIT_STATE(PE_DEPTH_CONFIG, (etna_zsa_state(ctx->zsa)->PE_DEPTH_CONFIG | - ctx->framebuffer.PE_DEPTH_CONFIG) & - ctx->shader_state.PE_DEPTH_CONFIG); + ctx->framebuffer.PE_DEPTH_CONFIG)); } if (unlikely(dirty & (ETNA_DIRTY_VIEWPORT))) { /*01404*/ EMIT_STATE(PE_DEPTH_NEAR, ctx->viewport.PE_DEPTH_NEAR); diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h index dc5f3f2b902..36ddb3bc1ec 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h @@ -245,7 +245,6 @@ struct compiled_shader_state { uint32_t PS_TEMP_REGISTER_CONTROL; uint32_t PS_TEMP_REGISTER_CONTROL_MSAA; /* Adds a temporary if needed to make space for extra input */ uint32_t PS_START_PC; - uint32_t PE_DEPTH_CONFIG; uint32_t GL_VARYING_TOTAL_COMPONENTS; uint32_t GL_VARYING_NUM_COMPONENTS[2]; uint32_t GL_VARYING_COMPONENT_USE[2]; @@ -257,6 +256,8 @@ struct compiled_shader_state { uint32_t *PS_INST_MEM; struct etna_reloc PS_INST_ADDR; struct etna_reloc VS_INST_ADDR; + unsigned writes_z:1; + unsigned uses_discard:1; }; /* Helpers to assist creating and setting bitarrays (eg, for varyings). diff --git a/src/gallium/drivers/etnaviv/etnaviv_shader.c b/src/gallium/drivers/etnaviv/etnaviv_shader.c index 3f28e4db3ce..e890b34061d 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_shader.c +++ b/src/gallium/drivers/etnaviv/etnaviv_shader.c @@ -251,8 +251,8 @@ etna_link_shaders(struct etna_context *ctx, struct compiled_shader_state *cs, VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN((link.pcoord_varying_comp_ofs != -1) ? link.pcoord_varying_comp_ofs : 0x7f); - /* mask out early Z bit when frag depth is written */ - cs->PE_DEPTH_CONFIG = ~COND(fs->ps_depth_out_reg >= 0, VIVS_PE_DEPTH_CONFIG_EARLY_Z); + cs->writes_z = fs->ps_depth_out_reg >= 0; + cs->uses_discard = fs->uses_discard; /* reference instruction memory */ cs->vs_inst_mem_size = vs->code_size; diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index e25d78ddb3a..1b4a7040b50 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -39,6 +39,7 @@ #include "etnaviv_surface.h" #include "etnaviv_translate.h" #include "etnaviv_util.h" +#include "etnaviv_zsa.h" #include "util/u_framebuffer.h" #include "util/u_helpers.h" #include "util/u_inlines.h" @@ -675,6 +676,71 @@ etna_update_clipping(struct etna_context *ctx) return true; } +static bool +etna_update_zsa(struct etna_context *ctx) +{ + struct compiled_shader_state *shader_state = &ctx->shader_state; + struct pipe_depth_stencil_alpha_state *zsa_state = ctx->zsa; + struct etna_zsa_state *zsa = etna_zsa_state(zsa_state); + struct etna_screen *screen = ctx->screen; + uint32_t new_pe_depth, new_ra_depth; + bool late_z_write = false, early_z_write = false, + late_z_test = false, early_z_test = false; + + if (zsa->z_write_enabled) { + if (VIV_FEATURE(screen, chipMinorFeatures5, RA_WRITE_DEPTH) && + !VIV_FEATURE(screen, chipFeatures, NO_EARLY_Z) && + !zsa->stencil_enabled && + !zsa_state->alpha.enabled && + !shader_state->writes_z && + !shader_state->uses_discard) + early_z_write = true; + else + late_z_write = true; + } + + if (zsa->z_test_enabled) { + if (!VIV_FEATURE(screen, chipFeatures, NO_EARLY_Z) && + !zsa->stencil_modified && + !shader_state->writes_z) + early_z_test = true; + else + late_z_test = true; + } + + new_pe_depth = VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC(zsa->z_test_enabled ? + /* compare funcs have 1 to 1 mapping */ + zsa_state->depth.func : PIPE_FUNC_ALWAYS) | + COND(zsa->z_write_enabled, VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE) | + COND(early_z_test, VIVS_PE_DEPTH_CONFIG_EARLY_Z) | + COND(!late_z_write && !late_z_test && !zsa->stencil_enabled, + VIVS_PE_DEPTH_CONFIG_DISABLE_ZS); + + /* blob sets this to 0x40000031 on GC7000, seems to make no difference, + * but keep it in mind if depth behaves strangely. */ + new_ra_depth = 0x0000030 | + COND(early_z_test, VIVS_RA_EARLY_DEPTH_TEST_ENABLE); + + if (VIV_FEATURE(screen, chipMinorFeatures5, RA_WRITE_DEPTH)) { + if (!early_z_write) + new_ra_depth |= VIVS_RA_EARLY_DEPTH_WRITE_DISABLE; + /* The new early hierarchical test seems to only work properly if depth + * is also written from the early stage. + */ + if (late_z_test || (early_z_test && late_z_write)) + new_ra_depth |= VIVS_RA_EARLY_DEPTH_HDEPTH_DISABLE; + } + + if (new_pe_depth != zsa->PE_DEPTH_CONFIG || + new_ra_depth != zsa->RA_DEPTH_CONFIG) + ctx->dirty |= ETNA_DIRTY_ZSA; + + zsa->PE_DEPTH_CONFIG = new_pe_depth; + zsa->RA_DEPTH_CONFIG = new_ra_depth; + + return true; +} + struct etna_state_updater { bool (*update)(struct etna_context *ctx); uint32_t dirty; @@ -699,6 +765,9 @@ static const struct etna_state_updater etna_state_updates[] = { { etna_update_clipping, ETNA_DIRTY_SCISSOR | ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_VIEWPORT, + }, + { + etna_update_zsa, ETNA_DIRTY_ZSA | ETNA_DIRTY_SHADER, } }; diff --git a/src/gallium/drivers/etnaviv/etnaviv_zsa.c b/src/gallium/drivers/etnaviv/etnaviv_zsa.c index 2f9f2cb13c1..66d0c290c9f 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_zsa.c +++ b/src/gallium/drivers/etnaviv/etnaviv_zsa.c @@ -47,11 +47,10 @@ etna_zsa_state_create(struct pipe_context *pctx, cs->base = *so; + cs->z_test_enabled = so->depth.enabled && so->depth.func != PIPE_FUNC_ALWAYS; + cs->z_write_enabled = so->depth.enabled && so->depth.writemask; + /* XXX does stencil[0] / stencil[1] order depend on rs->front_ccw? */ - bool early_z = !VIV_FEATURE(ctx->screen, chipFeatures, NO_EARLY_Z); - bool disable_zs = - (!so->depth.enabled || so->depth.func == PIPE_FUNC_ALWAYS) && - !so->depth.writemask; /* Set operations to KEEP if write mask is 0. * When we don't do this, the depth buffer is written for the entire primitive @@ -73,27 +72,21 @@ etna_zsa_state_create(struct pipe_context *pctx, if (so->stencil[0].enabled) { if (so->stencil[0].func != PIPE_FUNC_ALWAYS || (so->stencil[1].enabled && so->stencil[1].func != PIPE_FUNC_ALWAYS)) - disable_zs = false; + cs->stencil_enabled = 1; if (so->stencil[0].fail_op != PIPE_STENCIL_OP_KEEP || so->stencil[0].zfail_op != PIPE_STENCIL_OP_KEEP || so->stencil[0].zpass_op != PIPE_STENCIL_OP_KEEP) { - disable_zs = early_z = false; + cs->stencil_modified = 1; } else if (so->stencil[1].enabled) { if (so->stencil[1].fail_op != PIPE_STENCIL_OP_KEEP || so->stencil[1].zfail_op != PIPE_STENCIL_OP_KEEP || so->stencil[1].zpass_op != PIPE_STENCIL_OP_KEEP) { - disable_zs = early_z = false; + cs->stencil_modified = 1; } } } - /* Disable early z reject when no depth test is enabled. - * This avoids having to sample depth even though we know it's going to - * succeed. */ - if (so->depth.enabled == false || so->depth.func == PIPE_FUNC_ALWAYS) - early_z = false; - /* calculate extra_reference value */ uint32_t extra_reference = 0; @@ -103,15 +96,6 @@ etna_zsa_state_create(struct pipe_context *pctx, cs->PE_STENCIL_CONFIG_EXT = VIVS_PE_STENCIL_CONFIG_EXT_EXTRA_ALPHA_REF(extra_reference); - /* compare funcs have 1 to 1 mapping */ - cs->PE_DEPTH_CONFIG = - VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC(so->depth.enabled ? so->depth.func - : PIPE_FUNC_ALWAYS) | - COND(so->depth.writemask, VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE) | - COND(early_z, VIVS_PE_DEPTH_CONFIG_EARLY_Z) | - /* this bit changed meaning with HALTI5: */ - COND((disable_zs && screen->specs.halti < 5) || ((early_z || disable_zs) && VIV_FEATURE(screen, chipMinorFeatures5, RA_WRITE_DEPTH)), VIVS_PE_DEPTH_CONFIG_DISABLE_ZS); - cs->PE_ALPHA_OP = COND(so->alpha.enabled, VIVS_PE_ALPHA_OP_ALPHA_TEST) | VIVS_PE_ALPHA_OP_ALPHA_FUNC(so->alpha.func) | @@ -138,12 +122,6 @@ etna_zsa_state_create(struct pipe_context *pctx, VIVS_PE_STENCIL_CONFIG_EXT2_WRITE_MASK_BACK(stencil_back->writemask); } - /* blob sets this to 0x40000031 on GC7000, seems to make no difference, - * but keep it in mind if depth behaves strangely. */ - cs->RA_DEPTH_CONFIG = 0x00000031; - if (VIV_FEATURE(screen, chipMinorFeatures5, RA_WRITE_DEPTH) && !disable_zs && !early_z) - cs->RA_DEPTH_CONFIG |= 0x11000000; - /* XXX does alpha/stencil test affect PE_COLOR_FORMAT_OVERWRITE? */ return cs; } diff --git a/src/gallium/drivers/etnaviv/etnaviv_zsa.h b/src/gallium/drivers/etnaviv/etnaviv_zsa.h index dfa1b572a30..e423474ad10 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_zsa.h +++ b/src/gallium/drivers/etnaviv/etnaviv_zsa.h @@ -40,6 +40,10 @@ struct etna_zsa_state { uint32_t PE_STENCIL_CONFIG_EXT; uint32_t PE_STENCIL_CONFIG_EXT2[2]; uint32_t RA_DEPTH_CONFIG; + unsigned z_test_enabled:1; + unsigned z_write_enabled:1; + unsigned stencil_enabled:1; + unsigned stencil_modified:1; };