mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 15:00:10 +01:00
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:
parent
c938101bb5
commit
35fc1595b3
5 changed files with 47 additions and 22 deletions
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue