radv: add support for depth/stencil resolves with vkCmdResolve2()

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38043>
This commit is contained in:
Samuel Pitoiset 2025-09-11 15:33:37 +02:00 committed by Marge Bot
parent 8306256e2a
commit d3924f5bd6

View file

@ -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);