diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 8eeea1dba58..fe05f13813f 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -1485,21 +1485,20 @@ can_fast_clear_color_att(struct anv_cmd_buffer *cmd_buffer, return false; } - /* We only support fast-clears on the first layer */ - if (pRects[0].layerCount > 1 || pRects[0].baseArrayLayer > 0) + /* We only support fast-clearing a single layer */ + if (pRects[0].layerCount > 1) return false; bool is_multiview = cmd_buffer->state.gfx.view_mask != 0; if (is_multiview && (cmd_buffer->state.gfx.view_mask != 1)) return false; - return anv_can_fast_clear_color_view(cmd_buffer->device, - (struct anv_image_view *)att->iview, - att->layout, - clear_color, - pRects->layerCount, - pRects->rect, - cmd_buffer->queue_family->queueFlags); + return anv_can_fast_clear_color_view(cmd_buffer, att->iview->image, + att->iview->vk.base_mip_level, + pRects, att->layout, + att->iview->planes[0].isl.format, + att->iview->planes[0].isl.swizzle, + clear_color); } static void diff --git a/src/intel/vulkan/anv_image_view.c b/src/intel/vulkan/anv_image_view.c index dc3eabf871e..6a4c3ef61c3 100644 --- a/src/intel/vulkan/anv_image_view.c +++ b/src/intel/vulkan/anv_image_view.c @@ -247,9 +247,10 @@ anv_can_hiz_clear_ds_view(struct anv_device *device, static bool isl_color_value_requires_conversion(union isl_color_value color, const struct isl_surf *surf, - const struct isl_view *view) + enum isl_format view_format, + struct isl_swizzle view_swizzle) { - if (surf->format == view->format && isl_swizzle_is_identity(view->swizzle)) + if (surf->format == view_format && isl_swizzle_is_identity(view_swizzle)) return false; uint32_t surf_pack[4] = { 0, 0, 0, 0 }; @@ -257,42 +258,38 @@ isl_color_value_requires_conversion(union isl_color_value color, uint32_t view_pack[4] = { 0, 0, 0, 0 }; union isl_color_value swiz_color = - isl_color_value_swizzle_inv(color, view->swizzle); - isl_color_value_pack(&swiz_color, view->format, view_pack); + isl_color_value_swizzle_inv(color, view_swizzle); + isl_color_value_pack(&swiz_color, view_format, view_pack); return memcmp(surf_pack, view_pack, sizeof(surf_pack)) != 0; } bool -anv_can_fast_clear_color_view(struct anv_device *device, - struct anv_image_view *iview, +anv_can_fast_clear_color_view(const struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + unsigned level, + const struct VkClearRect *clear_rect, VkImageLayout layout, - union isl_color_value clear_color, - uint32_t num_layers, - VkRect2D render_area, - const VkQueueFlagBits queue_flags) + enum isl_format view_format, + struct isl_swizzle view_swizzle, + union isl_color_value clear_color) { if (INTEL_DEBUG(DEBUG_NO_FAST_CLEAR)) return false; - if (iview->planes[0].isl.base_array_layer >= - anv_image_aux_layers(iview->image, VK_IMAGE_ASPECT_COLOR_BIT, - iview->planes[0].isl.base_level)) - return false; - /* Start by getting the fast clear type. We use the first subpass * layout here because we don't want to fast-clear if the first subpass * to use the attachment can't handle fast-clears. */ enum anv_fast_clear_type fast_clear_type = - anv_layout_to_fast_clear_type(device->info, iview->image, - VK_IMAGE_ASPECT_COLOR_BIT, - layout, queue_flags); + anv_layout_to_fast_clear_type(cmd_buffer->device->info, image, + VK_IMAGE_ASPECT_COLOR_BIT, layout, + cmd_buffer->queue_family->queueFlags); switch (fast_clear_type) { case ANV_FAST_CLEAR_NONE: return false; case ANV_FAST_CLEAR_DEFAULT_VALUE: - if (!isl_color_value_is_zero(clear_color, iview->planes[0].isl.format)) + if (!isl_color_value_is_zero(clear_color, view_format)) return false; break; case ANV_FAST_CLEAR_ANY: @@ -303,10 +300,10 @@ anv_can_fast_clear_color_view(struct anv_device *device, * alignment restrictions. It's easier to just restrict to full size * fast clears for now. */ - if (render_area.offset.x != 0 || - render_area.offset.y != 0 || - render_area.extent.width != iview->vk.extent.width || - render_area.extent.height != iview->vk.extent.height) + if (clear_rect->rect.offset.x != 0 || + clear_rect->rect.offset.y != 0 || + clear_rect->rect.extent.width != image->vk.extent.width || + clear_rect->rect.extent.height != image->vk.extent.height) return false; /* If the clear color is one that would require non-trivial format @@ -315,9 +312,9 @@ anv_can_fast_clear_color_view(struct anv_device *device, * format re-interpretation is for sRGB. */ if (isl_color_value_requires_conversion(clear_color, - &iview->image->planes[0].primary_surface.isl, - &iview->planes[0].isl)) { - anv_perf_warn(VK_LOG_OBJS(&iview->vk.base), + &image->planes[0].primary_surface.isl, + view_format, view_swizzle)) { + anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "Cannot fast-clear to colors which would require " "format conversion on resolve"); return false; @@ -330,25 +327,26 @@ anv_can_fast_clear_color_view(struct anv_device *device, * were no known applications which would benefit from fast-clearing * more than just the first slice. */ - if (iview->planes[0].isl.base_level > 0 || - iview->planes[0].isl.base_array_layer > 0) { - anv_perf_warn(VK_LOG_OBJS(&iview->image->vk.base), - "Rendering with multi-lod or multi-layer framebuffer " - "with LOAD_OP_LOAD and baseMipLevel > 0 or " + if (level > 0) { + anv_perf_warn(VK_LOG_OBJS(&image->vk.base), + "level > 0. Not fast clearing."); + return false; + } + + if (clear_rect->baseArrayLayer > 0) { + anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "baseArrayLayer > 0. Not fast clearing."); return false; } - if (num_layers > 1) { - anv_perf_warn(VK_LOG_OBJS(&iview->image->vk.base), - "Rendering to a multi-layer framebuffer with " - "LOAD_OP_CLEAR. Only fast-clearing the first slice"); + if (clear_rect->layerCount > 1) { + anv_perf_warn(VK_LOG_OBJS(&image->vk.base), + "layerCount > 1. Only fast-clearing the first slice"); } /* Wa_18020603990 - slow clear surfaces up to 256x256, 32bpp. */ - if (intel_needs_workaround(device->info, 18020603990)) { - const struct anv_surface *anv_surf = - &iview->image->planes->primary_surface; + if (intel_needs_workaround(cmd_buffer->device->info, 18020603990)) { + const struct anv_surface *anv_surf = &image->planes->primary_surface; if (isl_format_get_layout(anv_surf->isl.format)->bpb <= 32 && anv_surf->isl.logical_level0_px.w <= 256 && anv_surf->isl.logical_level0_px.h <= 256) @@ -358,10 +356,10 @@ anv_can_fast_clear_color_view(struct anv_device *device, /* On gfx12.0, CCS fast clears don't seem to cover the correct portion of * the aux buffer when the pitch is not 512B-aligned. */ - if (device->info->verx10 == 120 && - iview->image->planes->primary_surface.isl.samples == 1 && - iview->image->planes->primary_surface.isl.row_pitch_B % 512) { - anv_perf_warn(VK_LOG_OBJS(&iview->image->vk.base), + if (cmd_buffer->device->info->verx10 == 120 && + image->planes->primary_surface.isl.samples == 1 && + image->planes->primary_surface.isl.row_pitch_B % 512) { + anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "Pitch not 512B-aligned. Slow clearing surface."); return false; } @@ -376,15 +374,14 @@ anv_can_fast_clear_color_view(struct anv_device *device, * address, raw & converted such that all fixed functions can find the * value they need. */ - if (device->info->ver == 9 && - isl_format_is_srgb(iview->planes[0].isl.format) && - !isl_color_value_is_zero_one(clear_color, - iview->planes[0].isl.format)) + if (cmd_buffer->device->info->ver == 9 && + isl_format_is_srgb(view_format) && + !isl_color_value_is_zero_one(clear_color, view_format)) return false; /* Wa_16021232440: Disable fast clear when height is 16k */ - if (intel_needs_workaround(device->info, 16021232440) && - iview->vk.extent.height == 16 * 1024) { + if (intel_needs_workaround(cmd_buffer->device->info, 16021232440) && + image->vk.extent.height == 16 * 1024) { return false; } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 011684ac2bf..73d8c1c746f 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -5780,13 +5780,14 @@ anv_can_hiz_clear_ds_view(struct anv_device *device, const VkQueueFlagBits queue_flags); bool -anv_can_fast_clear_color_view(struct anv_device *device, - struct anv_image_view *iview, +anv_can_fast_clear_color_view(const struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + unsigned level, + const struct VkClearRect *clear_rect, VkImageLayout layout, - union isl_color_value clear_color, - uint32_t num_layers, - VkRect2D render_area, - const VkQueueFlagBits queue_flags); + enum isl_format view_format, + struct isl_swizzle view_swizzle, + union isl_color_value clear_color); enum isl_aux_state ATTRIBUTE_PURE anv_layout_to_aux_state(const struct intel_device_info * const devinfo, diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 8b15626c9db..0c3732ee778 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -5215,6 +5215,12 @@ void genX(CmdBeginRendering)( if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR && !(gfx->rendering_flags & VK_RENDERING_RESUMING_BIT)) { + uint32_t clear_view_mask = pRenderingInfo->viewMask; + VkClearRect clear_rect = { + .rect = render_area, + .baseArrayLayer = iview->vk.base_array_layer, + .layerCount = layers, + }; const union isl_color_value clear_color = vk_to_isl_color_with_format(att->clearValue.color, iview->planes[0].isl.format); @@ -5222,10 +5228,12 @@ void genX(CmdBeginRendering)( /* We only support fast-clears on the first layer */ const bool fast_clear = (!is_multiview || (gfx->view_mask & 1)) && - anv_can_fast_clear_color_view(cmd_buffer->device, iview, - att->imageLayout, clear_color, - layers, render_area, - cmd_buffer->queue_family->queueFlags); + anv_can_fast_clear_color_view(cmd_buffer, iview->image, + iview->vk.base_mip_level, + &clear_rect, att->imageLayout, + iview->planes[0].isl.format, + iview->planes[0].isl.swizzle, + clear_color); if (att->imageLayout != initial_layout) { assert(render_area.offset.x == 0 && render_area.offset.y == 0 && @@ -5256,9 +5264,6 @@ void genX(CmdBeginRendering)( } } - uint32_t clear_view_mask = pRenderingInfo->viewMask; - uint32_t base_clear_layer = iview->vk.base_array_layer; - uint32_t clear_layer_count = gfx->layer_count; if (fast_clear) { /* We only support fast-clears on the first layer */ assert(iview->vk.base_mip_level == 0 && @@ -5284,8 +5289,8 @@ void genX(CmdBeginRendering)( false); } clear_view_mask &= ~1u; - base_clear_layer++; - clear_layer_count--; + clear_rect.baseArrayLayer++; + clear_rect.layerCount--; #if GFX_VER < 20 genX(set_fast_clear_state)(cmd_buffer, iview->image, iview->planes[0].isl.format, @@ -5311,7 +5316,8 @@ void genX(CmdBeginRendering)( iview->planes[0].isl.format, iview->planes[0].isl.swizzle, iview->vk.base_mip_level, - base_clear_layer, clear_layer_count, + clear_rect.baseArrayLayer, + clear_rect.layerCount, render_area, clear_color); } } else {