diff --git a/src/freedreno/registers/adreno/a6xx.xml b/src/freedreno/registers/adreno/a6xx.xml index 20ea4b6b162..9f801a20c61 100644 --- a/src/freedreno/registers/adreno/a6xx.xml +++ b/src/freedreno/registers/adreno/a6xx.xml @@ -954,6 +954,8 @@ to upconvert to 32b float internally? know will definitely not be visible. + Not a real hw value, used internally by mesa + diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.h b/src/gallium/drivers/freedreno/a6xx/fd6_context.h index cb264ca1c0c..93d676661a3 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_context.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.h @@ -39,13 +39,18 @@ #include "a6xx.xml.h" struct fd6_lrz_state { - bool enable : 1; - bool write : 1; - bool test : 1; - enum fd_lrz_direction direction : 2; + union { + struct { + bool enable : 1; + bool write : 1; + bool test : 1; + enum fd_lrz_direction direction : 2; - /* this comes from the fs program state, rather than zsa: */ - enum a6xx_ztest_mode z_mode : 2; + /* this comes from the fs program state, rather than zsa: */ + enum a6xx_ztest_mode z_mode : 2; + }; + uint32_t val : 7; + }; }; /** diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 689d3b8ec27..98ed5312b53 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -107,16 +107,15 @@ build_vbo_state(struct fd6_emit *emit) assert_dt static enum a6xx_ztest_mode compute_ztest_mode(struct fd6_emit *emit, bool lrz_valid) assert_dt { + if (emit->prog->lrz_mask.z_mode != A6XX_INVALID_ZTEST) + return emit->prog->lrz_mask.z_mode; + struct fd_context *ctx = emit->ctx; struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer; struct fd6_zsa_stateobj *zsa = fd6_zsa_stateobj(ctx->zsa); const struct ir3_shader_variant *fs = emit->fs; - if (fs->fs.early_fragment_tests) - return A6XX_EARLY_Z; - - if (fs->no_earlyz || fs->writes_pos || !zsa->base.depth_enabled || - fs->writes_stencilref) { + if (!zsa->base.depth_enabled) { return A6XX_LATE_Z; } else if ((fs->has_kill || zsa->alpha_test) && (zsa->writes_zs || !pfb->zsbuf)) { @@ -142,7 +141,6 @@ compute_lrz_state(struct fd6_emit *emit) assert_dt { struct fd_context *ctx = emit->ctx; struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer; - const struct ir3_shader_variant *fs = emit->fs; struct fd6_lrz_state lrz; if (!pfb->zsbuf) { @@ -158,9 +156,10 @@ compute_lrz_state(struct fd6_emit *emit) assert_dt lrz = zsa->lrz; + lrz.val &= emit->prog->lrz_mask.val; + /* normalize lrz state: */ - if (reads_dest || fs->writes_pos || fs->no_earlyz || fs->has_kill || - blend->base.alpha_to_coverage) { + if (reads_dest || blend->base.alpha_to_coverage) { lrz.write = false; } @@ -222,12 +221,6 @@ compute_lrz_state(struct fd6_emit *emit) assert_dt memset(&lrz, 0, sizeof(lrz)); } - if (fs->no_earlyz || fs->writes_pos) { - lrz.enable = false; - lrz.write = false; - lrz.test = false; - } - lrz.z_mode = compute_ztest_mode(emit, rsc->lrz_valid); /* Once we start writing to the real depth buffer, we lock in the @@ -255,8 +248,7 @@ build_lrz(struct fd6_emit *emit) assert_dt struct fd6_lrz_state lrz = compute_lrz_state(emit); /* If the LRZ state has not changed, we can skip the emit: */ - if (!ctx->last.dirty && - !memcmp(&fd6_ctx->last.lrz, &lrz, sizeof(lrz))) + if (!ctx->last.dirty && (fd6_ctx->last.lrz.val == lrz.val)) return NULL; fd6_ctx->last.lrz = lrz; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c index db718bdfc54..765c719ebdc 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c @@ -1366,6 +1366,27 @@ fd6_program_create(void *data, struct ir3_shader_variant *bs, state->num_driver_params = num_dp; + state->lrz_mask.val = ~0; + + if (fs->has_kill) { + state->lrz_mask.write = false; + } + + if (fs->no_earlyz || fs->writes_pos) { + state->lrz_mask.enable = false; + state->lrz_mask.write = false; + state->lrz_mask.test = false; + } + + if (fs->fs.early_fragment_tests) { + state->lrz_mask.z_mode = A6XX_EARLY_Z; + } else if (fs->no_earlyz || fs->writes_pos || fs->writes_stencilref) { + state->lrz_mask.z_mode = A6XX_LATE_Z; + } else { + /* Wildcard indicates that we need to figure out at draw time: */ + state->lrz_mask.z_mode = A6XX_INVALID_ZTEST; + } + return &state->base; } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.h b/src/gallium/drivers/freedreno/a6xx/fd6_program.h index 09150c2afb8..2acdd0e18cb 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.h @@ -75,6 +75,11 @@ struct fd6_program_state { * calculate it up-front. */ uint32_t user_consts_cmdstream_size; + + /** + * The FS contribution to LRZ state + */ + struct fd6_lrz_state lrz_mask; }; static inline struct fd6_program_state *