From 7b67de7d0eb960abc85adca0c33f73cfb45e346e Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Wed, 1 Sep 2021 18:35:53 +0200 Subject: [PATCH] vkd3d: Generalize get_plane_footprints. Get information directly from vkd3d_format and allow for subsampled formats in the future. Signed-off-by: Hans-Kristian Arntzen --- libs/vkd3d/device.c | 14 ++++++------- libs/vkd3d/utils.c | 42 ++++++++++++++++++++++---------------- libs/vkd3d/vkd3d_private.h | 14 +++++++++++-- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 27d68be2..2bdd08b2 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -3851,7 +3851,7 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(d3d12_device_if unsigned int i, sub_resource_idx, miplevel_idx, row_count, row_size, row_pitch; unsigned int width, height, depth, num_planes, num_subresources; unsigned int num_subresources_per_plane, plane_idx; - const struct vkd3d_format *plane_format; + struct vkd3d_format_footprint plane_footprint; const struct vkd3d_format *format; uint64_t offset, size, total; @@ -3903,14 +3903,14 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(d3d12_device_if sub_resource_idx = first_sub_resource + i; plane_idx = sub_resource_idx / num_subresources_per_plane; - plane_format = vkd3d_format_footprint_for_plane(device, format, plane_idx); + plane_footprint = vkd3d_format_footprint_for_plane(format, plane_idx); miplevel_idx = sub_resource_idx % desc->MipLevels; - width = align(d3d12_resource_desc_get_width(desc, miplevel_idx), plane_format->block_width); - height = align(d3d12_resource_desc_get_height(desc, miplevel_idx), plane_format->block_height); + width = align(d3d12_resource_desc_get_width(desc, miplevel_idx), plane_footprint.block_width); + height = align(d3d12_resource_desc_get_height(desc, miplevel_idx), plane_footprint.block_height); depth = d3d12_resource_desc_get_depth(desc, miplevel_idx); - row_count = height / plane_format->block_height; - row_size = (width / plane_format->block_width) * plane_format->byte_count * plane_format->block_byte_count; + row_count = height / plane_footprint.block_height; + row_size = (width / plane_footprint.block_width) * plane_footprint.block_byte_count; /* For whatever reason, we need to use 512 bytes of alignment for depth-stencil formats. * This is not documented, but it is observed behavior on both NV and WARP drivers. @@ -3920,7 +3920,7 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(d3d12_device_if if (layouts) { layouts[i].Offset = base_offset + offset; - layouts[i].Footprint.Format = plane_format->dxgi_format; + layouts[i].Footprint.Format = plane_footprint.dxgi_format; layouts[i].Footprint.Width = width; layouts[i].Footprint.Height = height; layouts[i].Footprint.Depth = depth; diff --git a/libs/vkd3d/utils.c b/libs/vkd3d/utils.c index ed4f0c12..413ba6c6 100644 --- a/libs/vkd3d/utils.c +++ b/libs/vkd3d/utils.c @@ -123,17 +123,23 @@ static const struct vkd3d_format vkd3d_formats[] = {DXGI_FORMAT_B4G4R4A4_UNORM, VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,2, 1, 1, 1, COLOR, 1}, }; +static const struct vkd3d_format_footprint depth_stencil_copy_footprints[] = +{ + { DXGI_FORMAT_R32_TYPELESS, 1, 1, 4, 0, 0 }, + { DXGI_FORMAT_R8_TYPELESS, 1, 1, 1, 0, 0 }, +}; + /* Each depth/stencil format is only compatible with itself in Vulkan. */ static const struct vkd3d_format vkd3d_depth_stencil_formats[] = { - {DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS}, - {DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2}, + {DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS, false, depth_stencil_copy_footprints}, + {DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2, 0, false, depth_stencil_copy_footprints}, {DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH, 2}, {DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, STENCIL, 2}, {DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, DEPTH, 1, TYPELESS}, {DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, DEPTH, 1}, - {DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS}, - {DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2}, + {DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS, false, depth_stencil_copy_footprints}, + {DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2, 0, false, depth_stencil_copy_footprints}, {DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH, 2}, {DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, STENCIL, 2}, {DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM, 2, 1, 1, 1, DEPTH, 1, TYPELESS}, @@ -483,22 +489,22 @@ const struct vkd3d_format *vkd3d_get_format(const struct d3d12_device *device, return format->dxgi_format ? format : NULL; } -const struct vkd3d_format *vkd3d_format_footprint_for_plane(const struct d3d12_device *device, - const struct vkd3d_format *format, unsigned int plane_idx) +struct vkd3d_format_footprint vkd3d_format_footprint_for_plane(const struct vkd3d_format *format, unsigned int plane_idx) { - switch (format->dxgi_format) + if (format->plane_footprints) { - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - if (plane_idx == 0) - return vkd3d_get_format(device, DXGI_FORMAT_R32_TYPELESS, false); - else - return vkd3d_get_format(device, DXGI_FORMAT_R8_TYPELESS, false); - - default: - return format; + return format->plane_footprints[plane_idx]; + } + else + { + struct vkd3d_format_footprint footprint; + footprint.dxgi_format = format->dxgi_format; + footprint.block_width = format->block_width; + footprint.block_height = format->block_height; + footprint.subsample_x_log2 = 0; + footprint.subsample_y_log2 = 0; + footprint.block_byte_count = format->byte_count * format->block_byte_count; + return footprint; } } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 4526281b..431f913a 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -2840,6 +2840,16 @@ enum vkd3d_format_type VKD3D_FORMAT_TYPE_UINT, }; +struct vkd3d_format_footprint +{ + DXGI_FORMAT dxgi_format; + uint32_t block_width; + uint32_t block_height; + uint32_t block_byte_count; + uint32_t subsample_x_log2; + uint32_t subsample_y_log2; +}; + struct vkd3d_format { DXGI_FORMAT dxgi_format; @@ -2852,6 +2862,7 @@ struct vkd3d_format unsigned int plane_count; enum vkd3d_format_type type; bool is_emulated; + const struct vkd3d_format_footprint *plane_footprints; }; static inline size_t vkd3d_format_get_data_offset(const struct vkd3d_format *format, @@ -2878,8 +2889,7 @@ DXGI_FORMAT vkd3d_get_typeless_format(const struct d3d12_device *device, DXGI_FO const struct vkd3d_format *vkd3d_find_uint_format(const struct d3d12_device *device, DXGI_FORMAT dxgi_format); VkFormat vkd3d_internal_get_vk_format(const struct d3d12_device *device, DXGI_FORMAT dxgi_format); -const struct vkd3d_format *vkd3d_format_footprint_for_plane(const struct d3d12_device *device, - const struct vkd3d_format *format, unsigned int plane_idx); +struct vkd3d_format_footprint vkd3d_format_footprint_for_plane(const struct vkd3d_format *format, unsigned int plane_idx); HRESULT vkd3d_init_format_info(struct d3d12_device *device); void vkd3d_cleanup_format_info(struct d3d12_device *device);