radv: Don't handle DCC in compute resolve.
[mesa.git] / src / amd / vulkan / radv_meta_clear.c
index 71c4dbcbd6b5e4565e50f4b52254b21a27345f55..b42ecedfc9809d15ad5ffb14986e203987e9a2ee 100644 (file)
@@ -296,26 +296,26 @@ radv_device_finish_meta_clear_state(struct radv_device *device)
                for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) {
                        radv_DestroyPipeline(radv_device_to_handle(device),
                                             state->clear[i].color_pipelines[j],
-                                            &device->meta_state.alloc);
+                                            &state->alloc);
                        radv_DestroyRenderPass(radv_device_to_handle(device),
                                               state->clear[i].render_pass[j],
-                                              &device->meta_state.alloc);
+                                              &state->alloc);
                }
 
                for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) {
                        radv_DestroyPipeline(radv_device_to_handle(device),
                                             state->clear[i].depth_only_pipeline[j],
-                                            &device->meta_state.alloc);
+                                            &state->alloc);
                        radv_DestroyPipeline(radv_device_to_handle(device),
                                             state->clear[i].stencil_only_pipeline[j],
-                                            &device->meta_state.alloc);
+                                            &state->alloc);
                        radv_DestroyPipeline(radv_device_to_handle(device),
                                             state->clear[i].depthstencil_pipeline[j],
-                                            &device->meta_state.alloc);
+                                            &state->alloc);
                }
                radv_DestroyRenderPass(radv_device_to_handle(device),
                                      state->clear[i].depthstencil_rp,
-                                     &device->meta_state.alloc);
+                                     &state->alloc);
        }
        radv_DestroyPipelineLayout(radv_device_to_handle(device),
                                   state->clear_color_p_layout,
@@ -374,10 +374,8 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
 
        radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false);
 
-       if (cmd_buffer->state.pipeline != radv_pipeline_from_handle(pipeline)) {
-               radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
-                                          pipeline);
-       }
+       radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
+                            pipeline);
 
        radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
                        .x = clear_rect->rect.offset.x,
@@ -543,8 +541,10 @@ create_depthstencil_pipeline(struct radv_device *device,
 
 static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer,
                                      const struct radv_image_view *iview,
+                                     VkImageAspectFlags aspects,
                                      VkImageLayout layout,
-                                     const VkClearRect *clear_rect)
+                                     const VkClearRect *clear_rect,
+                                     VkClearDepthStencilValue clear_value)
 {
        uint32_t queue_mask = radv_image_queue_family_mask(iview->image,
                                                           cmd_buffer->queue_family_index,
@@ -553,6 +553,11 @@ static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer,
            clear_rect->rect.extent.width != iview->extent.width ||
            clear_rect->rect.extent.height != iview->extent.height)
                return false;
+       if (iview->image->tc_compatible_htile &&
+           (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && clear_value.depth != 0.0 &&
+             clear_value.depth != 1.0) ||
+            ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && clear_value.stencil != 0)))
+               return false;
        if (iview->image->surface.htile_size &&
            iview->base_mip == 0 &&
            iview->base_layer == 0 &&
@@ -572,7 +577,7 @@ pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer,
                           const VkClearRect *clear_rect,
                           VkClearDepthStencilValue clear_value)
 {
-       bool fast = depth_view_can_fast_clear(cmd_buffer, iview, layout, clear_rect);
+       bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout, clear_rect, clear_value);
        int index = DEPTH_CLEAR_SLOW;
 
        if (fast) {
@@ -609,10 +614,6 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
        const uint32_t samples_log2 = ffs(samples) - 1;
        VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
 
-       assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
-              aspects == VK_IMAGE_ASPECT_STENCIL_BIT ||
-              aspects == (VK_IMAGE_ASPECT_DEPTH_BIT |
-                          VK_IMAGE_ASPECT_STENCIL_BIT));
        assert(pass_att != VK_ATTACHMENT_UNUSED);
 
        if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
@@ -637,12 +638,12 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
                                                         clear_rect,
                                                         clear_value);
 
-       if (cmd_buffer->state.pipeline != radv_pipeline_from_handle(pipeline)) {
-               radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
-                                    pipeline);
-       }
+       radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
+                            pipeline);
 
-       if (depth_view_can_fast_clear(cmd_buffer, iview, subpass->depth_stencil_attachment.layout, clear_rect))
+       if (depth_view_can_fast_clear(cmd_buffer, iview, aspects,
+                                     subpass->depth_stencil_attachment.layout,
+                                     clear_rect, clear_value))
                radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects);
 
        radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
@@ -673,12 +674,12 @@ emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer,
        const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
        VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
        VkImageAspectFlags aspects = clear_att->aspectMask;
-       uint32_t clear_word;
+       uint32_t clear_word, flush_bits;
 
        if (!iview->image->surface.htile_size)
                return false;
 
-       if (cmd_buffer->device->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
+       if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
                return false;
 
        if (!radv_layout_is_htile_compressed(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index)))
@@ -694,9 +695,6 @@ emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer,
        if (iview->image->info.array_size != iview->layer_count)
                goto fail;
 
-       if (iview->image->info.levels > 1)
-               goto fail;
-
        if (!radv_image_extent_compare(iview->image, &iview->extent))
                goto fail;
 
@@ -728,20 +726,17 @@ emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer,
                cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_DB |
                                                RADV_CMD_FLAG_FLUSH_AND_INV_DB_META;
 
-       radv_fill_buffer(cmd_buffer, iview->image->bo,
-                        iview->image->offset + iview->image->htile_offset,
-                        iview->image->surface.htile_size, clear_word);
-
+       flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo,
+                                     iview->image->offset + iview->image->htile_offset,
+                                     iview->image->surface.htile_size, clear_word);
 
        radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects);
