From 51faab487f77e153a9ac05b1e7bca978decc2250 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 7 Oct 2016 14:43:21 -0700 Subject: [PATCH] anv: Use blorp for ClearAttachments Signed-off-by: Jason Ekstrand Reviewed-by: Topi Pohjolainen --- src/intel/vulkan/anv_blorp.c | 113 ++++++++++++++++++++++++++++++ src/intel/vulkan/anv_meta_clear.c | 24 ------- 2 files changed, 113 insertions(+), 24 deletions(-) diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 60ed98e3d5d..8577e5f39b2 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -868,6 +868,119 @@ void anv_CmdClearDepthStencilImage( blorp_batch_finish(&batch); } +static void +clear_color_attachment(struct anv_cmd_buffer *cmd_buffer, + struct blorp_batch *batch, + const VkClearAttachment *attachment, + uint32_t rectCount, const VkClearRect *pRects) +{ + const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; + const struct anv_subpass *subpass = cmd_buffer->state.subpass; + const uint32_t att = attachment->colorAttachment; + const struct anv_image_view *iview = + fb->attachments[subpass->color_attachments[att]]; + const struct anv_image *image = iview->image; + + struct blorp_surf surf; + get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT, &surf); + + union isl_color_value clear_color; + memcpy(clear_color.u32, attachment->clearValue.color.uint32, + sizeof(clear_color.u32)); + + static const bool color_write_disable[4] = { false, false, false, false }; + + for (uint32_t r = 0; r < rectCount; ++r) { + const VkOffset2D offset = pRects[r].rect.offset; + const VkExtent2D extent = pRects[r].rect.extent; + blorp_clear(batch, &surf, iview->isl.format, iview->isl.swizzle, + iview->isl.base_level, + iview->isl.base_array_layer + pRects[r].baseArrayLayer, + pRects[r].layerCount, + offset.x, offset.y, + offset.x + extent.width, offset.y + extent.height, + clear_color, color_write_disable); + } +} + +static void +clear_depth_stencil_attachment(struct anv_cmd_buffer *cmd_buffer, + struct blorp_batch *batch, + const VkClearAttachment *attachment, + uint32_t rectCount, const VkClearRect *pRects) +{ + const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; + const struct anv_subpass *subpass = cmd_buffer->state.subpass; + const struct anv_image_view *iview = + fb->attachments[subpass->depth_stencil_attachment]; + const struct anv_image *image = iview->image; + + bool clear_depth = attachment->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT; + bool clear_stencil = attachment->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT; + + struct blorp_surf depth, stencil; + if (clear_depth) { + get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_DEPTH_BIT, + &depth); + } else { + memset(&depth, 0, sizeof(depth)); + } + + if (clear_stencil) { + get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_STENCIL_BIT, + &stencil); + } else { + memset(&stencil, 0, sizeof(stencil)); + } + + for (uint32_t r = 0; r < rectCount; ++r) { + const VkOffset2D offset = pRects[r].rect.offset; + const VkExtent2D extent = pRects[r].rect.extent; + VkClearDepthStencilValue value = attachment->clearValue.depthStencil; + blorp_clear_depth_stencil(batch, &depth, &stencil, + iview->isl.base_level, + iview->isl.base_array_layer + + pRects[r].baseArrayLayer, + pRects[r].layerCount, + offset.x, offset.y, + offset.x + extent.width, + offset.y + extent.height, + clear_depth, value.depth, + clear_stencil ? 0xff : 0, value.stencil); + } +} + +void anv_CmdClearAttachments( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment* pAttachments, + uint32_t rectCount, + const VkClearRect* pRects) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + + /* Because this gets called within a render pass, we tell blorp not to + * trash our depth and stencil buffers. + */ + struct blorp_batch batch; + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, + BLORP_BATCH_NO_EMIT_DEPTH_STENCIL); + + for (uint32_t a = 0; a < attachmentCount; ++a) { + if (pAttachments[a].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { + clear_color_attachment(cmd_buffer, &batch, + &pAttachments[a], + rectCount, pRects); + } else { + clear_depth_stencil_attachment(cmd_buffer, &batch, + &pAttachments[a], + rectCount, pRects); + } + } + + blorp_batch_finish(&batch); +} + static void resolve_image(struct blorp_batch *batch, const struct anv_image *src_image, diff --git a/src/intel/vulkan/anv_meta_clear.c b/src/intel/vulkan/anv_meta_clear.c index ce7f8a71129..6802229a9ac 100644 --- a/src/intel/vulkan/anv_meta_clear.c +++ b/src/intel/vulkan/anv_meta_clear.c @@ -751,27 +751,3 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer) meta_clear_end(&saved_state, cmd_buffer); } - -void anv_CmdClearAttachments( - VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment* pAttachments, - uint32_t rectCount, - const VkClearRect* pRects) -{ - ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - struct anv_meta_saved_state saved_state; - - meta_clear_begin(&saved_state, cmd_buffer); - - /* FINISHME: We can do better than this dumb loop. It thrashes too much - * state. - */ - for (uint32_t a = 0; a < attachmentCount; ++a) { - for (uint32_t r = 0; r < rectCount; ++r) { - emit_clear(cmd_buffer, &pAttachments[a], &pRects[r]); - } - } - - meta_clear_end(&saved_state, cmd_buffer); -} -- 2.30.2