Mesa (main): v3dv: remove fallback path for vkCmdClearAttachments

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 12 07:56:03 UTC 2021


Module: Mesa
Branch: main
Commit: 5ba7f64b454b78c71be0827c74f37497fd135822
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5ba7f64b454b78c71be0827c74f37497fd135822

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Thu Jul  8 13:13:17 2021 +0200

v3dv: remove fallback path for vkCmdClearAttachments

Now that we support layered clears this code is dead.

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11783>

---

 src/broadcom/vulkan/v3dv_meta_clear.c | 354 ----------------------------------
 1 file changed, 354 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_meta_clear.c b/src/broadcom/vulkan/v3dv_meta_clear.c
index 7bbb4aa50a6..9d6a39e074c 100644
--- a/src/broadcom/vulkan/v3dv_meta_clear.c
+++ b/src/broadcom/vulkan/v3dv_meta_clear.c
@@ -827,261 +827,6 @@ fail:
    return result;
 }
 
-static VkFormat
-get_color_format_for_depth_stencil_format(VkFormat format)
-{
-   /* For single depth/stencil aspect formats, we just choose a compatible
-    * 1 channel format, but for combined depth/stencil we want an RGBA format
-    * so we can specify the channels we want to write.
-    */
-   switch (format) {
-   case VK_FORMAT_D16_UNORM:
-      return VK_FORMAT_R16_UINT;
-   case VK_FORMAT_D32_SFLOAT:
-      return VK_FORMAT_R32_SFLOAT;
-   case VK_FORMAT_X8_D24_UNORM_PACK32:
-   case VK_FORMAT_D24_UNORM_S8_UINT:
-      return VK_FORMAT_R8G8B8A8_UINT;
-   default:
-      unreachable("Unsupported depth/stencil format");
-   };
-}
-
-/**
- * Emits a scissored quad in the clear color, however, unlike the subpass
- * versions, this creates its own framebuffer setup with a single color
- * attachment, and therefore spanws new jobs, making it much slower than the
- * subpass version.
- *
- * This path is only used when we have clears on layers other than the
- * base layer in a framebuffer attachment, since we don't currently
- * support any form of layered rendering that would allow us to implement
- * this in the subpass version.
- *
- * Notice this can also handle depth/stencil formats by rendering to the
- * depth/stencil target using a compatible color format.
- */
-static void
-emit_color_clear_rect(struct v3dv_cmd_buffer *cmd_buffer,
-                      uint32_t attachment_idx,
-                      VkFormat rt_format,
-                      uint32_t rt_samples,
-                      uint32_t rt_components,
-                      VkClearColorValue clear_color,
-                      const VkClearRect *rect)
-{
-   assert(cmd_buffer->state.pass);
-   struct v3dv_device *device = cmd_buffer->device;
-   struct v3dv_render_pass *pass = cmd_buffer->state.pass;
-
-   assert(attachment_idx != VK_ATTACHMENT_UNUSED &&
-          attachment_idx < pass->attachment_count);
-
-   struct v3dv_meta_color_clear_pipeline *pipeline = NULL;
-   VkResult result =
-      get_color_clear_pipeline(device,
-                               NULL, 0, /* Not using current subpass */
-                               0, attachment_idx,
-                               rt_format, rt_samples, rt_components, false,
-                               &pipeline);
-   if (result != VK_SUCCESS) {
-      if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
-         v3dv_flag_oom(cmd_buffer, NULL);
-      return;
-   }
-   assert(pipeline && pipeline->pipeline && pipeline->pass);
-
-   /* Since we are not emitting the draw call in the current subpass we should
-    * be caching the clear pipeline and we don't have to take care of destorying
-    * it below.
-    */
-   assert(pipeline->cached);
-
-   /* Store command buffer state for the current subpass before we interrupt
-    * it to emit the color clear pass and then finish the job for the
-    * interrupted subpass.
-    */
-   v3dv_cmd_buffer_meta_state_push(cmd_buffer, false);
-   v3dv_cmd_buffer_finish_job(cmd_buffer);
-
-   struct v3dv_framebuffer *subpass_fb =
-      v3dv_framebuffer_from_handle(cmd_buffer->state.meta.framebuffer);
-   VkCommandBuffer cmd_buffer_handle = v3dv_cmd_buffer_to_handle(cmd_buffer);
-   VkDevice device_handle = v3dv_device_to_handle(cmd_buffer->device);
-
-   /* If we are clearing a depth/stencil attachment as a color attachment
-    * then we need to configure the framebuffer to the compatible color
-    * format.
-    */
-   const struct v3dv_image_view *att_iview =
-      subpass_fb->attachments[attachment_idx];
-   const bool is_depth_or_stencil =
-      vk_format_is_depth_or_stencil(att_iview->vk_format);
-
-   /* Emit the pass for each attachment layer, which creates a framebuffer
-    * for each selected layer of the attachment and then renders a scissored
-    * quad in the clear color.
-    */
-   uint32_t dirty_dynamic_state = 0;
-   for (uint32_t i = 0; i < rect->layerCount; i++) {
-      VkImageViewCreateInfo fb_layer_view_info = {
-         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-         .image = v3dv_image_to_handle((struct v3dv_image *)att_iview->image),
-         .viewType =
-            v3dv_image_type_to_view_type(att_iview->image->type),
-         .format = is_depth_or_stencil ? rt_format : att_iview->vk_format,
-         .subresourceRange = {
-            .aspectMask = is_depth_or_stencil ? VK_IMAGE_ASPECT_COLOR_BIT :
-                                                att_iview->aspects,
-            .baseMipLevel = att_iview->base_level,
-            .levelCount = att_iview->max_level - att_iview->base_level + 1,
-            .baseArrayLayer = att_iview->first_layer + rect->baseArrayLayer + i,
-            .layerCount = 1,
-         },
-      };
-      VkImageView fb_attachment;
-      result = v3dv_CreateImageView(v3dv_device_to_handle(device),
-                                    &fb_layer_view_info,
-                                    &device->vk.alloc, &fb_attachment);
-      if (result != VK_SUCCESS)
-         goto fail;
-
-      v3dv_cmd_buffer_add_private_obj(
-         cmd_buffer, (uintptr_t)fb_attachment,
-         (v3dv_cmd_buffer_private_obj_destroy_cb)v3dv_DestroyImageView);
-
-      VkFramebufferCreateInfo fb_info = {
-         .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-         .renderPass = v3dv_render_pass_to_handle(pass),
-         .attachmentCount = 1,
-         .pAttachments = &fb_attachment,
-         .width = subpass_fb->width,
-         .height = subpass_fb->height,
-         .layers = 1,
-      };
-
-      VkFramebuffer fb;
-      result = v3dv_CreateFramebuffer(device_handle, &fb_info,
-                                      &cmd_buffer->device->vk.alloc, &fb);
-      if (result != VK_SUCCESS)
-         goto fail;
-
-      v3dv_cmd_buffer_add_private_obj(
-         cmd_buffer, (uintptr_t)fb,
-         (v3dv_cmd_buffer_private_obj_destroy_cb)v3dv_DestroyFramebuffer);
-
-      VkRenderPassBeginInfo rp_info = {
-         .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-         .renderPass = pipeline->pass,
-         .framebuffer = fb,
-         .renderArea = {
-            .offset = { rect->rect.offset.x, rect->rect.offset.y },
-            .extent = { rect->rect.extent.width, rect->rect.extent.height } },
-         .clearValueCount = 0,
-      };
-
-      v3dv_CmdBeginRenderPass(cmd_buffer_handle, &rp_info,
-                              VK_SUBPASS_CONTENTS_INLINE);
-
-      struct v3dv_job *job = cmd_buffer->state.job;
-      if (!job)
-         goto fail;
-      job->is_subpass_continue = true;
-
-      v3dv_CmdPushConstants(cmd_buffer_handle,
-                            device->meta.color_clear.p_layout,
-                            VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16,
-                            &clear_color);
-
-      v3dv_CmdBindPipeline(cmd_buffer_handle,
-                           VK_PIPELINE_BIND_POINT_GRAPHICS,
-                           pipeline->pipeline);
-
-      const VkViewport viewport = {
-         .x = rect->rect.offset.x,
-         .y = rect->rect.offset.y,
-         .width = rect->rect.extent.width,
-         .height = rect->rect.extent.height,
-         .minDepth = 0.0f,
-         .maxDepth = 1.0f
-      };
-      v3dv_CmdSetViewport(cmd_buffer_handle, 0, 1, &viewport);
-      v3dv_CmdSetScissor(cmd_buffer_handle, 0, 1, &rect->rect);
-
-      v3dv_CmdDraw(cmd_buffer_handle, 4, 1, 0, 0);
-
-      v3dv_CmdEndRenderPass(cmd_buffer_handle);
-   }
-
-   /* The clear pipeline sets viewport and scissor state, so we need
-    * to restore it
-    */
-   dirty_dynamic_state = V3DV_CMD_DIRTY_VIEWPORT | V3DV_CMD_DIRTY_SCISSOR;
-
-fail:
-   v3dv_cmd_buffer_meta_state_pop(cmd_buffer, dirty_dynamic_state, true);
-}
-
-static void
-emit_ds_clear_rect(struct v3dv_cmd_buffer *cmd_buffer,
-                   VkImageAspectFlags aspects,
-                   uint32_t attachment_idx,
-                   VkClearDepthStencilValue clear_ds,
-                   const VkClearRect *rect)
-{
-   assert(cmd_buffer->state.pass);
-   assert(attachment_idx != VK_ATTACHMENT_UNUSED);
-   assert(attachment_idx < cmd_buffer->state.pass->attachment_count);
-
-   VkFormat format =
-      cmd_buffer->state.pass->attachments[attachment_idx].desc.format;
-   assert ((aspects & ~vk_format_aspects(format)) == 0);
-
-   uint32_t samples =
-      cmd_buffer->state.pass->attachments[attachment_idx].desc.samples;
-
-   enum pipe_format pformat = vk_format_to_pipe_format(format);
-   VkClearColorValue clear_color;
-   uint32_t clear_zs =
-      util_pack_z_stencil(pformat, clear_ds.depth, clear_ds.stencil);
-
-   /* We implement depth/stencil clears by turning them into color clears
-    * with a compatible color format.
-    */
-   VkFormat color_format = get_color_format_for_depth_stencil_format(format);
-
-   uint32_t comps;
-   if (color_format == VK_FORMAT_R8G8B8A8_UINT) {
-    /* We are clearing a D24 format so we need to select the channels that we
-     * are being asked to clear to avoid clearing aspects that should be
-     * preserved. Also, the hardware uses the MSB channels to store the D24
-     * component, so we need to shift the components in the clear value to
-     * match that.
-     */
-      comps = 0;
-      if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
-         comps |= VK_COLOR_COMPONENT_R_BIT;
-         clear_color.uint32[0] = clear_zs >> 24;
-      }
-      if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
-         comps |= VK_COLOR_COMPONENT_G_BIT |
-                  VK_COLOR_COMPONENT_B_BIT |
-                  VK_COLOR_COMPONENT_A_BIT;
-         clear_color.uint32[1] = (clear_zs >>  0) & 0xff;
-         clear_color.uint32[2] = (clear_zs >>  8) & 0xff;
-         clear_color.uint32[3] = (clear_zs >> 16) & 0xff;
-      }
-   } else {
-      /* For anything else we use a single component format */
-      comps = VK_COLOR_COMPONENT_R_BIT;
-      clear_color.uint32[0] = clear_zs;
-   }
-
-   emit_color_clear_rect(cmd_buffer, attachment_idx,
-                         color_format, samples, comps,
-                         clear_color, rect);
-}
-
 /* Emits a scissored quad in the clear color */
 static void
 emit_subpass_color_clear_rects(struct v3dv_cmd_buffer *cmd_buffer,
@@ -1274,44 +1019,6 @@ emit_subpass_ds_clear_rects(struct v3dv_cmd_buffer *cmd_buffer,
    v3dv_cmd_buffer_meta_state_pop(cmd_buffer, dynamic_states, false);
 }
 
-static bool
-is_subrect(const VkRect2D *r0, const VkRect2D *r1)
-{
-   return r0->offset.x <= r1->offset.x &&
-          r0->offset.y <= r1->offset.y &&
-          r0->offset.x + r0->extent.width >= r1->offset.x + r1->extent.width &&
-          r0->offset.y + r0->extent.height >= r1->offset.y + r1->extent.height;
-}
-
-static bool
-can_use_tlb_clear(struct v3dv_cmd_buffer *cmd_buffer,
-                  uint32_t rect_count,
-                  const VkClearRect* rects)
-{
-   const struct v3dv_framebuffer *framebuffer = cmd_buffer->state.framebuffer;
-
-   const VkRect2D *render_area = &cmd_buffer->state.render_area;
-
-   /* Check if we are clearing a single region covering the entire framebuffer
-    * and that we are not constrained by the current render area.
-    *
-    * From the Vulkan 1.0 spec:
-    *
-    *   "The vkCmdClearAttachments command is not affected by the bound
-    *    pipeline state."
-    *
-    * So we can ignore scissor and viewport state for this check.
-    */
-   const VkRect2D fb_rect = {
-      { 0, 0 },
-      { framebuffer->width, framebuffer->height }
-   };
-
-   return rect_count == 1 &&
-          is_subrect(&rects[0].rect, &fb_rect) &&
-          is_subrect(render_area, &fb_rect);
-}
-
 static void
 handle_deferred_clear_attachments(struct v3dv_cmd_buffer *cmd_buffer,
                                   uint32_t attachmentCount,
@@ -1438,65 +1145,4 @@ v3dv_CmdClearAttachments(VkCommandBuffer commandBuffer,
                                      rectCount, pRects);
       }
    }