-       if (post_flush)
-               *post_flush |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
-                              RADV_CMD_FLAG_INV_VMEM_L1 |
-                              RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2;
-       else
-               cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
-                                               RADV_CMD_FLAG_INV_VMEM_L1 |
-                                               RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2;
+       if (post_flush) {
+               *post_flush |= flush_bits;
+       } else {
+               cmd_buffer->state.flush_bits |= flush_bits;
+       }
+
        return true;
 fail:
        return false;
@@ -950,13 +945,13 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
        const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
        const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
        VkClearColorValue clear_value = clear_att->clearValue.color;
-       uint32_t clear_color[2];
+       uint32_t clear_color[2], flush_bits;
        bool ret;
 
        if (!iview->image->cmask.size && !iview->image->surface.dcc_size)
                return false;
 
-       if (cmd_buffer->device->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
+       if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
                return false;
 
        if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index)))
@@ -1019,30 +1014,22 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
                                             &clear_value, &reset_value,
                                             &can_avoid_fast_clear_elim);
 
-               radv_fill_buffer(cmd_buffer, iview->image->bo,
-                                iview->image->offset + iview->image->dcc_offset,
-                                iview->image->surface.dcc_size, reset_value);
+               flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo,
+                                             iview->image->offset + iview->image->dcc_offset,
+                                             iview->image->surface.dcc_size, reset_value);
                radv_set_dcc_need_cmask_elim_pred(cmd_buffer, iview->image,
                                                  !can_avoid_fast_clear_elim);
        } else {
-
-               if (iview->image->surface.bpe > 8) {
-                       /* 128 bit formats not supported */
-                       return false;
-               }
-               radv_fill_buffer(cmd_buffer, iview->image->bo,
-                                iview->image->offset + iview->image->cmask.offset,
-                                iview->image->cmask.size, 0);
+               flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo,
+                                             iview->image->offset + iview->image->cmask.offset,
+                                             iview->image->cmask.size, 0);
        }
 
-       if (post_flush)
-               *post_flush |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
-                              RADV_CMD_FLAG_INV_VMEM_L1 |
-                              RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2;
-       else
-               cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
-                                               RADV_CMD_FLAG_INV_VMEM_L1 |
-                                               RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2;
+       if (post_flush) {
+               *post_flush |= flush_bits;
+       } else {
+               cmd_buffer->state.flush_bits |= flush_bits;
+       }
 
        radv_set_color_clear_regs(cmd_buffer, iview->image, subpass_att, clear_color);
 
@@ -1143,7 +1130,9 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
        if (!radv_subpass_needs_clear(cmd_buffer))
                return;
 
-       radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer);
+       radv_meta_save(&saved_state, cmd_buffer,
+                      RADV_META_SAVE_GRAPHICS_PIPELINE |
+                      RADV_META_SAVE_CONSTANTS);
 
        for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
                uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
@@ -1364,11 +1353,6 @@ radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer,
        }
 }
 
-union meta_saved_state {
-       struct radv_meta_saved_state gfx;
-       struct radv_meta_saved_compute_state compute;
-};
-
 void radv_CmdClearColorImage(
        VkCommandBuffer                             commandBuffer,
        VkImage                                     image_h,
@@ -1379,22 +1363,25 @@ void radv_CmdClearColorImage(
 {
        RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
        RADV_FROM_HANDLE(radv_image, image, image_h);
-       union meta_saved_state saved_state;
+       struct radv_meta_saved_state saved_state;
        bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
 
-       if (cs)
-               radv_meta_save_compute(&saved_state.compute, cmd_buffer, 16);
-       else
-               radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state.gfx, cmd_buffer);
+       if (cs) {
+               radv_meta_save(&saved_state, cmd_buffer,
+                              RADV_META_SAVE_COMPUTE_PIPELINE |
+                              RADV_META_SAVE_CONSTANTS |
+                              RADV_META_SAVE_DESCRIPTORS);
+       } else {
+               radv_meta_save(&saved_state, cmd_buffer,
+                              RADV_META_SAVE_GRAPHICS_PIPELINE |
+                              RADV_META_SAVE_CONSTANTS);
+       }
 
        radv_cmd_clear_image(cmd_buffer, image, imageLayout,
                             (const VkClearValue *) pColor,
                             rangeCount, pRanges, cs);
 
-       if (cs)
-               radv_meta_restore_compute(&saved_state.compute, cmd_buffer);
-       else
-               radv_meta_restore(&saved_state.gfx, cmd_buffer);
+       radv_meta_restore(&saved_state, cmd_buffer);
 }
 
 void radv_CmdClearDepthStencilImage(
@@ -1409,7 +1396,9 @@ void radv_CmdClearDepthStencilImage(
        RADV_FROM_HANDLE(radv_image, image, image_h);
        struct radv_meta_saved_state saved_state;
 
-       radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer);
+       radv_meta_save(&saved_state, cmd_buffer,
+                      RADV_META_SAVE_GRAPHICS_PIPELINE |
+                      RADV_META_SAVE_CONSTANTS);
 
        radv_cmd_clear_image(cmd_buffer, image, imageLayout,
                             (const VkClearValue *) pDepthStencil,
@@ -1433,7 +1422,9 @@ void radv_CmdClearAttachments(
        if (!cmd_buffer->state.subpass)
                return;
 
-       radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer);
+       radv_meta_save(&saved_state, cmd_buffer,
+                      RADV_META_SAVE_GRAPHICS_PIPELINE |
+                      RADV_META_SAVE_CONSTANTS);
 
        /* FINISHME: We can do better than this dumb loop. It thrashes too much
         * state.