From b30437d23945a1ae6281360197bc5a68af071942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Mon, 18 Mar 2019 10:03:05 +0100 Subject: [PATCH] tests: Add test for copying misaligned texture regions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- tests/d3d12.c | 56 ------------- tests/d3d12_invalid_usage.c | 151 +++++++++++++++++++++++++++++++++--- tests/d3d12_test_utils.h | 56 +++++++++++++ 3 files changed, 195 insertions(+), 68 deletions(-) diff --git a/tests/d3d12.c b/tests/d3d12.c index 89cc4dd7..89858ae0 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -173,14 +173,6 @@ static void uav_barrier(ID3D12GraphicsCommandList *list, ID3D12Resource *resourc ID3D12GraphicsCommandList_ResourceBarrier(list, 1, &barrier); } -#define create_default_buffer(a, b, c, d) create_default_buffer_(__LINE__, a, b, c, d) -static ID3D12Resource *create_default_buffer_(unsigned int line, ID3D12Device *device, - size_t size, D3D12_RESOURCE_FLAGS resource_flags, D3D12_RESOURCE_STATES initial_resource_state) -{ - return create_buffer_(line, device, D3D12_HEAP_TYPE_DEFAULT, size, - resource_flags, initial_resource_state); -} - static void copy_sub_resource_data(const D3D12_MEMCPY_DEST *dst, const D3D12_SUBRESOURCE_DATA *src, unsigned int row_count, unsigned int slice_count, size_t row_size) { @@ -295,54 +287,6 @@ static void upload_texture_data_(unsigned int line, ID3D12Resource *texture, free(row_sizes); } -static unsigned int format_block_width(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 4; - default: - return 1; - } -} - -static unsigned int format_block_height(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 4; - default: - return 1; - } -} - static const DXGI_FORMAT depth_stencil_formats[] = { DXGI_FORMAT_R32G8X24_TYPELESS, diff --git a/tests/d3d12_invalid_usage.c b/tests/d3d12_invalid_usage.c index 940dea91..a76873bd 100644 --- a/tests/d3d12_invalid_usage.c +++ b/tests/d3d12_invalid_usage.c @@ -41,15 +41,15 @@ static void test_invalid_texture_resource_barriers(void) command_queue_desc.NodeMask = 0; hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc, &IID_ID3D12CommandQueue, (void **)&queue); - ok(SUCCEEDED(hr), "Failed to create command queue, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create command queue, hr %#x.\n", hr); hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&command_allocator); - ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr); hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); - ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); texture = create_default_texture(device, 32, 32, DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); @@ -60,7 +60,7 @@ static void test_invalid_texture_resource_barriers(void) transition_resource_state(command_list, texture, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); hr = ID3D12GraphicsCommandList_Close(command_list); - ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr); reset_command_list(command_list, command_allocator); @@ -80,10 +80,10 @@ static void test_invalid_texture_resource_barriers(void) ID3D12GraphicsCommandList_Release(command_list); hr = ID3D12CommandAllocator_Reset(command_allocator); - ok(SUCCEEDED(hr), "Failed to reset command allocator, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); - ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); /* The before state does not match with the previous state. */ transition_resource_state(command_list, texture, @@ -101,11 +101,11 @@ static void test_invalid_texture_resource_barriers(void) } hr = ID3D12CommandAllocator_Reset(command_allocator); - ok(SUCCEEDED(hr), "Failed to reset command allocator, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); ID3D12GraphicsCommandList_Release(command_list); hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); - ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); /* Exactly one write state or a combination of read-only states are allowed. */ transition_resource_state(command_list, texture, @@ -115,11 +115,11 @@ static void test_invalid_texture_resource_barriers(void) ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); hr = ID3D12CommandAllocator_Reset(command_allocator); - ok(SUCCEEDED(hr), "Failed to reset command allocator, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); ID3D12GraphicsCommandList_Release(command_list); hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); - ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); /* Readback resources cannot transition from D3D12_RESOURCE_STATE_COPY_DEST. */ transition_resource_state(command_list, readback_buffer, @@ -128,11 +128,11 @@ static void test_invalid_texture_resource_barriers(void) todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); hr = ID3D12CommandAllocator_Reset(command_allocator); - ok(SUCCEEDED(hr), "Failed to reset command allocator, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); ID3D12GraphicsCommandList_Release(command_list); hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); - ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); /* Upload resources cannot transition from D3D12_RESOURCE_STATE_GENERIC_READ. */ transition_resource_state(command_list, upload_buffer, @@ -150,6 +150,132 @@ static void test_invalid_texture_resource_barriers(void) ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); } +static void test_invalid_copy_texture_region(void) +{ + ID3D12Resource *dst_texture, *src_texture, *dst_buffer, *src_buffer; + D3D12_TEXTURE_COPY_LOCATION src_location, dst_location; + ID3D12CommandAllocator *command_allocator; + ID3D12GraphicsCommandList *command_list; + ID3D12Device *device; + ULONG refcount; + D3D12_BOX box; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device.\n"); + return; + } + + hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, + &IID_ID3D12CommandAllocator, (void **)&command_allocator); + ok(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr); + + hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, + command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + + src_buffer = create_upload_buffer(device, 0x40000, NULL); + dst_buffer = create_default_buffer(device, 0x40000, 0, D3D12_RESOURCE_STATE_COPY_DEST); + + src_texture = create_default_texture(device, 64, 64, + DXGI_FORMAT_BC3_UNORM, 0, D3D12_RESOURCE_STATE_COPY_SOURCE); + dst_texture = create_default_texture(device, 64, 64, + DXGI_FORMAT_BC3_UNORM, 0, D3D12_RESOURCE_STATE_COPY_DEST); + + dst_location.pResource = dst_texture; + dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst_location.SubresourceIndex = 0; + + src_location.pResource = src_buffer; + src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + src_location.PlacedFootprint.Offset = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; + src_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_BC3_UNORM; + src_location.PlacedFootprint.Footprint.Width = 64; + src_location.PlacedFootprint.Footprint.Height = 63; /* height must be multiple of block size */ + src_location.PlacedFootprint.Footprint.Depth = 1; + src_location.PlacedFootprint.Footprint.RowPitch + = 64 / format_block_width(DXGI_FORMAT_BC3_UNORM) * format_size(DXGI_FORMAT_BC3_UNORM); + + ID3D12GraphicsCommandList_CopyTextureRegion(command_list, + &dst_location, 0, 0, 0, &src_location, NULL); + + hr = ID3D12GraphicsCommandList_Close(command_list); + todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + hr = ID3D12CommandAllocator_Reset(command_allocator); + ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); + ID3D12GraphicsCommandList_Release(command_list); + hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, + command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + + src_location.PlacedFootprint.Footprint.Width = 4; + src_location.PlacedFootprint.Footprint.Height = 4; + + /* dst y must be multiple of block size */ + ID3D12GraphicsCommandList_CopyTextureRegion(command_list, + &dst_location, 0, 3, 0, &src_location, NULL); + + hr = ID3D12GraphicsCommandList_Close(command_list); + todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + hr = ID3D12CommandAllocator_Reset(command_allocator); + ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); + ID3D12GraphicsCommandList_Release(command_list); + hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, + command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + + /* row pitch must be multiple of D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT */ + src_location.PlacedFootprint.Footprint.RowPitch + = 64 / format_block_width(DXGI_FORMAT_BC3_UNORM) * format_size(DXGI_FORMAT_BC3_UNORM) + 1; + + ID3D12GraphicsCommandList_CopyTextureRegion(command_list, + &dst_location, 0, 0, 0, &src_location, NULL); + + hr = ID3D12GraphicsCommandList_Close(command_list); + todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + hr = ID3D12CommandAllocator_Reset(command_allocator); + ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); + ID3D12GraphicsCommandList_Release(command_list); + hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, + command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list); + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + + dst_location.pResource = dst_buffer; + dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dst_location.PlacedFootprint.Offset = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; + dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_BC3_UNORM; + dst_location.PlacedFootprint.Footprint.Width = 64; + dst_location.PlacedFootprint.Footprint.Height = 64; + dst_location.PlacedFootprint.Footprint.Depth = 1; + dst_location.PlacedFootprint.Footprint.RowPitch + = 64 / format_block_width(DXGI_FORMAT_BC3_UNORM) * format_size(DXGI_FORMAT_BC3_UNORM); + + src_location.pResource = src_texture; + src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + src_location.SubresourceIndex = 0; + + /* coordinates must be multiple of block size */ + set_box(&box, 0, 0, 0, 31, 31, 1); + ID3D12GraphicsCommandList_CopyTextureRegion(command_list, + &dst_location, 0, 0, 0, &src_location, &box); + + hr = ID3D12GraphicsCommandList_Close(command_list); + todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + ID3D12CommandAllocator_Release(command_allocator); + ID3D12GraphicsCommandList_Release(command_list); + ID3D12Resource_Release(dst_buffer); + ID3D12Resource_Release(src_buffer); + ID3D12Resource_Release(dst_texture); + ID3D12Resource_Release(src_texture); + refcount = ID3D12Device_Release(device); + ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); +} + START_TEST(d3d12_invalid_usage) { parse_args(argc, argv); @@ -157,4 +283,5 @@ START_TEST(d3d12_invalid_usage) init_adapter_info(); run_test(test_invalid_texture_resource_barriers); + run_test(test_invalid_copy_texture_region); } diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index a771c166..14c6d04e 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -268,6 +268,54 @@ static unsigned int format_size(DXGI_FORMAT format) } } +static inline unsigned int format_block_width(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 4; + default: + return 1; + } +} + +static inline unsigned int format_block_height(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 4; + default: + return 1; + } +} + struct resource_readback { unsigned int width; @@ -431,6 +479,14 @@ static inline void check_sub_resource_uint_(unsigned int line, ID3D12Resource *t release_resource_readback(&rb); } +#define create_default_buffer(a, b, c, d) create_default_buffer_(__LINE__, a, b, c, d) +static inline ID3D12Resource *create_default_buffer_(unsigned int line, ID3D12Device *device, + size_t size, D3D12_RESOURCE_FLAGS resource_flags, D3D12_RESOURCE_STATES initial_resource_state) +{ + return create_buffer_(line, device, D3D12_HEAP_TYPE_DEFAULT, size, + resource_flags, initial_resource_state); +} + static ID3D12Resource *create_default_texture_(unsigned int line, ID3D12Device *device, D3D12_RESOURCE_DIMENSION dimension, unsigned int width, unsigned int height, unsigned int depth_or_array_size, unsigned int miplevel_count, DXGI_FORMAT format,