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 <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2021-09-01 18:35:53 +02:00
parent 3d5010555e
commit 7b67de7d0e
3 changed files with 43 additions and 27 deletions

View File

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

View File

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

View File

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