From 1b4c12d3eea5287933e9f1a8aa673d168f16a035 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 6 Dec 2019 11:34:39 -0800 Subject: [PATCH] freedreno/a6xx: fix LRZ logic In particular, we need to invalidate the LRZ state when we cannot be confident in what the Z state would be during rendering: 1) depth test modes not supported by LRZ 2) stencil test, which would require full rasterization and stencil test in the binning pass (whereas LRZ normally just needs to determine the min and max z value in an 8x8 quad) Signed-off-by: Rob Clark --- src/freedreno/registers/a6xx.xml | 3 +- src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 6 +- src/gallium/drivers/freedreno/a6xx/fd6_gmem.c | 2 +- src/gallium/drivers/freedreno/a6xx/fd6_zsa.c | 68 ++++++++++++------- src/gallium/drivers/freedreno/a6xx/fd6_zsa.h | 1 + 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/freedreno/registers/a6xx.xml b/src/freedreno/registers/a6xx.xml index fe5b6adc37b..480590a85f7 100644 --- a/src/freedreno/registers/a6xx.xml +++ b/src/freedreno/registers/a6xx.xml @@ -1975,10 +1975,9 @@ to upconvert to 32b float internally? update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL - - + diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index a44aa3f224c..e878c0c1370 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -706,7 +706,11 @@ build_lrz(struct fd6_emit *emit, bool binning_pass) struct fd_ringbuffer *ring = fd_submit_new_ringbuffer(emit->ctx->batch->submit, 16, FD_RINGBUFFER_STREAMING); - if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid) { + if (zsa->invalidate_lrz) { + rsc->lrz_valid = false; + gras_lrz_cntl = 0; + rb_lrz_cntl = 0; + } else if (emit->no_lrz_write || !rsc->lrz || !rsc->lrz_valid) { gras_lrz_cntl = 0; rb_lrz_cntl = 0; } else if (binning_pass && blend->lrz_write && zsa->lrz_write) { diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c index 75c901f7507..0176402ad87 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c @@ -284,7 +284,7 @@ use_hw_binning(struct fd_batch *batch) // TODO figure out hw limits for binning - return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) > 2) && + return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) >= 2) && (batch->num_draws > 0); } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_zsa.c b/src/gallium/drivers/freedreno/a6xx/fd6_zsa.c index 290c8eb9296..9689de162d6 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_zsa.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_zsa.c @@ -47,45 +47,61 @@ fd6_zsa_state_create(struct pipe_context *pctx, so->base = *cso; - switch (cso->depth.func) { - case PIPE_FUNC_LESS: - case PIPE_FUNC_LEQUAL: - so->gras_lrz_cntl = A6XX_GRAS_LRZ_CNTL_ENABLE; - so->rb_lrz_cntl = A6XX_RB_LRZ_CNTL_ENABLE; - break; - - case PIPE_FUNC_GREATER: - case PIPE_FUNC_GEQUAL: - so->gras_lrz_cntl = A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_GREATER; - so->rb_lrz_cntl = A6XX_RB_LRZ_CNTL_ENABLE; - break; - - default: - /* LRZ not enabled */ - so->gras_lrz_cntl = 0; - break; - } - - if (cso->depth.writemask) { - if (cso->depth.enabled) - so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_UNK4; - so->lrz_write = true; - } - so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_ZFUNC(cso->depth.func); /* maps 1:1 */ - if (cso->depth.enabled) + if (cso->depth.enabled) { so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_ENABLE | A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE; + so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_Z_TEST_ENABLE; + + if (cso->depth.writemask) { + so->lrz_write = true; + } + + switch (cso->depth.func) { + case PIPE_FUNC_LESS: + case PIPE_FUNC_LEQUAL: + so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE; + so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE; + break; + + case PIPE_FUNC_GREATER: + case PIPE_FUNC_GEQUAL: + so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_GREATER; + so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE; + break; + + case PIPE_FUNC_NEVER: + so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE; + so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE; + so->lrz_write = false; + break; + + case PIPE_FUNC_EQUAL: + case PIPE_FUNC_NOTEQUAL: + case PIPE_FUNC_ALWAYS: + so->lrz_write = false; + so->invalidate_lrz = true; + break; + } + } + if (cso->depth.writemask) so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE; if (cso->stencil[0].enabled) { const struct pipe_stencil_state *s = &cso->stencil[0]; + /* stencil test happens before depth test, so without performing + * stencil test we don't really know what the updates to the + * depth buffer will be. + */ + so->lrz_write = false; + so->invalidate_lrz = true; + so->rb_stencil_control |= A6XX_RB_STENCIL_CONTROL_STENCIL_READ | A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE | diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_zsa.h b/src/gallium/drivers/freedreno/a6xx/fd6_zsa.h index 996158c3839..f1c4f6f29b6 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_zsa.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_zsa.h @@ -45,6 +45,7 @@ struct fd6_zsa_stateobj { uint32_t gras_lrz_cntl; uint32_t rb_lrz_cntl; bool lrz_write; + bool invalidate_lrz; struct fd_ringbuffer *stateobj; struct fd_ringbuffer *stateobj_no_alpha; -- 2.30.2