summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/etnaviv/etnaviv_state.c
diff options
context:
space:
mode:
authorLucas Stach <[email protected]>2017-10-12 16:07:48 +0200
committerChristian Gmeiner <[email protected]>2017-10-14 16:40:08 +0200
commit4daee6733f3c4c755f9450a0dea33c0203cacd68 (patch)
tree21a5ecf25d7b20101cb53574556b38909ba8bb8b /src/gallium/drivers/etnaviv/etnaviv_state.c
parent34360ac6eddd44f20aae2a382fc4c7a77f9096ba (diff)
etnaviv: rework TS enable to be a derived state
Draw operations should not use the TS if the TS buffer content is invalid, as this leads to wrong rendering or even GPU hangs. As the TS valid status can change between draws (clear operations changing it to valid, blits using the RS to the color or ZS buffer changing it to invalid), the TS_MEM_CONFIG must be updated before each draw if the status has changed. This fixes the remaining TS related piglit failures (regressions of a standard run against a piglit run with TS completely disabled). Signed-off-by: Lucas Stach <[email protected]> Reviewed-by: Wladimir J. van der Laan <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]>
Diffstat (limited to 'src/gallium/drivers/etnaviv/etnaviv_state.c')
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_state.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c
index fc3d9f108fa..34bcb190699 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_state.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_state.c
@@ -165,7 +165,6 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
cs->PE_COLOR_STRIDE = cbuf->surf.stride;
if (cbuf->surf.ts_size) {
- ts_mem_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value;
cs->TS_COLOR_STATUS_BASE = cbuf->ts_reloc;
@@ -231,7 +230,6 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
cs->PE_DEPTH_NORMALIZE = fui(exp2f(depth_bits) - 1.0f);
if (zsbuf->surf.ts_size) {
- ts_mem_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
cs->TS_DEPTH_CLEAR_VALUE = zsbuf->level->clear_value;
cs->TS_DEPTH_STATUS_BASE = zsbuf->ts_reloc;
@@ -325,7 +323,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
cs->PE_LOGIC_OP = VIVS_PE_LOGIC_OP_SINGLE_BUFFER(ctx->specs.single_buffer ? 2 : 0);
ctx->framebuffer_s = *sv; /* keep copy of original structure */
- ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER;
+ ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_DERIVE_TS;
}
static void
@@ -572,6 +570,41 @@ etna_vertex_elements_state_bind(struct pipe_context *pctx, void *ve)
ctx->dirty |= ETNA_DIRTY_VERTEX_ELEMENTS;
}
+static bool
+etna_update_ts_config(struct etna_context *ctx)
+{
+ uint32_t new_ts_config = ctx->framebuffer.TS_MEM_CONFIG;
+
+ if (ctx->framebuffer_s.nr_cbufs > 0) {
+ struct etna_surface *c_surf = etna_surface(ctx->framebuffer_s.cbufs[0]);
+
+ if(c_surf->level->ts_size && c_surf->level->ts_valid) {
+ new_ts_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
+ } else {
+ new_ts_config &= ~VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
+ }
+ }
+
+ if (ctx->framebuffer_s.zsbuf) {
+ struct etna_surface *zs_surf = etna_surface(ctx->framebuffer_s.zsbuf);
+
+ if(zs_surf->level->ts_size && zs_surf->level->ts_valid) {
+ new_ts_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
+ } else {
+ new_ts_config &= ~VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
+ }
+ }
+
+ if (new_ts_config != ctx->framebuffer.TS_MEM_CONFIG) {
+ ctx->framebuffer.TS_MEM_CONFIG = new_ts_config;
+ ctx->dirty |= ETNA_DIRTY_TS;
+ }
+
+ ctx->dirty &= ~ETNA_DIRTY_DERIVE_TS;
+
+ return true;
+}
+
struct etna_state_updater {
bool (*update)(struct etna_context *ctx);
uint32_t dirty;
@@ -589,6 +622,9 @@ static const struct etna_state_updater etna_state_updates[] = {
},
{
etna_update_blend_color, ETNA_DIRTY_BLEND_COLOR | ETNA_DIRTY_FRAMEBUFFER,
+ },
+ {
+ etna_update_ts_config, ETNA_DIRTY_DERIVE_TS,
}
};