From eca931a7263fac06dd73be6901b2e6571d9a5026 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 23 Nov 2018 17:04:12 +0100 Subject: [PATCH] radv: add radv_can_fast_clear_{color,depth}() helpers For further optimisations. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_meta_clear.c | 133 +++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 44 deletions(-) diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index 9c124c9b677..6c8ef4958f2 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -935,22 +935,13 @@ radv_image_view_can_fast_clear(struct radv_device *device, } static bool -emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, - const VkClearAttachment *clear_att, - const VkClearRect *clear_rect, - enum radv_cmd_flush_bits *pre_flush, - enum radv_cmd_flush_bits *post_flush) +radv_can_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer, + const struct radv_image_view *iview, + VkImageLayout image_layout, + VkImageAspectFlags aspects, + const VkClearRect *clear_rect, + const VkClearDepthStencilValue clear_value) { - const struct radv_subpass *subpass = cmd_buffer->state.subpass; - const uint32_t pass_att = subpass->depth_stencil_attachment.attachment; - VkImageLayout image_layout = subpass->depth_stencil_attachment.layout; - const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; - 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, flush_bits; - uint32_t htile_mask; - if (!radv_image_view_can_fast_clear(cmd_buffer->device, iview)) return false; @@ -979,6 +970,30 @@ emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, !radv_is_fast_clear_stencil_allowed(clear_value))) return false; + return true; +} + +static bool +emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, + const VkClearAttachment *clear_att, + const VkClearRect *clear_rect, + enum radv_cmd_flush_bits *pre_flush, + enum radv_cmd_flush_bits *post_flush) +{ + const struct radv_subpass *subpass = cmd_buffer->state.subpass; + const uint32_t pass_att = subpass->depth_stencil_attachment.attachment; + VkImageLayout image_layout = subpass->depth_stencil_attachment.layout; + const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; + 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, flush_bits; + uint32_t htile_mask; + + if (!radv_can_fast_clear_depth(cmd_buffer, iview, image_layout, aspects, + clear_rect, clear_value)) + return false; + clear_word = radv_get_htile_fast_clear_value(iview->image, clear_value); htile_mask = radv_get_htile_mask(iview->image, aspects); @@ -1367,23 +1382,14 @@ static void vi_get_fast_clear_parameters(VkFormat format, } static bool -emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, - const VkClearAttachment *clear_att, - const VkClearRect *clear_rect, - enum radv_cmd_flush_bits *pre_flush, - enum radv_cmd_flush_bits *post_flush, - uint32_t view_mask) +radv_can_fast_clear_color(struct radv_cmd_buffer *cmd_buffer, + const struct radv_image_view *iview, + VkImageLayout image_layout, + const VkClearRect *clear_rect, + VkClearColorValue clear_value, + uint32_t view_mask) { - const struct radv_subpass *subpass = cmd_buffer->state.subpass; - const uint32_t subpass_att = clear_att->colorAttachment; - const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; - VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout; - 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], flush_bits = 0; - uint32_t cmask_clear_value; - bool ret; + uint32_t clear_color[2]; if (!radv_image_view_can_fast_clear(cmd_buffer->device, iview)) return false; @@ -1405,9 +1411,55 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, return false; /* DCC */ - ret = radv_format_pack_clear_color(iview->vk_format, - clear_color, &clear_value); - if (ret == false) + if (!radv_format_pack_clear_color(iview->vk_format, + clear_color, &clear_value)) + return false; + + if (radv_image_has_dcc(iview->image)) { + bool can_avoid_fast_clear_elim; + uint32_t reset_value; + + vi_get_fast_clear_parameters(iview->vk_format, + &clear_value, &reset_value, + &can_avoid_fast_clear_elim); + + if (iview->image->info.samples > 1) { + /* DCC fast clear with MSAA should clear CMASK. */ + /* FIXME: This doesn't work for now. There is a + * hardware bug with fast clears and DCC for MSAA + * textures. AMDVLK has a workaround but it doesn't + * seem to work here. Note that we might emit useless + * CB flushes but that shouldn't matter. + */ + if (!can_avoid_fast_clear_elim) + return false; + } + } + + return true; +} + + +static bool +emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, + const VkClearAttachment *clear_att, + const VkClearRect *clear_rect, + enum radv_cmd_flush_bits *pre_flush, + enum radv_cmd_flush_bits *post_flush, + uint32_t view_mask) +{ + const struct radv_subpass *subpass = cmd_buffer->state.subpass; + const uint32_t subpass_att = clear_att->colorAttachment; + const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; + VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout; + 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], flush_bits = 0; + uint32_t cmask_clear_value; + + if (!radv_can_fast_clear_color(cmd_buffer, iview, image_layout, + clear_rect, clear_value, view_mask)) return false; if (pre_flush) { @@ -1416,6 +1468,9 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, *pre_flush |= cmd_buffer->state.flush_bits; } + /* DCC */ + radv_format_pack_clear_color(iview->vk_format, clear_color, &clear_value); + cmask_clear_value = radv_get_cmask_fast_clear_value(iview->image); /* clear cmask buffer */ @@ -1429,16 +1484,6 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, &can_avoid_fast_clear_elim); if (iview->image->info.samples > 1) { - /* DCC fast clear with MSAA should clear CMASK. */ - /* FIXME: This doesn't work for now. There is a - * hardware bug with fast clears and DCC for MSAA - * textures. AMDVLK has a workaround but it doesn't - * seem to work here. Note that we might emit useless - * CB flushes but that shouldn't matter. - */ - if (!can_avoid_fast_clear_elim) - return false; - assert(radv_image_has_cmask(iview->image)); flush_bits = radv_clear_cmask(cmd_buffer, iview->image, -- 2.30.2