diff options
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 29 |
3 files changed, 49 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 2feca0172fa..6a52247d458 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -287,6 +287,7 @@ struct r600_surface { bool export_16bpc; bool color_is_int8; bool color_is_int10; + bool dcc_incompatible; /* Color registers. */ unsigned cb_color_info; @@ -801,6 +802,9 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ); bool vi_dcc_formats_compatible(enum pipe_format format1, enum pipe_format format2); +bool vi_dcc_formats_are_incompatible(struct pipe_resource *tex, + unsigned level, + enum pipe_format view_format); void vi_disable_dcc_if_incompatible_format(struct r600_common_context *rctx, struct pipe_resource *tex, unsigned level, diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 0daa5ea53e2..877f5552bd5 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -1903,6 +1903,18 @@ bool vi_dcc_formats_compatible(enum pipe_format format1, type1 == type2; } +bool vi_dcc_formats_are_incompatible(struct pipe_resource *tex, + unsigned level, + enum pipe_format view_format) +{ + struct r600_texture *rtex = (struct r600_texture *)tex; + + return vi_dcc_enabled(rtex, level) && + !vi_dcc_formats_compatible(tex->format, view_format); +} + +/* This can't be merged with the above function, because + * vi_dcc_formats_compatible should be called only when DCC is enabled. */ void vi_disable_dcc_if_incompatible_format(struct r600_common_context *rctx, struct pipe_resource *tex, unsigned level, @@ -1922,7 +1934,6 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe, unsigned width0, unsigned height0, unsigned width, unsigned height) { - struct r600_common_context *rctx = (struct r600_common_context*)pipe; struct r600_surface *surface = CALLOC_STRUCT(r600_surface); if (!surface) @@ -1942,11 +1953,10 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe, surface->width0 = width0; surface->height0 = height0; - if (texture->target != PIPE_BUFFER) - vi_disable_dcc_if_incompatible_format(rctx, texture, - templ->u.tex.level, - templ->format); - + surface->dcc_incompatible = + texture->target != PIPE_BUFFER && + vi_dcc_formats_are_incompatible(texture, templ->u.tex.level, + templ->format); return &surface->base; } diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 866c2063994..2c2e3c77f6e 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2439,6 +2439,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, struct r600_texture *rtex; bool old_any_dst_linear = sctx->framebuffer.any_dst_linear; unsigned old_nr_samples = sctx->framebuffer.nr_samples; + bool unbound = false; int i; for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) { @@ -2450,6 +2451,34 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, vi_separate_dcc_stop_query(ctx, rtex); } + /* Disable DCC if the formats are incompatible. */ + for (i = 0; i < state->nr_cbufs; i++) { + if (!state->cbufs[i]) + continue; + + surf = (struct r600_surface*)state->cbufs[i]; + rtex = (struct r600_texture*)surf->base.texture; + + if (!surf->dcc_incompatible) + continue; + + /* Since the DCC decompression calls back into set_framebuffer- + * _state, we need to unbind the framebuffer, so that + * vi_separate_dcc_stop_query isn't called twice with the same + * color buffer. + */ + if (!unbound) { + util_copy_framebuffer_state(&sctx->framebuffer.state, NULL); + unbound = true; + } + + if (vi_dcc_enabled(rtex, surf->base.u.tex.level)) + if (!r600_texture_disable_dcc(&sctx->b, rtex)) + sctx->b.decompress_dcc(ctx, rtex); + + surf->dcc_incompatible = false; + } + /* Only flush TC when changing the framebuffer state, because * the only client not using TC that can change textures is * the framebuffer. |