tests: Add test for planar footprints.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2021-09-01 17:04:05 +02:00
parent bc9bd9c482
commit 6f8ebaae7e
3 changed files with 110 additions and 5 deletions

View File

@ -1240,30 +1240,40 @@ static void check_copyable_footprints_(unsigned int line, const D3D12_RESOURCE_D
const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, const UINT *row_counts,
const uint64_t *row_sizes, uint64_t *total_size)
{
unsigned int miplevel, width, height, depth, row_count, row_size, row_pitch;
unsigned int miplevel, width, height, depth, row_count, row_size, row_pitch, layers, plane, num_planes;
uint64_t offset, size, total;
unsigned int i;
layers = desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? 1 : desc->DepthOrArraySize;
num_planes = format_num_planes(desc->Format);
offset = total = 0;
for (i = 0; i < sub_resource_count; ++i)
{
miplevel = (sub_resource_idx + i) % desc->MipLevels;
plane = (sub_resource_idx + i) / (desc->MipLevels * layers);
width = align(max(1, desc->Width >> miplevel), format_block_width(desc->Format));
height = align(max(1, desc->Height >> miplevel), format_block_height(desc->Format));
depth = desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? desc->DepthOrArraySize : 1;
depth = max(1, depth >> miplevel);
row_count = height / format_block_height(desc->Format);
row_size = (width / format_block_width(desc->Format)) * format_size(desc->Format);
row_pitch = align(row_size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
row_size = (width / format_block_width(desc->Format)) * format_size_planar(desc->Format, plane);
/* For whatever reason, depth-stencil images actually have 512 byte row alignment, not 256.
* Both WARP and NV driver have this behavior, so it might be an undocumented requirement.
* This function is likely part of the core runtime though ... */
row_pitch = align(row_size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT * num_planes);
if (layouts)
{
const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *l = &layouts[i];
const D3D12_SUBRESOURCE_FOOTPRINT *f = &l->Footprint;
DXGI_FORMAT footprint_format;
footprint_format = format_to_footprint_format(desc->Format, plane);
ok_(line)(l->Offset == base_offset + offset,
"Got offset %"PRIu64", expected %"PRIu64".\n", l->Offset, base_offset + offset);
ok_(line)(f->Format == desc->Format, "Got format %#x, expected %#x.\n", f->Format, desc->Format);
ok_(line)(f->Format == footprint_format, "Got format %#x, expected %#x.\n", f->Format, footprint_format);
ok_(line)(f->Width == width, "Got width %u, expected %u.\n", f->Width, width);
ok_(line)(f->Height == height, "Got height %u, expected %u.\n", f->Height, height);
ok_(line)(f->Depth == depth, "Got depth %u, expected %u.\n", f->Depth, depth);
@ -1277,7 +1287,7 @@ static void check_copyable_footprints_(unsigned int line, const D3D12_RESOURCE_D
ok_(line)(row_sizes[i] == row_size, "Got row size %"PRIu64", expected %u.\n", row_sizes[i], row_size);
size = max(0, row_count - 1) * row_pitch + row_size;
size = max(0, depth - 1) * align(size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) + size;
size = max(0, depth - 1) * align(size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT * num_planes) + size;
total = offset + size;
offset = align(total, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
@ -1287,6 +1297,55 @@ static void check_copyable_footprints_(unsigned int line, const D3D12_RESOURCE_D
ok_(line)(*total_size == total, "Got total size %"PRIu64", expected %"PRIu64".\n", *total_size, total);
}
void test_get_copyable_footprints_planar(void)
{
D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprints[2 * 2 * 3];
UINT64 row_sizes[ARRAY_SIZE(footprints)];
UINT row_counts[ARRAY_SIZE(footprints)];
D3D12_RESOURCE_DESC desc;
ID3D12Device *device;
UINT64 total_bytes;
unsigned int i;
/* All of these formats will have R32_TYPELESS + R8_TYPELESS placements. */
static const DXGI_FORMAT planar_formats[] =
{
DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
DXGI_FORMAT_D24_UNORM_S8_UINT,
DXGI_FORMAT_R24G8_TYPELESS,
DXGI_FORMAT_R32G8X24_TYPELESS,
};
if (!(device = create_device()))
{
skip("Failed to create device.\n");
return;
}
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.Width = 130;
desc.Height = 119;
desc.DepthOrArraySize = 2;
desc.MipLevels = 3;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
desc.Alignment = 0;
for (i = 0; i < ARRAY_SIZE(planar_formats); i++)
{
vkd3d_test_set_context("Test %u", i);
desc.Format = planar_formats[i];
ID3D12Device_GetCopyableFootprints(device, &desc, 0, ARRAY_SIZE(footprints), 0,
footprints, row_counts, row_sizes, &total_bytes);
check_copyable_footprints(&desc, 0, ARRAY_SIZE(footprints), 0, footprints, row_counts, row_sizes, &total_bytes);
}
vkd3d_test_set_context(NULL);
ID3D12Device_Release(device);
}
void test_get_copyable_footprints(void)
{
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[10];

View File

@ -354,6 +354,51 @@ static inline unsigned int format_size(DXGI_FORMAT format)
}
}
static inline unsigned int format_num_planes(DXGI_FORMAT format)
{
switch (format)
{
case DXGI_FORMAT_D24_UNORM_S8_UINT:
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R24G8_TYPELESS:
case DXGI_FORMAT_R32G8X24_TYPELESS:
return 2;
default:
return 1;
}
}
static inline unsigned int format_size_planar(DXGI_FORMAT format, unsigned int plane)
{
switch (format)
{
case DXGI_FORMAT_D24_UNORM_S8_UINT:
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R24G8_TYPELESS:
case DXGI_FORMAT_R32G8X24_TYPELESS:
return plane ? 1 : 4;
default:
return format_size(format);
}
}
static inline unsigned int format_to_footprint_format(DXGI_FORMAT format, unsigned int plane)
{
switch (format)
{
case DXGI_FORMAT_D24_UNORM_S8_UINT:
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R24G8_TYPELESS:
case DXGI_FORMAT_R32G8X24_TYPELESS:
return plane ? DXGI_FORMAT_R8_TYPELESS : DXGI_FORMAT_R32_TYPELESS;
default:
return format;
}
}
static inline unsigned int format_block_width(DXGI_FORMAT format)
{
switch (format)

View File

@ -270,3 +270,4 @@ decl_test(test_shader_fp16);
decl_test(test_shader_sm62_denorm);
decl_test(test_shader_sm64_packed);
decl_test(test_shader_sm65_wave_intrinsics);
decl_test(test_get_copyable_footprints_planar);