bool export_16bpc;
bool color_is_int8;
bool color_is_int10;
+ bool dcc_incompatible;
/* Color registers. */
unsigned cb_color_info;
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,
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,
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)
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;
}
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++) {
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.