radeonsi: clarify the conditions when FLUSH_AND_INV_DB is needed
[mesa.git] / src / gallium / drivers / radeonsi / si_clear.c
index a83f65c6f1be5cb5cbcca9e834816b82413f7c1c..2af778b41ad423ac8ff1937652b00bd21abc6242 100644 (file)
@@ -25,7 +25,7 @@
 #include "si_pipe.h"
 #include "sid.h"
 
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 #include "util/u_pack_color.h"
 #include "util/u_surface.h"
 
@@ -76,12 +76,8 @@ static bool si_set_clear_color(struct si_texture *tex,
                       color->ui[0] == color->ui[2]);
                uc.ui[0] = color->ui[0];
                uc.ui[1] = color->ui[3];
-       } else if (util_format_is_pure_uint(surface_format)) {
-               util_format_write_4ui(surface_format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
-       } else if (util_format_is_pure_sint(surface_format)) {
-               util_format_write_4i(surface_format, color->i, 0, &uc, 0, 0, 0, 1, 1);
        } else {
-               util_pack_color(color->f, surface_format, &uc);
+               util_pack_color_union(surface_format, &uc, color);
        }
 
        if (memcmp(tex->color_clear_value, &uc, 2 * sizeof(uint32_t)) == 0)
@@ -245,7 +241,7 @@ bool vi_dcc_clear_level(struct si_context *sctx,
                dcc_offset = 0;
        } else {
                dcc_buffer = &tex->buffer.b.b;
-               dcc_offset = tex->dcc_offset;
+               dcc_offset = tex->surface.dcc_offset;
        }
 
        if (sctx->chip_class >= GFX9) {
@@ -400,7 +396,7 @@ static void si_do_fast_color_clear(struct si_context *sctx,
        int i;
 
        /* This function is broken in BE, so just disable this path for now */
-#ifdef PIPE_ARCH_BIG_ENDIAN
+#if UTIL_ARCH_BIG_ENDIAN
        return;
 #endif
 
@@ -510,12 +506,13 @@ static void si_do_fast_color_clear(struct si_context *sctx,
                                continue;
 
                        tex->separate_dcc_dirty = true;
+                       tex->displayable_dcc_dirty = true;
 
                        /* DCC fast clear with MSAA should clear CMASK to 0xC. */
                        if (tex->buffer.b.b.nr_samples >= 2 && tex->cmask_buffer) {
                                uint32_t clear_value = 0xCCCCCCCC;
                                si_clear_buffer(sctx, &tex->cmask_buffer->b.b,
-                                               tex->cmask_offset, tex->surface.cmask_size,
+                                               tex->surface.cmask_offset, tex->surface.cmask_size,
                                                &clear_value, 4, SI_COHERENCY_CB_META, false);
                                fmask_decompress_needed = true;
                        }
@@ -540,7 +537,7 @@ static void si_do_fast_color_clear(struct si_context *sctx,
                        /* Do the fast clear. */
                        uint32_t clear_value = 0;
                        si_clear_buffer(sctx, &tex->cmask_buffer->b.b,
-                                       tex->cmask_offset, tex->surface.cmask_size,
+                                       tex->surface.cmask_offset, tex->surface.cmask_size,
                                        &clear_value, 4, SI_COHERENCY_CB_META, false);
                        eliminate_needed = true;
                }
@@ -559,7 +556,7 @@ static void si_do_fast_color_clear(struct si_context *sctx,
                /* Chips with DCC constant encoding don't need to set the clear
                 * color registers for DCC clear values 0 and 1.
                 */
-               if (sctx->screen->has_dcc_constant_encode && !eliminate_needed)
+               if (sctx->screen->info.has_dcc_constant_encode && !eliminate_needed)
                        continue;
 
                if (si_set_clear_color(tex, fb->cbufs[i]->format, color)) {
@@ -578,6 +575,7 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
        struct pipe_surface *zsbuf = fb->zsbuf;
        struct si_texture *zstex =
                zsbuf ? (struct si_texture*)zsbuf->texture : NULL;
+       bool needs_db_flush = false;
 
        if (buffers & PIPE_CLEAR_COLOR) {
                si_do_fast_color_clear(sctx, &buffers, color);
@@ -613,6 +611,11 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
                        }
 
                        if (zstex->depth_clear_value != (float)depth) {
+                               if ((zstex->depth_clear_value != 0) != (depth != 0)) {
+                                       /* ZRANGE_PRECISION register of a bound surface will change so we
+                                        * must flush the DB caches. */
+                                       needs_db_flush = true;
+                               }
                                /* Update DB_DEPTH_CLEAR. */
                                zstex->depth_clear_value = depth;
                                sctx->framebuffer.dirty_zsbuf = true;
@@ -644,19 +647,7 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
                        si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);
                }
 
-               /* TODO: Find out what's wrong here. Fast depth clear leads to
-                * corruption in ARK: Survival Evolved, but that may just be
-                * a coincidence and the root cause is elsewhere.
-                *
-                * The corruption can be fixed by putting the DB flush before
-                * or after the depth clear. (surprisingly)
-                *
-                * https://bugs.freedesktop.org/show_bug.cgi?id=102955 (apitrace)
-                *
-                * This hack decreases back-to-back ClearDepth performance.
-                */
-               if ((sctx->db_depth_clear || sctx->db_stencil_clear) &&
-                   sctx->screen->options.clear_db_cache_before_clear)
+               if (needs_db_flush)
                        sctx->flags |= SI_CONTEXT_FLUSH_AND_INV_DB;
        }
 
@@ -692,7 +683,7 @@ static void si_clear_render_target(struct pipe_context *ctx,
        struct si_context *sctx = (struct si_context *)ctx;
        struct si_texture *sdst = (struct si_texture*)dst->texture;
 
-       if (dst->texture->nr_samples <= 1 && !sdst->dcc_offset) {
+       if (dst->texture->nr_samples <= 1 && !sdst->surface.dcc_offset) {
                si_compute_clear_render_target(ctx, dst, color, dstx, dsty, width,
                                               height, render_condition_enabled);
                return;
@@ -733,8 +724,6 @@ static void si_clear_texture(struct pipe_context *pipe,
        struct si_texture *stex = (struct si_texture*)tex;
        struct pipe_surface tmpl = {{0}};
        struct pipe_surface *sf;
-       const struct util_format_description *desc =
-               util_format_description(tex->format);
 
        tmpl.format = tex->format;
        tmpl.u.tex.first_layer = box->z;
@@ -751,11 +740,12 @@ static void si_clear_texture(struct pipe_context *pipe,
 
                /* Depth is always present. */
                clear = PIPE_CLEAR_DEPTH;
-               desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
+               util_format_unpack_z_float(tex->format, &depth, data, 1);
 
                if (stex->surface.has_stencil) {
                        clear |= PIPE_CLEAR_STENCIL;
-                       desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
+                       util_format_unpack_s_8uint(tex->format,
+                                                  &stencil, data, 1);
                }
 
                si_clear_depth_stencil(pipe, sf, clear, depth, stencil,
@@ -764,13 +754,7 @@ static void si_clear_texture(struct pipe_context *pipe,
        } else {
                union pipe_color_union color;
 
-               /* pipe_color_union requires the full vec4 representation. */
-               if (util_format_is_pure_uint(tex->format))
-                       desc->unpack_rgba_uint(color.ui, 0, data, 0, 1, 1);
-               else if (util_format_is_pure_sint(tex->format))
-                       desc->unpack_rgba_sint(color.i, 0, data, 0, 1, 1);
-               else
-                       desc->unpack_rgba_float(color.f, 0, data, 0, 1, 1);
+               util_format_unpack_rgba(tex->format, color.ui, data, 1);
 
                if (screen->is_format_supported(screen, tex->format,
                                                tex->target, 0, 0,