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:
@@ -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">
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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 |
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user