From 604d3ed7d2c4aa8b021f7e9a1503ad4452bcd8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Briano?= Date: Mon, 9 Feb 2026 14:55:50 -0800 Subject: [PATCH] anv, hasvk: handle MSAA resolving to a 3D slice The destination for CmdResolve can be a 3D image, and while some restrictions on the base layer and count exist, the Z offset into which the resolve will happen has no such restriction. Fixes some new tests: dEQP-VK.pipeline.*.multisample.m10_resolve.resolve_cmd.*.full_3d.* Fixes: 0e7761b35cd ("anv, hasvk: allow using a 3D image as a resolve target") Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/vulkan/anv_blorp.c | 17 ++++++++++------- src/intel/vulkan_hasvk/anv_blorp.c | 16 +++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 503fa79f44c..66078cbe7c6 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -2174,7 +2174,7 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *dst_image, enum isl_format dst_format_override, enum isl_aux_usage dst_aux_usage, - uint32_t dst_level, uint32_t dst_base_layer, + uint32_t dst_level, uint32_t dst_base_layer_or_z, VkImageAspectFlagBits aspect, uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, @@ -2188,9 +2188,6 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, assert(src_image->vk.image_type == VK_IMAGE_TYPE_2D); assert(src_image->vk.samples > 1); - assert((dst_image->vk.image_type == VK_IMAGE_TYPE_2D) || - (dst_image->vk.image_type == VK_IMAGE_TYPE_3D && - dst_base_layer == 0 && layer_count == 1)); assert(dst_image->vk.samples == 1); struct blorp_surf src_surf, dst_surf; @@ -2206,7 +2203,7 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, false, &dst_surf); anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image, aspect, dst_aux_usage, - dst_level, dst_base_layer, layer_count); + dst_level, dst_base_layer_or_z, layer_count); if (filter == BLORP_FILTER_NONE) { /* If no explicit filter is provided, then it's implied by the type of @@ -2225,7 +2222,7 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, blorp_blit(&batch, &src_surf, src_level, src_base_layer + l, src_format_override, ISL_SWIZZLE_IDENTITY, - &dst_surf, dst_level, dst_base_layer + l, + &dst_surf, dst_level, dst_base_layer_or_z + l, dst_format_override, ISL_SWIZZLE_IDENTITY, src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height, @@ -2444,6 +2441,11 @@ resolve_image(struct anv_cmd_buffer *cmd_buffer, const uint32_t layer_count = vk_image_subresource_layer_count(&dst_image->vk, ®ion->dstSubresource); + + assert((dst_image->vk.image_type == VK_IMAGE_TYPE_2D) || + (dst_image->vk.image_type == VK_IMAGE_TYPE_3D && + region->dstSubresource.baseArrayLayer == 0 && layer_count == 1)); + const bool skip_srgb_decode = res_info ? (res_info->flags & VK_RESOLVE_IMAGE_SKIP_TRANSFER_FUNCTION_BIT_KHR) : @@ -2486,7 +2488,8 @@ resolve_image(struct anv_cmd_buffer *cmd_buffer, region->srcSubresource.baseArrayLayer, dst_image, dst_format, dst_aux_usage, region->dstSubresource.mipLevel, - region->dstSubresource.baseArrayLayer, + MAX2(region->dstSubresource.baseArrayLayer, + region->dstOffset.z), aspect, region->srcOffset.x, region->srcOffset.y, diff --git a/src/intel/vulkan_hasvk/anv_blorp.c b/src/intel/vulkan_hasvk/anv_blorp.c index 4d2c5a6f941..13ab2f65e8e 100644 --- a/src/intel/vulkan_hasvk/anv_blorp.c +++ b/src/intel/vulkan_hasvk/anv_blorp.c @@ -1300,7 +1300,7 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *dst_image, enum isl_format dst_format_override, enum isl_aux_usage dst_aux_usage, - uint32_t dst_level, uint32_t dst_base_layer, + uint32_t dst_level, uint32_t dst_base_layer_or_z, VkImageAspectFlagBits aspect, uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, @@ -1314,9 +1314,6 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, assert(src_image->vk.image_type == VK_IMAGE_TYPE_2D); assert(src_image->vk.samples > 1); - assert((dst_image->vk.image_type == VK_IMAGE_TYPE_2D) || - (dst_image->vk.image_type == VK_IMAGE_TYPE_3D && - dst_base_layer == 0 && layer_count == 1)); assert(dst_image->vk.samples == 1); struct blorp_surf src_surf, dst_surf; @@ -1335,7 +1332,7 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, dst_aux_usage, &dst_surf); anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image, aspect, dst_aux_usage, - dst_level, dst_base_layer, layer_count); + dst_level, dst_base_layer_or_z, layer_count); if (filter == BLORP_FILTER_NONE) { /* If no explicit filter is provided, then it's implied by the type of @@ -1354,7 +1351,7 @@ anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer, blorp_blit(&batch, &src_surf, src_level, src_base_layer + l, src_format_override, ISL_SWIZZLE_IDENTITY, - &dst_surf, dst_level, dst_base_layer + l, + &dst_surf, dst_level, dst_base_layer_or_z + l, dst_format_override, ISL_SWIZZLE_IDENTITY, src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height, @@ -1467,6 +1464,10 @@ resolve_image(struct anv_cmd_buffer *cmd_buffer, const uint32_t layer_count = vk_image_subresource_layer_count(&dst_image->vk, ®ion->dstSubresource); + assert((dst_image->vk.image_type == VK_IMAGE_TYPE_2D) || + (dst_image->vk.image_type == VK_IMAGE_TYPE_3D && + region->dstSubresource.baseArrayLayer == 0 && layer_count == 1)); + anv_foreach_image_aspect_bit(aspect_bit, src_image, region->srcSubresource.aspectMask) { enum isl_aux_usage src_aux_usage = @@ -1486,7 +1487,8 @@ resolve_image(struct anv_cmd_buffer *cmd_buffer, region->srcSubresource.baseArrayLayer, dst_image, ISL_FORMAT_UNSUPPORTED, dst_aux_usage, region->dstSubresource.mipLevel, - region->dstSubresource.baseArrayLayer, + MAX2(region->dstSubresource.baseArrayLayer, + region->dstOffset.z), (1 << aspect_bit), region->srcOffset.x, region->srcOffset.y,