diff --git a/src/amd/vulkan/meta/radv_meta_resolve.c b/src/amd/vulkan/meta/radv_meta_resolve.c index d53ea3573e2..4bb3a393da4 100644 --- a/src/amd/vulkan/meta/radv_meta_resolve.c +++ b/src/amd/vulkan/meta/radv_meta_resolve.c @@ -379,27 +379,65 @@ radv_meta_resolve_hardware_image(struct radv_cmd_buffer *cmd_buffer, struct radv static void resolve_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, VkImageLayout src_image_layout, struct radv_image *dst_image, VkImageLayout dst_image_layout, const VkImageResolve2 *region, - enum radv_resolve_method resolve_method) + const VkResolveImageModeInfoKHR *resolve_mode_info, enum radv_resolve_method resolve_method) { - switch (resolve_method) { - case RESOLVE_HW: - radv_meta_resolve_hardware_image(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, - dst_image->vk.format, dst_image_layout, region); - break; - case RESOLVE_FRAGMENT: - radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); + if (vk_format_is_depth_or_stencil(src_image->vk.format)) { + if ((region->srcSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && + resolve_mode_info->resolveMode != VK_RESOLVE_MODE_NONE) { + VkImageResolve2 depth_region = *region; + depth_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + depth_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - radv_meta_resolve_fragment_image(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, - dst_image->vk.format, dst_image_layout, region); - break; - case RESOLVE_COMPUTE: - radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); + if (resolve_method == RESOLVE_FRAGMENT) { + radv_meta_resolve_depth_stencil_fs(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, + dst_image->vk.format, dst_image_layout, resolve_mode_info->resolveMode, + &depth_region, 0); + } else { + assert(resolve_method == RESOLVE_COMPUTE); + radv_meta_resolve_depth_stencil_cs(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, + dst_image->vk.format, dst_image_layout, resolve_mode_info->resolveMode, + &depth_region); + } + } - radv_meta_resolve_compute_image(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, - dst_image->vk.format, dst_image_layout, region); - break; - default: - assert(!"Invalid resolve method selected"); + if ((region->srcSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && + resolve_mode_info->stencilResolveMode != VK_RESOLVE_MODE_NONE) { + VkImageResolve2 stencil_region = *region; + stencil_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + stencil_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + + if (resolve_method == RESOLVE_FRAGMENT) { + radv_meta_resolve_depth_stencil_fs(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, + dst_image->vk.format, dst_image_layout, + resolve_mode_info->stencilResolveMode, &stencil_region, 0); + } else { + assert(resolve_method == RESOLVE_COMPUTE); + radv_meta_resolve_depth_stencil_cs(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, + dst_image->vk.format, dst_image_layout, + resolve_mode_info->stencilResolveMode, &stencil_region); + } + } + } else { + switch (resolve_method) { + case RESOLVE_HW: + radv_meta_resolve_hardware_image(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, + dst_image->vk.format, dst_image_layout, region); + break; + case RESOLVE_FRAGMENT: + radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); + + radv_meta_resolve_fragment_image(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, + dst_image->vk.format, dst_image_layout, region); + break; + case RESOLVE_COMPUTE: + radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); + + radv_meta_resolve_compute_image(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, + dst_image->vk.format, dst_image_layout, region); + break; + default: + assert(!"Invalid resolve method selected"); + } } } @@ -415,6 +453,9 @@ radv_CmdResolveImage2(VkCommandBuffer commandBuffer, const VkResolveImageInfo2 * VkImageLayout dst_image_layout = pResolveImageInfo->dstImageLayout; enum radv_resolve_method resolve_method = pdev->info.gfx_level >= GFX11 ? RESOLVE_FRAGMENT : RESOLVE_HW; + const VkResolveImageModeInfoKHR *resolve_mode_info = + vk_find_struct_const(pResolveImageInfo->pNext, RESOLVE_IMAGE_MODE_INFO_KHR); + radv_suspend_conditional_rendering(cmd_buffer); /* we can use the hw resolve only for single full resolves */ @@ -439,7 +480,8 @@ radv_CmdResolveImage2(VkCommandBuffer commandBuffer, const VkResolveImageInfo2 * radv_pick_resolve_method_images(device, src_image, src_image->vk.format, dst_image, region->dstSubresource.mipLevel, dst_image_layout, cmd_buffer, &resolve_method); - resolve_image(cmd_buffer, src_image, src_image_layout, dst_image, dst_image_layout, region, resolve_method); + resolve_image(cmd_buffer, src_image, src_image_layout, dst_image, dst_image_layout, region, resolve_mode_info, + resolve_method); } radv_resume_conditional_rendering(cmd_buffer);