freedreno/a6xx: Pre-compute PROG related LRZ state

PROG state mostly just disables various LRZ related flags, which can
be handled as a simple mask.  The exception is ztest mode, which is
either overriden by PROG state, or we use the all 1's value (which
isn't valid from hw standpoint) to signal that it needs to be computed
at draw time, which fortunately fits in with the bitmask approach.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21274>
This commit is contained in:
Rob Clark 2023-02-11 08:06:38 -08:00 committed by Marge Bot
parent c938101bb5
commit 35fc1595b3
5 changed files with 47 additions and 22 deletions

View file

@ -954,6 +954,8 @@ to upconvert to 32b float internally?
know will definitely not be visible.
</doc>
<value value="0x2" name="A6XX_EARLY_LRZ_LATE_Z"/>
<doc>Not a real hw value, used internally by mesa</doc>
<value value="0x3" name="A6XX_INVALID_ZTEST"/>
</enum>
<domain name="A6XX" width="32">

View file

@ -39,13 +39,18 @@
#include "a6xx.xml.h"
struct fd6_lrz_state {
bool enable : 1;
bool write : 1;
bool test : 1;
enum fd_lrz_direction direction : 2;
union {
struct {
bool enable : 1;
bool write : 1;
bool test : 1;
enum fd_lrz_direction direction : 2;
/* this comes from the fs program state, rather than zsa: */
enum a6xx_ztest_mode z_mode : 2;
/* this comes from the fs program state, rather than zsa: */
enum a6xx_ztest_mode z_mode : 2;
};
uint32_t val : 7;
};
};
/**

View file

@ -107,16 +107,15 @@ build_vbo_state(struct fd6_emit *emit) assert_dt
static enum a6xx_ztest_mode
compute_ztest_mode(struct fd6_emit *emit, bool lrz_valid) assert_dt
{
if (emit->prog->lrz_mask.z_mode != A6XX_INVALID_ZTEST)
return emit->prog->lrz_mask.z_mode;
struct fd_context *ctx = emit->ctx;
struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
struct fd6_zsa_stateobj *zsa = fd6_zsa_stateobj(ctx->zsa);
const struct ir3_shader_variant *fs = emit->fs;
if (fs->fs.early_fragment_tests)
return A6XX_EARLY_Z;
if (fs->no_earlyz || fs->writes_pos || !zsa->base.depth_enabled ||
fs->writes_stencilref) {
if (!zsa->base.depth_enabled) {
return A6XX_LATE_Z;
} else if ((fs->has_kill || zsa->alpha_test) &&
(zsa->writes_zs || !pfb->zsbuf)) {
@ -142,7 +141,6 @@ compute_lrz_state(struct fd6_emit *emit) assert_dt
{
struct fd_context *ctx = emit->ctx;
struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
const struct ir3_shader_variant *fs = emit->fs;
struct fd6_lrz_state lrz;
if (!pfb->zsbuf) {
@ -158,9 +156,10 @@ compute_lrz_state(struct fd6_emit *emit) assert_dt
lrz = zsa->lrz;
lrz.val &= emit->prog->lrz_mask.val;
/* normalize lrz state: */
if (reads_dest || fs->writes_pos || fs->no_earlyz || fs->has_kill ||
blend->base.alpha_to_coverage) {
if (reads_dest || blend->base.alpha_to_coverage) {
lrz.write = false;
}
@ -222,12 +221,6 @@ compute_lrz_state(struct fd6_emit *emit) assert_dt
memset(&lrz, 0, sizeof(lrz));
}
if (fs->no_earlyz || fs->writes_pos) {
lrz.enable = false;
lrz.write = false;
lrz.test = false;
}
lrz.z_mode = compute_ztest_mode(emit, rsc->lrz_valid);
/* Once we start writing to the real depth buffer, we lock in the
@ -255,8 +248,7 @@ build_lrz(struct fd6_emit *emit) assert_dt
struct fd6_lrz_state lrz = compute_lrz_state(emit);
/* If the LRZ state has not changed, we can skip the emit: */
if (!ctx->last.dirty &&
!memcmp(&fd6_ctx->last.lrz, &lrz, sizeof(lrz)))
if (!ctx->last.dirty && (fd6_ctx->last.lrz.val == lrz.val))
return NULL;
fd6_ctx->last.lrz = lrz;

View file

@ -1366,6 +1366,27 @@ fd6_program_create(void *data, struct ir3_shader_variant *bs,
state->num_driver_params = num_dp;
state->lrz_mask.val = ~0;
if (fs->has_kill) {
state->lrz_mask.write = false;
}
if (fs->no_earlyz || fs->writes_pos) {
state->lrz_mask.enable = false;
state->lrz_mask.write = false;
state->lrz_mask.test = false;
}
if (fs->fs.early_fragment_tests) {
state->lrz_mask.z_mode = A6XX_EARLY_Z;
} else if (fs->no_earlyz || fs->writes_pos || fs->writes_stencilref) {
state->lrz_mask.z_mode = A6XX_LATE_Z;
} else {
/* Wildcard indicates that we need to figure out at draw time: */
state->lrz_mask.z_mode = A6XX_INVALID_ZTEST;
}
return &state->base;
}

View file

@ -75,6 +75,11 @@ struct fd6_program_state {
* calculate it up-front.
*/
uint32_t user_consts_cmdstream_size;
/**
* The FS contribution to LRZ state
*/
struct fd6_lrz_state lrz_mask;
};
static inline struct fd6_program_state *