From ebcf3545db7dad66f5bce94e659720dfdd9f4805 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 1 Jun 2020 17:29:00 -0700 Subject: [PATCH] freedreno/ir3: split kill from no_earlyz Unlike other conditions which prevent early-discard of fragments, kill does not prevent early LRZ test. Split `has_kill` from `no_earlyz` so we can take advantage of this. Signed-off-by: Rob Clark Part-of: --- src/freedreno/ir3/ir3_compiler_nir.c | 2 +- src/freedreno/ir3/ir3_shader.h | 9 ++++++++- src/freedreno/vulkan/tu_pipeline.c | 2 +- src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 2 +- src/gallium/drivers/freedreno/a4xx/fd4_emit.c | 2 +- src/gallium/drivers/freedreno/a5xx/fd5_draw.c | 2 +- src/gallium/drivers/freedreno/a5xx/fd5_emit.c | 2 +- src/gallium/drivers/freedreno/a6xx/fd6_draw.c | 2 +- src/gallium/drivers/freedreno/a6xx/fd6_program.c | 2 +- 9 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 054c679aedf..ff699a8925a 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -1892,7 +1892,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) array_insert(ctx->ir, ctx->ir->predicates, kill); array_insert(b, b->keeps, kill); - ctx->so->no_earlyz = true; + ctx->so->has_kill = true; break; } diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index d623cf4fdaf..809af42d6cb 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -534,9 +534,16 @@ struct ir3_shader_variant { bool need_fine_derivatives; - /* do we have kill, image write, etc (which prevents early-z): */ + /* do we have image write, etc (which prevents early-z): */ bool no_earlyz; + /* do we have kill, which also prevents early-z, but not necessarily + * early-lrz (as long as lrz-write is disabled, which must be handled + * outside of ir3. Unlike other no_earlyz cases, kill doesn't have + * side effects that prevent early-lrz discard. + */ + bool has_kill; + bool per_samp; /* for astc srgb workaround, the number/base of additional diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 5b93306a30e..debc4811e32 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -1385,7 +1385,7 @@ tu6_emit_fs_outputs(struct tu_cs *cs, uint32_t gras_su_depth_plane_cntl = 0; uint32_t rb_depth_plane_cntl = 0; - if (fs->no_earlyz || fs->writes_pos) { + 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; } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index f86d4712c9a..0758b40bf8c 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -575,7 +575,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, val |= A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z; val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE; } - if (fp->no_earlyz) { + if (fp->no_earlyz || fp->has_kill) { val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE; } if (!ctx->rasterizer->depth_clip_near) { diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 6f94733e9ad..95c2dc7d639 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -581,7 +581,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) { struct fd4_zsa_stateobj *zsa = fd4_zsa_stateobj(ctx->zsa); - bool fragz = fp->no_earlyz | fp->writes_pos; + bool fragz = fp->no_earlyz | fp->has_kill | fp->writes_pos; bool clamp = !ctx->rasterizer->depth_clip_near; OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1); diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c index a1b6ea5456d..05fdaf78b51 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c @@ -142,7 +142,7 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, /* figure out whether we need to disable LRZ write for binning * pass using draw pass's fp: */ - emit.no_lrz_write = fp->writes_pos || fp->no_earlyz; + emit.no_lrz_write = fp->writes_pos || fp->no_earlyz || fp->has_kill; emit.binning_pass = false; emit.dirty = dirty; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c index 3670cba0aae..40e1ab34e06 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c @@ -602,7 +602,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) { struct fd5_zsa_stateobj *zsa = fd5_zsa_stateobj(ctx->zsa); - bool fragz = fp->no_earlyz | fp->writes_pos; + bool fragz = fp->no_earlyz || fp->has_kill || fp->writes_pos; OUT_PKT4(ring, REG_A5XX_RB_DEPTH_CNTL, 1); OUT_RING(ring, zsa->rb_depth_cntl); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index 037f3a81ca0..dab1cf32cd9 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -220,7 +220,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, /* figure out whether we need to disable LRZ write for binning * pass using draw pass's fs: */ - emit.no_lrz_write = emit.fs->writes_pos || emit.fs->no_earlyz; + emit.no_lrz_write = emit.fs->writes_pos || emit.fs->no_earlyz || emit.fs->has_kill; struct fd_ringbuffer *ring = ctx->batch->draw; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c index 98774a2cfe5..45a05544e6b 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c @@ -835,7 +835,7 @@ 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->writes_pos; + bool fragz = fs->no_earlyz || fs->has_kill || fs->writes_pos; OUT_PKT4(ring, REG_A6XX_RB_DEPTH_PLANE_CNTL, 1); OUT_RING(ring, COND(fragz, A6XX_RB_DEPTH_PLANE_CNTL_FRAG_WRITES_Z)); -- 2.30.2