#include "a6xx.xml.h"
struct fd6_lrz_state {
- 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;
+ 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;
+ };
+ uint32_t val : 7;
+ };
};
/**
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)) {
{
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) {
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;
}
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
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;
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;
}