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 <robdclark@chromium.org>
This commit is contained in:
Rob Clark
2019-12-06 11:34:39 -08:00
committed by Rob Clark
parent 3c479849c5
commit 1b4c12d3ee
5 changed files with 50 additions and 30 deletions

View File

@@ -1975,10 +1975,9 @@ to upconvert to 32b float internally?
<bitfield name="LRZ_WRITE" pos="1" type="boolean"/>
<doc>update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL</doc>
<bitfield name="GREATER" pos="2" type="boolean"/>
<!-- set at end of batch that had LRZ enabled (to flush/disable it?) -->
<bitfield name="UNK3" pos="3" type="boolean"/>
<!-- set when depth-test + depth-write enabled -->
<bitfield name="UNK4" pos="4" type="boolean"/>
<bitfield name="Z_TEST_ENABLE" pos="4" type="boolean"/>
</reg32>
<reg32 offset="0x8101" name="GRAS_UNKNOWN_8101"/>
<reg32 offset="0x8102" name="GRAS_2D_BLIT_INFO">

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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 |

View File

@@ -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;