Skip to content

Commit

Permalink
vkd3d: enable ds<->color copies using maintenance8
Browse files Browse the repository at this point in the history
this avoids renderpass copies for allowed formats, though
only DIRECT/GRAPHICS queue is supported by maintenance8

Signed-off-by: Mike Blumenkrantz <[email protected]>
  • Loading branch information
zmike committed Jan 27, 2025
1 parent 5aa23ec commit 2ece52a
Showing 1 changed file with 89 additions and 4 deletions.
93 changes: 89 additions & 4 deletions libs/vkd3d/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -7720,10 +7720,90 @@ struct d3d12_image_copy_barrier
bool dst_is_depth_stencil;
};

static bool d3d12_command_list_check_ds_color_copy_compatibility_24_32bit(const struct vkd3d_format *color_format)
{
switch (color_format->vk_format) {
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32_UINT:
return true;
default:
return false;
}
}

static bool d3d12_command_list_check_ds_color_copy_compatibility_16bit(const struct vkd3d_format *color_format)
{
switch (color_format->vk_format) {
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R16_SINT:
return true;
default:
return false;
}
}

static bool d3d12_command_list_check_ds_color_copy_compatibility_8bit(const struct vkd3d_format *color_format)
{
switch (color_format->vk_format) {
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_SNORM:
return true;
default:
return false;
}
}

/* maintenance8 enables copies between:
• 32-bit depth (VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT)
◦ VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SINT, VK_FORMAT_R32_UINT
• 24-bit depth (VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D24_UNORM_S8_UINT)
◦ VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SINT, VK_FORMAT_R32_UINT
• 16-bit depth (VK_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM_S8_UINT)
◦ VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_SNORM, VK_FORMAT_R16_UINT, VK_FORMAT_R16_SINT
• 8-bit stencil (VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT)
◦ VK_FORMAT_R8_UINT, VK_FORMAT_R8_SINT, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_SNORM
*/
static bool d3d12_command_list_check_ds_color_copy_compatibility(const struct vkd3d_format *dst_format, const struct vkd3d_format *src_format)
{
VkImageAspectFlags ds_bits = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
const struct vkd3d_format *ds_format = dst_format->vk_aspect_mask & ds_bits ? dst_format : src_format;
const struct vkd3d_format *color_format = ds_format == dst_format ? src_format : dst_format;

/* ensure formats detected as expected */
if ((ds_format->vk_aspect_mask & ds_bits) == 0 ||
(color_format->vk_aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) == 0)
return false;

/* try the stencil copy case first: always 8bit */
if (ds_format->vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT &&
color_format->byte_count == 1)
return d3d12_command_list_check_ds_color_copy_compatibility_8bit(color_format);

switch (ds_format->vk_format)
{
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D24_UNORM_S8_UINT:
return d3d12_command_list_check_ds_color_copy_compatibility_24_32bit(color_format);
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_D16_UNORM_S8_UINT:
return d3d12_command_list_check_ds_color_copy_compatibility_16bit(color_format);
default:
return false;
}
}

static void d3d12_command_list_copy_image_barrier_flags(struct d3d12_image_copy_barrier *barrier,
const struct d3d12_resource *dst_resource, const struct vkd3d_format *dst_format,
const struct d3d12_resource *src_resource, const struct vkd3d_format *src_format,
const VkImageCopy2 *region, bool overlapping_subresource)
const VkImageCopy2 *region, bool overlapping_subresource, bool allow_ds_color_copies)
{
/* Individual aspects of planar images are treated as-if they were using a view-compatible
* format, so we can copy between planes and color images as long as the formats are of the
Expand All @@ -7732,7 +7812,8 @@ static void d3d12_command_list_copy_image_barrier_flags(struct d3d12_image_copy_
VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT;

barrier->use_copy = dst_format->vk_aspect_mask == src_format->vk_aspect_mask ||
((dst_format->vk_aspect_mask & compatible_aspects) && (src_format->vk_aspect_mask & compatible_aspects));
((dst_format->vk_aspect_mask & compatible_aspects) && (src_format->vk_aspect_mask & compatible_aspects)) ||
(allow_ds_color_copies && d3d12_command_list_check_ds_color_copy_compatibility(dst_format, src_format));
barrier->dst_is_depth_stencil = !!(dst_format->vk_aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));

if (barrier->use_copy)
Expand Down Expand Up @@ -7801,7 +7882,9 @@ static void d3d12_command_list_copy_image_transition_images(struct d3d12_command
d3d12_command_list_copy_image_barrier_flags(&barrier,
dst_resource, dst_format,
src_resource, src_format,
region, overlapping_subresource);
region, overlapping_subresource,
/* TODO: maintenance8 only allows GRAPHICS queue DS<->COLOR, but future extensions may allow on other queues */
list->type == D3D12_COMMAND_LIST_TYPE_DIRECT && list->device->device_info.maintenance_8_features.maintenance8);

dst_copy_pass_access = barrier.dst.access;
if (overlapping_subresource)
Expand Down Expand Up @@ -7847,7 +7930,9 @@ static void d3d12_command_list_copy_image(struct d3d12_command_list *list,
d3d12_command_list_copy_image_barrier_flags(&barrier,
dst_resource, dst_format,
src_resource, src_format,
region, overlapping_subresource);
region, overlapping_subresource,
/* TODO: maintenance8 only allows GRAPHICS queue DS<->COLOR, but future extensions may allow on other queues */
list->type == D3D12_COMMAND_LIST_TYPE_DIRECT && list->device->device_info.maintenance_8_features.maintenance8);

VKD3D_BREADCRUMB_TAG("Image -> Image");
VKD3D_BREADCRUMB_RESOURCE(src_resource);
Expand Down

0 comments on commit 2ece52a

Please sign in to comment.