radeonsi: split si_clear_buffer to remove enum si_method
[mesa.git] / src / gallium / drivers / radeonsi / si_blit.c
index 0ab1356aecdde03578e078287907701b29506cc7..cf6495291bdb32713ff42a7ca82d39985e70d752 100644 (file)
@@ -59,6 +59,10 @@ void si_blitter_begin(struct si_context *sctx, enum si_blitter_op op)
                util_blitter_save_fragment_shader(sctx->blitter, sctx->ps_shader.cso);
                util_blitter_save_sample_mask(sctx->blitter, sctx->sample_mask);
                util_blitter_save_scissor(sctx->blitter, &sctx->scissors.states[0]);
+               util_blitter_save_window_rectangles(sctx->blitter,
+                                                   sctx->window_rectangles_include,
+                                                   sctx->num_window_rectangles,
+                                                   sctx->window_rectangles);
        }
 
        if (op & SI_SAVE_FRAMEBUFFER)
@@ -538,7 +542,7 @@ si_decompress_color_texture(struct si_context *sctx, struct si_texture *tex,
                            unsigned first_level, unsigned last_level)
 {
        /* CMASK or DCC can be discarded and we can still end up here. */
-       if (!tex->cmask_size && !tex->surface.fmask_size && !tex->dcc_offset)
+       if (!tex->cmask_buffer && !tex->surface.fmask_size && !tex->dcc_offset)
                return;
 
        si_blit_decompress_color(sctx, tex, first_level, last_level, 0,
@@ -859,7 +863,7 @@ static void si_decompress_subresource(struct pipe_context *ctx,
                si_decompress_depth(sctx, stex, planes,
                                    level, level,
                                    first_layer, last_layer);
-       } else if (stex->surface.fmask_size || stex->cmask_size || stex->dcc_offset) {
+       } else if (stex->surface.fmask_size || stex->cmask_buffer || stex->dcc_offset) {
                /* If we've rendered into the framebuffer and it's a blitting
                 * source, make sure the decompression pass is invoked
                 * by dirtying the framebuffer.
@@ -1139,7 +1143,7 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
            info->src.box.height == dst_height &&
            info->src.box.depth == 1 &&
            !dst->surface.is_linear &&
-           (!dst->cmask_size || !dst->dirty_level_mask)) { /* dst cannot be fast-cleared */
+           (!dst->cmask_buffer || !dst->dirty_level_mask)) { /* dst cannot be fast-cleared */
                /* Check the last constraint. */
                if (src->surface.micro_tile_mode != dst->surface.micro_tile_mode) {
                        /* The next fast clear will switch to this mode to
@@ -1325,16 +1329,40 @@ static void si_flush_resource(struct pipe_context *ctx,
        if (tex->dcc_separate_buffer && !tex->separate_dcc_dirty)
                return;
 
-       if (!tex->is_depth && (tex->cmask_size || tex->dcc_offset)) {
+       if (!tex->is_depth && (tex->cmask_buffer || tex->dcc_offset)) {
                si_blit_decompress_color(sctx, tex, 0, res->last_level,
                                         0, util_max_layer(res, 0),
                                         tex->dcc_separate_buffer != NULL);
        }
 
        /* Always do the analysis even if DCC is disabled at the moment. */
-       if (tex->dcc_gather_statistics && tex->separate_dcc_dirty) {
-               tex->separate_dcc_dirty = false;
-               vi_separate_dcc_process_and_reset_stats(ctx, tex);
+       if (tex->dcc_gather_statistics) {
+               bool separate_dcc_dirty = tex->separate_dcc_dirty;
+
+               /* If the color buffer hasn't been unbound and fast clear hasn't
+                * been used, separate_dcc_dirty is false, but there may have been
+                * new rendering. Check if the color buffer is bound and assume
+                * it's dirty.
+                *
+                * Note that DRI2 never unbinds window colorbuffers, which means
+                * the DCC pipeline statistics query would never be re-set and would
+                * keep adding new results until all free memory is exhausted if we
+                * didn't do this.
+                */
+               if (!separate_dcc_dirty) {
+                       for (unsigned i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) {
+                               if (sctx->framebuffer.state.cbufs[i] &&
+                                   sctx->framebuffer.state.cbufs[i]->texture == res) {
+                                       separate_dcc_dirty = true;
+                                       break;
+                               }
+                       }
+               }
+
+               if (separate_dcc_dirty) {
+                       tex->separate_dcc_dirty = false;
+                       vi_separate_dcc_process_and_reset_stats(ctx, tex);
+               }
        }
 }