-   return;
-
-   perf_debug("Falling back to slow path for vkCmdClearAttachments due to "
-              "clearing layers other than the base array layer.\n");
-
-   /* If we can't handle this as a draw call inside the current job then we
-    * will have to spawn jobs for the clears, which will be slow. In that case,
-    * try to use the TLB to clear if possible.
-    */
-   if (can_use_tlb_clear(cmd_buffer, rectCount, pRects)) {
-      v3dv_X(cmd_buffer->device, cmd_buffer_emit_tlb_clear)
-         (cmd_buffer, attachmentCount, pAttachments,
-          pRects[0].baseArrayLayer, pRects[0].layerCount);
-      return;
-   }
-
-   /* Otherwise, fall back to drawing rects with the clear value using a
-    * separate job. This is the slowest path.
-    */
-   for (uint32_t i = 0; i < attachmentCount; i++) {
-      uint32_t attachment_idx = VK_ATTACHMENT_UNUSED;
-
-      if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
-         uint32_t rt_idx = pAttachments[i].colorAttachment;
-         attachment_idx = subpass->color_attachments[rt_idx].attachment;
-      } else if (pAttachments[i].aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
-                                               VK_IMAGE_ASPECT_STENCIL_BIT)) {
-         attachment_idx = subpass->ds_attachment.attachment;
-      }
-
-      if (attachment_idx == VK_ATTACHMENT_UNUSED)
-         continue;
-
-      if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
-         const uint32_t components = VK_COLOR_COMPONENT_R_BIT |
-                                     VK_COLOR_COMPONENT_G_BIT |
-                                     VK_COLOR_COMPONENT_B_BIT |
-                                     VK_COLOR_COMPONENT_A_BIT;
-         const uint32_t samples =
-            cmd_buffer->state.pass->attachments[attachment_idx].desc.samples;
-         const VkFormat format =
-            cmd_buffer->state.pass->attachments[attachment_idx].desc.format;
-         for (uint32_t j = 0; j < rectCount; j++) {
-            emit_color_clear_rect(cmd_buffer,
-                                  attachment_idx,
-                                  format,
-                                  samples,
-                                  components,
-                                  pAttachments[i].clearValue.color,
-                                  &pRects[j]);
-         }
-      } else {
-         for (uint32_t j = 0; j < rectCount; j++) {
-            emit_ds_clear_rect(cmd_buffer,
-                               pAttachments[i].aspectMask,
-                               attachment_idx,
-                               pAttachments[i].clearValue.depthStencil,
-                               &pRects[j]);
-         }
-      }
-   }
 }



More information about the mesa-commit mailing list