From: Rob Clark Date: Sun, 31 May 2020 17:46:54 +0000 (-0700) Subject: freedreno/a6xx: update depth-plane control regs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=27e501bcfc585757ddf9ad6c37a0cee361c2275e;p=mesa.git freedreno/a6xx: update depth-plane control regs And document the early-lrz-late-z mode. Initially I thought this would be two bits to control early-lrz vs early-z. But having early-z without early-lrz does not make sense, and the way the values line up makes an enum fit better. Signed-off-by: Rob Clark Part-of: --- diff --git a/src/freedreno/registers/a6xx.xml b/src/freedreno/registers/a6xx.xml index c7b83059eb8..0a0eec3ea07 100644 --- a/src/freedreno/registers/a6xx.xml +++ b/src/freedreno/registers/a6xx.xml @@ -891,6 +891,44 @@ to upconvert to 32b float internally? + + Allow early z-test and early-lrz (if applicable) + + Disable early z-test and early-lrz test (if applicable) + + + A special mode that allows early-lrz test but disables + early-z test. Which might sound a bit funny, since + lrz-test happens before z-test. But as long as a couple + conditions are maintained this allows using lrz-test in + cases where fragment shader has kill/discard: + + 1) Disable lrz-write in cases where it is uncertain during + binning pass that a fragment will pass. Ie. if frag + shader has-kill, writes-z, or alpha/stencil test is + enabled. (For correctness, lrz-write must be disabled + when blend is enabled.) This is analogous to how a + z-prepass works. + + 2) Disable lrz-write and test if a depth-test direction + reversal is detected. Due to condition (1), the contents + of the lrz buffer are a conservative estimation of the + depth buffer during the draw pass. Meaning that geometry + that we know for certain will not be visible will not pass + lrz-test. But geometry which may be (or contributes to + blend) will pass the lrz-test. + + This allows us to keep early-lrz-test in cases where the frag + shader does not write-z (ie. we know the z-value before FS) + and does not have side-effects (image/ssbo writes, etc), but + does have kill/discard. Which turns out to be a common + enough case that it is useful to keep early-lrz test against + the conservative lrz buffer to discard fragments that we + know will definitely not be visible. + + + + @@ -1909,7 +1947,7 @@ to upconvert to 32b float internally? - + @@ -2259,7 +2297,7 @@ to upconvert to 32b float internally? - + diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index debc4811e32..5002f9f6f2a 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -1383,18 +1383,19 @@ tu6_emit_fs_outputs(struct tu_cs *cs, tu_cs_emit_regs(cs, A6XX_RB_RENDER_COMPONENTS(.dword = render_components)); - uint32_t gras_su_depth_plane_cntl = 0; - uint32_t rb_depth_plane_cntl = 0; + enum a6xx_ztest_mode zmode; + if (fs->no_earlyz || fs->has_kill || fs->writes_pos) { - gras_su_depth_plane_cntl |= A6XX_GRAS_SU_DEPTH_PLANE_CNTL_FRAG_WRITES_Z; - rb_depth_plane_cntl |= A6XX_RB_DEPTH_PLANE_CNTL_FRAG_WRITES_Z; + zmode = A6XX_LATE_Z; + } else { + zmode = A6XX_EARLY_Z; } tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_DEPTH_PLANE_CNTL, 1); - tu_cs_emit(cs, gras_su_depth_plane_cntl); + tu_cs_emit(cs, A6XX_GRAS_SU_DEPTH_PLANE_CNTL_Z_MODE(zmode)); tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_PLANE_CNTL, 1); - tu_cs_emit(cs, rb_depth_plane_cntl); + tu_cs_emit(cs, A6XX_RB_DEPTH_PLANE_CNTL_Z_MODE(zmode)); } static void diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c index 45a05544e6b..dad117688af 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c @@ -835,13 +835,19 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen, OUT_RING(ring, COND(primid_passthru, A6XX_VFD_CONTROL_6_PRIMID_PASSTHRU)); /* VFD_CONTROL_6 */ - bool fragz = fs->no_earlyz || fs->has_kill || fs->writes_pos; + enum a6xx_ztest_mode zmode; + + if (fs->no_earlyz || fs->has_kill || fs->writes_pos) { + zmode = A6XX_LATE_Z; + } else { + zmode = A6XX_EARLY_Z; + } OUT_PKT4(ring, REG_A6XX_RB_DEPTH_PLANE_CNTL, 1); - OUT_RING(ring, COND(fragz, A6XX_RB_DEPTH_PLANE_CNTL_FRAG_WRITES_Z)); + OUT_RING(ring, A6XX_RB_DEPTH_PLANE_CNTL_Z_MODE(zmode)); OUT_PKT4(ring, REG_A6XX_GRAS_SU_DEPTH_PLANE_CNTL, 1); - OUT_RING(ring, COND(fragz, A6XX_GRAS_SU_DEPTH_PLANE_CNTL_FRAG_WRITES_Z)); + OUT_RING(ring, A6XX_GRAS_SU_DEPTH_PLANE_CNTL_Z_MODE(zmode)); if (!binning_pass) fd6_emit_immediates(screen, fs, ring);