tests: Move test implementations to appropriate files.

Avoids crippling 50+ ksloc files which are impossible to navigate
efficiently. IDEs tend to give up on files these large and editors start
to chug hard.

This commit is essentially pure cut 'n paste, which is why it's all in
one large commit. There is little to no reason to attempt to split this
up into multiple smaller commits.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2021-08-25 14:00:58 +02:00
parent c2473fb873
commit 5ef3d4bff9
28 changed files with 53745 additions and 53092 deletions

File diff suppressed because it is too large Load Diff

1878
tests/d3d12_bindless.c Normal file

File diff suppressed because it is too large Load Diff

922
tests/d3d12_clear.c Normal file
View File

@ -0,0 +1,922 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
void test_clear_depth_stencil_view(void)
{
static const float expected_values[] = {0.5f, 0.1f, 0.1f, 0.6, 1.0f, 0.5f};
ID3D12GraphicsCommandList *command_list;
D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc;
ID3D12Resource *tmp_float, *tmp_uint;
struct depth_stencil_resource ds;
unsigned int dsv_increment_size;
D3D12_CLEAR_VALUE clear_value;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
unsigned int i;
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
dsv_increment_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
trace("DSV descriptor handle increment size: %u.\n", dsv_increment_size);
ok(dsv_increment_size, "Got unexpected increment size %#x.\n", dsv_increment_size);
clear_value.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
clear_value.DepthStencil.Depth = 0.5f;
clear_value.DepthStencil.Stencil = 0x3;
init_depth_stencil(&ds, device, 32, 32, 1, 1, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 0, &clear_value);
/* Tests that separate layout clear works correctly. */
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 0.5f, 0x3, 0, NULL);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, 0.75f, 0x7, 0, NULL);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_STENCIL, 0.75f, 0x7, 0, NULL);
transition_resource_state(command_list, ds.texture,
D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
tmp_float = create_default_texture2d(context.device, 32, 32, 1, 1, DXGI_FORMAT_R32_FLOAT,
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
tmp_uint = create_default_texture2d(context.device, 32, 32, 1, 1, DXGI_FORMAT_R8_UINT,
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
{
D3D12_TEXTURE_COPY_LOCATION dst_location, src_location;
D3D12_BOX src_box;
dst_location.SubresourceIndex = 0;
dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src_location.pResource = ds.texture;
src_box.left = 0;
src_box.right = 32;
src_box.top = 0;
src_box.bottom = 32;
src_box.front = 0;
src_box.back = 1;
dst_location.pResource = tmp_float;
src_location.SubresourceIndex = 0;
ID3D12GraphicsCommandList_CopyTextureRegion(context.list, &dst_location, 0, 0, 0, &src_location, &src_box);
dst_location.pResource = tmp_uint;
src_location.SubresourceIndex = 1;
ID3D12GraphicsCommandList_CopyTextureRegion(context.list, &dst_location, 0, 0, 0, &src_location, &src_box);
}
transition_resource_state(command_list, tmp_float,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
transition_resource_state(command_list, tmp_uint,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_float(tmp_float, 0, queue, command_list, 0.75f, 1);
reset_command_list(command_list, context.allocator);
check_sub_resource_uint8(tmp_uint, 0, queue, command_list, 0x7, 0);
ID3D12Resource_Release(tmp_float);
ID3D12Resource_Release(tmp_uint);
destroy_depth_stencil(&ds);
reset_command_list(command_list, context.allocator);
clear_value.Format = DXGI_FORMAT_D32_FLOAT;
init_depth_stencil(&ds, device, 32, 32, 6, 1, DXGI_FORMAT_D32_FLOAT, 0, &clear_value);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, expected_values[0], 0, 0, NULL);
memset(&dsv_desc, 0, sizeof(dsv_desc));
dsv_desc.Format = DXGI_FORMAT_D32_FLOAT;
dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY;
dsv_desc.Texture2DArray.FirstArraySlice = 1;
dsv_desc.Texture2DArray.ArraySize = 2;
ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, expected_values[1], 0, 0, NULL);
dsv_desc.Texture2DArray.FirstArraySlice = 3;
dsv_desc.Texture2DArray.ArraySize = 1;
ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, expected_values[3], 0, 0, NULL);
dsv_desc.Texture2DArray.FirstArraySlice = 4;
ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, expected_values[4], 0, 0, NULL);
transition_resource_state(command_list, ds.texture,
D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
for (i = 0; i < ARRAY_SIZE(expected_values); ++i)
{
check_sub_resource_float(ds.texture, i, queue, command_list, expected_values[i], 1);
reset_command_list(command_list, context.allocator);
}
destroy_depth_stencil(&ds);
destroy_test_context(&context);
}
void test_clear_render_target_view(void)
{
static const unsigned int array_expected_colors[] = {0xff00ff00, 0xff0000ff, 0xffff0000};
static const struct vec4 array_colors[] =
{
{0.0f, 1.0f, 0.0f, 1.0f},
{1.0f, 0.0f, 0.0f, 1.0f},
{0.0f, 0.0f, 1.0f, 1.0f},
};
static const float negative_value[] = {1.0f, -1.0f, -0.5f, -2.0f};
static const float color[] = {0.1f, 0.5f, 0.3f, 0.75f};
static const float green[] = {0.0f, 1.0f, 0.0f, 1.0f};
ID3D12GraphicsCommandList *command_list;
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_RESOURCE_DESC resource_desc;
unsigned int rtv_increment_size;
ID3D12DescriptorHeap *rtv_heap;
D3D12_CLEAR_VALUE clear_value;
struct test_context_desc desc;
struct resource_readback rb;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Resource *resource;
ID3D12Device *device;
unsigned int i;
D3D12_BOX box;
HRESULT hr;
static const struct
{
const float *color;
DXGI_FORMAT format;
uint32_t result;
}
r8g8b8a8[] =
{
{color, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 0xbf95bc59},
{green, DXGI_FORMAT_R8G8B8A8_UNORM, 0xff00ff00},
{color, DXGI_FORMAT_R8G8B8A8_UNORM, 0xbf4c7f19},
{green, DXGI_FORMAT_R8G8B8A8_UINT, 0x01000100},
{color, DXGI_FORMAT_R8G8B8A8_UINT, 0x00000000},
{negative_value, DXGI_FORMAT_R8G8B8A8_UINT, 0x00000001},
{green, DXGI_FORMAT_R8G8B8A8_SINT, 0x01000100},
{color, DXGI_FORMAT_R8G8B8A8_SINT, 0x00000000},
{negative_value, DXGI_FORMAT_R8G8B8A8_SINT, 0xfe00ff01},
};
static const struct
{
const float *color;
DXGI_FORMAT format;
uint64_t result;
}
r16g16b16a16[] =
{
{green, DXGI_FORMAT_R16G16B16A16_UNORM, 0xffff0000ffff0000},
{green, DXGI_FORMAT_R16G16B16A16_UINT, 0x0001000000010000},
{color, DXGI_FORMAT_R16G16B16A16_UINT, 0x0000000000000000},
{negative_value, DXGI_FORMAT_R16G16B16A16_UINT, 0x0000000000000001},
{green, DXGI_FORMAT_R16G16B16A16_SINT, 0x0001000000010000},
{color, DXGI_FORMAT_R16G16B16A16_SINT, 0x0000000000000000},
{negative_value, DXGI_FORMAT_R16G16B16A16_SINT, 0xfffe0000ffff0001},
};
STATIC_ASSERT(ARRAY_SIZE(array_colors) == ARRAY_SIZE(array_expected_colors));
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
rtv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
rtv_increment_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
trace("RTV descriptor handle increment size: %u.\n", rtv_increment_size);
rtv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv_heap);
memset(&heap_properties, 0, sizeof(heap_properties));
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resource_desc.Alignment = 0;
resource_desc.Width = 32;
resource_desc.Height = 32;
resource_desc.DepthOrArraySize = 1;
resource_desc.MipLevels = 1;
resource_desc.Format = DXGI_FORMAT_R8G8B8A8_TYPELESS;
resource_desc.SampleDesc.Count = 1;
resource_desc.SampleDesc.Quality = 0;
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
clear_value.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
clear_value.Color[0] = 1.0f;
clear_value.Color[1] = 0.0f;
clear_value.Color[2] = 0.0f;
clear_value.Color[3] = 1.0f;
hr = ID3D12Device_CreateCommittedResource(device,
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
&IID_ID3D12Resource, (void **)&resource);
ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
memset(&rtv_desc, 0, sizeof(rtv_desc));
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
/* R8G8B8A8 */
for (i = 0; i < ARRAY_SIZE(r8g8b8a8); ++i)
{
vkd3d_test_set_context("Test %u", i);
rtv_desc.Format = r8g8b8a8[i].format;
ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, r8g8b8a8[i].color, 0, NULL);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(resource, 0, queue, command_list, r8g8b8a8[i].result, 2);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
vkd3d_test_set_context(NULL);
/* R16G16B16A16 */
hr = ID3D12GraphicsCommandList_Close(command_list);
ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
reset_command_list(command_list, context.allocator);
ID3D12Resource_Release(resource);
resource_desc.Format = DXGI_FORMAT_R16G16B16A16_TYPELESS;
hr = ID3D12Device_CreateCommittedResource(device,
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_RENDER_TARGET, NULL,
&IID_ID3D12Resource, (void **)&resource);
ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(r16g16b16a16); ++i)
{
vkd3d_test_set_context("Test %u", i);
rtv_desc.Format = r16g16b16a16[i].format;
ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, r16g16b16a16[i].color, 0, NULL);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint64(resource, 0, queue, command_list, r16g16b16a16[i].result, 0);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
vkd3d_test_set_context(NULL);
/* 2D array texture */
hr = ID3D12GraphicsCommandList_Close(command_list);
ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
reset_command_list(command_list, context.allocator);
ID3D12Resource_Release(resource);
resource_desc.Format = DXGI_FORMAT_R8G8B8A8_TYPELESS;
resource_desc.DepthOrArraySize = ARRAY_SIZE(array_colors);
hr = ID3D12Device_CreateCommittedResource(device,
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
&IID_ID3D12Resource, (void **)&resource);
ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(array_colors); ++i)
{
memset(&rtv_desc, 0, sizeof(rtv_desc));
rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
rtv_desc.Texture2DArray.FirstArraySlice = i;
rtv_desc.Texture2DArray.ArraySize = 1;
ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, &array_colors[i].x, 0, NULL);
}
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
for (i = 0; i < ARRAY_SIZE(array_expected_colors); ++i)
{
check_sub_resource_uint(resource, i, queue, command_list, array_expected_colors[i], 2);
reset_command_list(command_list, context.allocator);
}
/* 2D multisample array texture */
ID3D12Resource_Release(resource);
resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
resource_desc.SampleDesc.Count = 4;
hr = ID3D12Device_CreateCommittedResource(device,
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
&IID_ID3D12Resource, (void **)&resource);
ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(array_colors); ++i)
{
memset(&rtv_desc, 0, sizeof(rtv_desc));
rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY;
rtv_desc.Texture2DMSArray.FirstArraySlice = i;
rtv_desc.Texture2DMSArray.ArraySize = 1;
ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, &array_colors[i].x, 0, NULL);
}
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
for (i = 0; i < ARRAY_SIZE(array_expected_colors); ++i)
{
check_sub_resource_uint(resource, i, queue, command_list, array_expected_colors[i], 2);
reset_command_list(command_list, context.allocator);
}
/* 3D texture */
ID3D12Resource_Release(resource);
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
resource_desc.DepthOrArraySize = 32;
resource_desc.MipLevels = 1;
resource_desc.SampleDesc.Count = 1;
hr = ID3D12Device_CreateCommittedResource(device,
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
&IID_ID3D12Resource, (void **)&resource);
ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
ID3D12Device_CreateRenderTargetView(device, resource, NULL, rtv_handle);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, color, 0, NULL);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(resource, 0, queue, command_list, 0xbf4c7f19, 2);
memset(&rtv_desc, 0, sizeof(rtv_desc));
rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
rtv_desc.Texture3D.FirstWSlice = 2;
rtv_desc.Texture3D.WSize = 2;
ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, green, 0, NULL);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list);
set_box(&box, 0, 0, 0, 32, 32, 2);
check_readback_data_uint(&rb, &box, 0xbf4c7f19, 1);
set_box(&box, 0, 0, 2, 32, 32, 4);
check_readback_data_uint(&rb, &box, 0xff00ff00, 1);
set_box(&box, 0, 0, 4, 32, 32, 32);
check_readback_data_uint(&rb, &box, 0xbf4c7f19, 1);
release_resource_readback(&rb);
ID3D12Resource_Release(resource);
ID3D12DescriptorHeap_Release(rtv_heap);
destroy_test_context(&context);
}
void test_clear_unordered_access_view_buffer(void)
{
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
ID3D12DescriptorHeap *cpu_heap, *gpu_heap;
ID3D12GraphicsCommandList *command_list;
struct test_context_desc desc;
struct test_context context;
struct resource_readback rb;
ID3D12CommandQueue *queue;
D3D12_HEAP_DESC heap_desc;
ID3D12Resource *buffer;
ID3D12Device *device;
UINT clear_value[4];
unsigned int i, j;
ID3D12Heap *heap;
D3D12_BOX box;
HRESULT hr;
#define BUFFER_SIZE (1024 * 1024)
static const struct
{
DXGI_FORMAT format;
D3D12_BUFFER_UAV buffer_uav;
unsigned int values[4];
unsigned int expected;
bool is_float;
bool is_null_descriptor;
}
tests[] =
{
{DXGI_FORMAT_R32_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0, 0, 0, 0}, 0},
{DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0, 0, 0, 0}, 0},
{DXGI_FORMAT_R32_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{1, 0, 0, 0}, 0, false, true},
{DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{2, 0, 0, 0}, 2},
{DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{3, 0, 0, 0}, 3},
{DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{4, 2, 3, 4}, 4},
{DXGI_FORMAT_R32_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t) - 10, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{5, 0, 0, 0}, 5},
{DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{0, 0, 0, 0}, 0},
{DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{0, 0, 0, 0}, 0},
{DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{6, 0, 0, 0}, 6},
{DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{6, 0, 0, 0}, 0, false, true},
{DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{7, 0, 0, 0}, 7},
{DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{8, 0, 0, 0}, 8},
{DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{9, 1, 1, 1}, 9},
{DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{~0u, 0, 0, 0}, ~0u},
{DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t) - 10, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{10, 0, 0, 0}, 10},
{DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t) - 9, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
{11, 0, 0, 0}, 11},
{DXGI_FORMAT_R32_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0, 0, 0, 0}, 0},
{DXGI_FORMAT_R32_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x3f800000 /* 1.0f */, 0, 0, 0}, 0x3f800000 /* 1.0f */, true},
{DXGI_FORMAT_R16G16_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x1234, 0xabcd, 0, 0}, 0xabcd1234},
{DXGI_FORMAT_R16G16_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x10000, 0, 0, 0}, 0},
{DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x1234, 0xabcd, 0, 0}, 0xabcd1234},
{DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x3f000080 /* 0.50000762951f */, 0x3f800000 /* 1.0f */, 0, 0}, 0xffff8000, true},
{DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x40000000 /* 2.0f */, 0 /* 0.0f */, 0, 0}, 0x0000ffff, true},
{DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0xbf800000 /* -1.0f */, 0 /* 0.0f */, 0x3f000000 /* 1.0f */, 0x3f000000 /* 1.0f */}, 0, true},
{DXGI_FORMAT_R16G16_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x1234, 0xabcd, 0, 0}, 0xabcd1234},
{DXGI_FORMAT_R16G16_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0x3c003800, true},
{DXGI_FORMAT_R8G8B8A8_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x11, 0x22, 0x33, 0x44}, 0x44332211},
{DXGI_FORMAT_R8G8B8A8_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x100, 0, 0, 0}, 0},
{DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0, 0, 0, 0}, 0},
{DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x7ff, 0x7ff, 0x3ff, 0}, 0xffffffff},
{DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x7ff, 0, 0x3ff, 0}, 0xffc007ff},
{DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0x40000000 /* 2.0f */, 0}, 0x801e0380, true},
{DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x3f000000 /* 1.0f */, 0 /* 0.0f */, 0xbf800000 /* -1.0f */, 0x3f000000 /* 1.0f */},
0x00000380, true},
{DXGI_FORMAT_R10G10B10A2_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x1010, 0x1020, 0x1030, 0x41}, (0x30 << 20) | (0x20 << 10) | (0x10 << 0) | (0x1 << 30)},
{DXGI_FORMAT_R10G10B10A2_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x1010, 0x1020, 0x1030, 0x41}, (0x30u << 20) | (0x20u << 10) | (0x10u << 0) | (0x1u << 30)},
{DXGI_FORMAT_R10G10B10A2_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
{0x3f002008 /* 0.5004887585532747f */, 0x3f800000 /* 1.0f */, 0, 0x3f800000 /* 1.0f */},
(0x3ffu << 10) | (0x200u << 0) | (0x3u << 30), true},
};
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
cpu_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
gpu_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
heap_desc.SizeInBytes = 2 * BUFFER_SIZE;
memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
heap_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&heap);
ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
vkd3d_test_set_context("Test %u", i);
buffer = create_placed_buffer(device, heap, BUFFER_SIZE, BUFFER_SIZE,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
for (j = 0; j < ARRAY_SIZE(clear_value); ++j)
clear_value[j] = tests[i].expected || tests[i].is_null_descriptor ? 0 : ~0u;
memset(&uav_desc, 0, sizeof(uav_desc));
uav_desc.Format = DXGI_FORMAT_R32_UINT;
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uav_desc.Buffer.NumElements = BUFFER_SIZE / sizeof(uint32_t);
ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
get_cpu_descriptor_handle(&context, cpu_heap, 1));
ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
get_cpu_descriptor_handle(&context, gpu_heap, 1));
uav_desc.Format = tests[i].format;
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uav_desc.Buffer = tests[i].buffer_uav;
ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
get_cpu_descriptor_handle(&context, cpu_heap, 0));
ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
get_cpu_descriptor_handle(&context, gpu_heap, 0));
if (tests[i].is_null_descriptor)
{
/* Test that we can clear out any knowledge about the existing descriptor. */
ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &uav_desc,
get_cpu_descriptor_handle(&context, cpu_heap, 0));
ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &uav_desc,
get_cpu_descriptor_handle(&context, gpu_heap, 0));
}
ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
get_gpu_descriptor_handle(&context, gpu_heap, 1),
get_cpu_descriptor_handle(&context, cpu_heap, 1),
buffer, clear_value, 0, NULL);
uav_barrier(command_list, buffer);
if (tests[i].is_float)
ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(command_list,
get_gpu_descriptor_handle(&context, gpu_heap, 0),
get_cpu_descriptor_handle(&context, cpu_heap, 0),
buffer, (const float *)tests[i].values, 0, NULL);
else
ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
get_gpu_descriptor_handle(&context, gpu_heap, 0),
get_cpu_descriptor_handle(&context, cpu_heap, 0),
buffer, tests[i].values, 0, NULL);
set_box(&box, 0, 0, 0, 1, 1, 1);
transition_resource_state(command_list, buffer,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_TYPELESS, &rb, queue, command_list);
box.left = 0;
box.right = uav_desc.Buffer.FirstElement;
check_readback_data_uint(&rb, &box, clear_value[0], 0);
box.left = uav_desc.Buffer.FirstElement;
box.right = uav_desc.Buffer.FirstElement + uav_desc.Buffer.NumElements;
check_readback_data_uint(&rb, &box, tests[i].expected, tests[i].is_float ? 1 : 0);
box.left = uav_desc.Buffer.FirstElement + uav_desc.Buffer.NumElements;
box.right = BUFFER_SIZE / format_size(uav_desc.Format);
check_readback_data_uint(&rb, &box, clear_value[0], 0);
release_resource_readback(&rb);
reset_command_list(command_list, context.allocator);
ID3D12Resource_Release(buffer);
}
vkd3d_test_set_context(NULL);
ID3D12DescriptorHeap_Release(cpu_heap);
ID3D12DescriptorHeap_Release(gpu_heap);
ID3D12Heap_Release(heap);
destroy_test_context(&context);
#undef BUFFER_SIZE
}
void test_clear_unordered_access_view_image(void)
{
unsigned int expected_colour, actual_colour;
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
ID3D12DescriptorHeap *cpu_heap, *gpu_heap;
ID3D12GraphicsCommandList *command_list;
unsigned int i, j, d, p, z, layer;
D3D12_HEAP_PROPERTIES heap_properties;
unsigned int image_size, image_depth;
D3D12_RESOURCE_DESC resource_desc;
struct test_context_desc desc;
struct test_context context;
struct resource_readback rb;
ID3D12CommandQueue *queue;
bool is_inside, success;
ID3D12Resource *texture;
ID3D12Device *device;
UINT clear_value[4];
HRESULT hr;
int x, y;
#define IMAGE_SIZE 16u
static const struct
{
DXGI_FORMAT format;
unsigned int image_mips;
unsigned int image_layers;
unsigned int mip_level;
unsigned int first_layer;
unsigned int layer_count;
unsigned int rect_count;
RECT clear_rects[2];
unsigned int values[4];
unsigned int expected;
bool is_float;
bool is_null_descriptor;
}
tests[] =
{
/* Test clearing a specific mip level. */
{DXGI_FORMAT_R32_FLOAT, 2, 1, 0, 0, 1, 0, {{0}}, {1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_FLOAT, 2, 1, 0, 0, 1, 0, {{0}}, {1, 0, 0, 0}, 0, false, true},
{DXGI_FORMAT_R32_FLOAT, 2, 1, 1, 0, 1, 0, {{0}}, {1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_FLOAT, 2, 1, 0, 0, 1, 0, {{0}}, {0x3f000000, 0, 0, 0}, 0x3f000000, true},
{DXGI_FORMAT_R32_FLOAT, 2, 1, 1, 0, 1, 0, {{0}}, {0x3f000000, 0, 0, 0}, 0x3f000000, true},
{DXGI_FORMAT_R32_FLOAT, 2, 1, 1, 0, 1, 0, {{0}}, {0x3f000000, 0, 0, 0}, 0, true, true},
/* Test clearing specific array layers. */
{DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 0, IMAGE_SIZE, 0, {{0}}, {1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 3, 2, 0, {{0}}, {1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 0, IMAGE_SIZE, 0, {{0}},
{0x3f000000, 0, 0, 0}, 0x3f000000, true},
{DXGI_FORMAT_R32_FLOAT, 1, IMAGE_SIZE, 0, 3, 2, 0, {{0}},
{0x3f000000, 0, 0, 0}, 0x3f000000, true},
/* Test a single clear rect. */
{DXGI_FORMAT_R32_FLOAT, 1, 1, 0, 0, 1, 1, {{1, 2, IMAGE_SIZE - 4, IMAGE_SIZE - 2}},
{1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_FLOAT, 1, 1, 0, 0, 1, 1, {{1, 2, IMAGE_SIZE - 4, IMAGE_SIZE - 2}},
{0x3f000000, 0, 0, 0}, 0x3f000000, true},
/* Test multiple clear rects. */
{DXGI_FORMAT_R32_FLOAT, 1, 1, 0, 0, 1, 2, {{1, 2, 3, 4}, {5, 6, 7, 8}},
{1, 0, 0, 0}, 1},
{DXGI_FORMAT_R32_FLOAT, 1, 1, 0, 0, 1, 2, {{1, 2, 3, 4}, {5, 6, 7, 8}},
{0x3f000000, 0, 0, 0}, 0x3f000000, true},
/* Test uint clears with formats. */
{DXGI_FORMAT_R16G16_UINT, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x00020001},
{DXGI_FORMAT_R16G16_UINT, 1, 1, 0, 0, 1, 0, {{0}}, {0x12345, 0, 0, 0}, 0x00002345},
{DXGI_FORMAT_R16G16_UNORM, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x00020001},
{DXGI_FORMAT_R16G16_FLOAT, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x00020001},
{DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x04030201},
{DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, 0, {{0}}, {0x123, 0, 0, 0}, 0x00000023},
{DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x04030201},
{DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x00c01001},
/* Test float clears with formats. */
{DXGI_FORMAT_R16G16_UNORM, 1, 1, 0, 0, 1, 0, {{0}},
{0x3f000080 /* 0.5f + unorm16 epsilon */, 0x3f800000 /* 1.0f */, 0, 0}, 0xffff8000, true},
{DXGI_FORMAT_R16G16_FLOAT, 1, 1, 0, 0, 1, 0, {{0}},
{0x3f000080 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0x3c003800, true},
{DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 0, 0, 1, 0, {{0}},
{0x3f000080 /* 0.5f + epsilon */, 0x3f800000 /* 1.0f */, 0, 0}, 0x0000ff80, true},
{DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 0, 0, 1, 0, {{0}},
{0, 0, 0x3f000080 /* 0.5f + epsilon */, 0x3f800000 /* 1.0f */}, 0xff800000, true},
{DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, 0, {{0}},
{0x3f000000 /* 1.0f */, 0 /* 0.0f */, 0xbf800000 /* -1.0f */, 0x3f000000 /* 1.0f */},
0x00000380, true},
};
static const struct
{
D3D12_RESOURCE_DIMENSION resource_dim;
D3D12_UAV_DIMENSION view_dim;
bool is_layered;
}
uav_dimensions[] =
{
{D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_UAV_DIMENSION_TEXTURE2D, false},
{D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_UAV_DIMENSION_TEXTURE2DARRAY, true },
/* Expected behaviour with partial layer coverage is unclear. */
{D3D12_RESOURCE_DIMENSION_TEXTURE3D, D3D12_UAV_DIMENSION_TEXTURE3D, false},
};
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
cpu_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
gpu_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
memset(&heap_properties, 0, sizeof(heap_properties));
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
for (d = 0; d < ARRAY_SIZE(uav_dimensions); ++d)
{
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
vkd3d_test_set_context("Dim %u, Test %u", d, i);
if (tests[i].image_layers > 1 && !uav_dimensions[d].is_layered)
continue;
resource_desc.Dimension = uav_dimensions[d].resource_dim;
resource_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
resource_desc.Width = IMAGE_SIZE;
resource_desc.Height = IMAGE_SIZE;
if (uav_dimensions[d].resource_dim == D3D12_RESOURCE_DIMENSION_TEXTURE1D)
resource_desc.Height = 1;
resource_desc.DepthOrArraySize = tests[i].image_layers;
resource_desc.MipLevels = tests[i].image_mips;
resource_desc.Format = tests[i].format;
resource_desc.SampleDesc.Count = 1;
resource_desc.SampleDesc.Quality = 0;
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
if (FAILED(hr = ID3D12Device_CreateCommittedResource(device, &heap_properties,
D3D12_HEAP_FLAG_NONE, &resource_desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
NULL, &IID_ID3D12Resource, (void **)&texture)))
{
skip("Failed to create texture, hr %#x.\n", hr);
continue;
}
uav_desc.Format = tests[i].format;
uav_desc.ViewDimension = uav_dimensions[d].view_dim;
for (j = 0; j < 2; ++j)
{
unsigned int first_layer = j ? 0 : tests[i].first_layer;
unsigned int layer_count = j ? tests[i].image_layers : tests[i].layer_count;
switch (uav_desc.ViewDimension)
{
case D3D12_UAV_DIMENSION_TEXTURE1D:
uav_desc.Texture1D.MipSlice = tests[i].mip_level;
break;
case D3D12_UAV_DIMENSION_TEXTURE1DARRAY:
uav_desc.Texture1DArray.MipSlice = tests[i].mip_level;
uav_desc.Texture1DArray.FirstArraySlice = first_layer;
uav_desc.Texture1DArray.ArraySize = layer_count;
break;
case D3D12_UAV_DIMENSION_TEXTURE2D:
uav_desc.Texture2D.MipSlice = tests[i].mip_level;
uav_desc.Texture2D.PlaneSlice = 0;
break;
case D3D12_UAV_DIMENSION_TEXTURE2DARRAY:
uav_desc.Texture2DArray.MipSlice = tests[i].mip_level;
uav_desc.Texture2DArray.FirstArraySlice = first_layer;
uav_desc.Texture2DArray.ArraySize = layer_count;
uav_desc.Texture2DArray.PlaneSlice = 0;
break;
case D3D12_UAV_DIMENSION_TEXTURE3D:
uav_desc.Texture3D.MipSlice = tests[i].mip_level;
uav_desc.Texture3D.FirstWSlice = first_layer;
uav_desc.Texture3D.WSize = layer_count;
break;
default:
continue;
}
ID3D12Device_CreateUnorderedAccessView(device, texture, NULL,
&uav_desc, get_cpu_descriptor_handle(&context, cpu_heap, j));
ID3D12Device_CreateUnorderedAccessView(device, texture, NULL,
&uav_desc, get_cpu_descriptor_handle(&context, gpu_heap, j));
}
if (tests[i].is_null_descriptor)
{
/* Test that we can clear out any knowledge about the existing descriptor. */
ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL,
&uav_desc, get_cpu_descriptor_handle(&context, cpu_heap, 0));
ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL,
&uav_desc, get_cpu_descriptor_handle(&context, gpu_heap, 0));
}
for (j = 0; j < 4; ++j)
{
clear_value[j] = tests[i].expected || tests[i].is_null_descriptor ? 0u : ~0u;
}
ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
get_gpu_descriptor_handle(&context, gpu_heap, 1),
get_cpu_descriptor_handle(&context, cpu_heap, 1),
texture, clear_value, 0, NULL);
uav_barrier(command_list, texture);
if (tests[i].is_float)
ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(command_list,
get_gpu_descriptor_handle(&context, gpu_heap, 0),
get_cpu_descriptor_handle(&context, cpu_heap, 0),
texture, (const float *)tests[i].values, tests[i].rect_count, tests[i].clear_rects);
else
ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
get_gpu_descriptor_handle(&context, gpu_heap, 0),
get_cpu_descriptor_handle(&context, cpu_heap, 0),
texture, tests[i].values, tests[i].rect_count, tests[i].clear_rects);
transition_resource_state(command_list, texture,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
image_depth = uav_dimensions[d].resource_dim == D3D12_RESOURCE_DIMENSION_TEXTURE3D
? max(tests[i].image_layers >> tests[i].mip_level, 1u) : 1;
image_size = max(IMAGE_SIZE >> tests[i].mip_level, 1u);
for (layer = 0; layer < tests[i].image_layers / image_depth; ++layer)
{
get_texture_readback_with_command_list(texture,
tests[i].mip_level + (layer * tests[i].image_mips),
&rb, queue, command_list);
for (p = 0; p < image_depth * image_size * image_size; ++p)
{
x = p % image_size;
y = (p / image_size) % image_size;
z = p / (image_size * image_size);
is_inside = tests[i].rect_count == 0;
for (j = 0; j < tests[i].rect_count; ++j)
{
if (y >= tests[i].clear_rects[j].top && y < tests[i].clear_rects[j].bottom
&& x >= tests[i].clear_rects[j].left && x < tests[i].clear_rects[j].right)
{
is_inside = true;
break;
}
}
if (uav_dimensions[d].resource_dim == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
is_inside = is_inside && z >= tests[i].first_layer
&& z < tests[i].first_layer + tests[i].layer_count;
else
is_inside = is_inside && layer >= tests[i].first_layer
&& layer < tests[i].first_layer + tests[i].layer_count;
expected_colour = is_inside ? tests[i].expected : clear_value[0];
actual_colour = get_readback_uint(&rb, x, y, z);
success = compare_color(actual_colour, expected_colour, tests[i].is_float ? 1 : 0);
ok(success, "At layer %u, (%u,%u,%u), expected %#x, got %#x.\n",
layer, x, y, z, expected_colour, actual_colour);
if (!success)
break;
}
release_resource_readback(&rb);
reset_command_list(command_list, context.allocator);
}
ID3D12Resource_Release(texture);
}
}
ID3D12DescriptorHeap_Release(cpu_heap);
ID3D12DescriptorHeap_Release(gpu_heap);
destroy_test_context(&context);
#undef IMAGE_SIZE
}

File diff suppressed because it is too large Load Diff

3983
tests/d3d12_command.c Normal file

File diff suppressed because it is too large Load Diff

1022
tests/d3d12_copy.c Normal file

File diff suppressed because it is too large Load Diff

1535
tests/d3d12_depth_stencil.c Normal file

File diff suppressed because it is too large Load Diff

4470
tests/d3d12_descriptors.c Normal file

File diff suppressed because it is too large Load Diff

1475
tests/d3d12_device.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2296
tests/d3d12_pso.c Normal file

File diff suppressed because it is too large Load Diff

265
tests/d3d12_pso_blob.c Normal file
View File

@ -0,0 +1,265 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
void test_get_cached_blob(void)
{
D3D12_COMPUTE_PIPELINE_STATE_DESC compute_desc;
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
ID3D12RootSignature *root_signature;
struct test_context context;
ID3D12PipelineState *state;
ID3D12Device *device;
ID3DBlob *blob;
HRESULT hr;
#if 0
[numthreads(1,1,1)]
void main() { }
#endif
static const DWORD cs_dxbc[] =
{
0x43425844, 0x1acc3ad0, 0x71c7b057, 0xc72c4306, 0xf432cb57, 0x00000001, 0x00000074, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000020, 0x00050050, 0x00000008, 0x0100086a,
0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x0100003e,
};
if (!init_test_context(&context, NULL))
return;
device = context.device;
memset(&root_signature_desc, 0, sizeof(root_signature_desc));
hr = create_root_signature(device, &root_signature_desc, &root_signature);
ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
memset(&compute_desc, 0, sizeof(compute_desc));
compute_desc.pRootSignature = root_signature;
compute_desc.CS.pShaderBytecode = cs_dxbc;
compute_desc.CS.BytecodeLength = sizeof(cs_dxbc);
hr = ID3D12Device_CreateComputePipelineState(device,
&compute_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to create compute pipeline, hr %#x.\n", hr);
hr = ID3D12PipelineState_GetCachedBlob(state, &blob);
ok(hr == S_OK, "Failed to get cached blob, hr %#x.\n", hr);
ok(ID3D10Blob_GetBufferSize(blob) > 0, "Cached blob is empty.\n");
ID3D12PipelineState_Release(state);
compute_desc.CachedPSO.pCachedBlob = ID3D10Blob_GetBufferPointer(blob);
compute_desc.CachedPSO.CachedBlobSizeInBytes = ID3D10Blob_GetBufferSize(blob);
hr = ID3D12Device_CreateComputePipelineState(device,
&compute_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to create compute pipeline, hr %#x.\n", hr);
ID3D12PipelineState_Release(state);
ID3D12RootSignature_Release(root_signature);
ID3D10Blob_Release(blob);
destroy_test_context(&context);
}
void test_pipeline_library(void)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC graphics_desc;
D3D12_COMPUTE_PIPELINE_STATE_DESC compute_desc;
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
ID3D12PipelineLibrary *pipeline_library;
ID3D12RootSignature *root_signature;
struct test_context context;
ID3D12PipelineState *state;
size_t serialized_size;
ID3D12Device1 *device1;
void *serialized_data;
ID3D12Device *device;
HRESULT hr;
#if 0
[numthreads(1,1,1)]
void main() { }
#endif
static const DWORD cs_dxbc[] =
{
0x43425844, 0x1acc3ad0, 0x71c7b057, 0xc72c4306, 0xf432cb57, 0x00000001, 0x00000074, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000020, 0x00050050, 0x00000008, 0x0100086a,
0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x0100003e,
};
#if 0
float4 main() : SV_POSITION {
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
#endif
static const DWORD vs_dxbc[] =
{
0x43425844, 0xae39b246, 0xddd05b5a, 0x5057a6a2, 0x034461ee, 0x00000001, 0x000000b8, 0x00000003,
0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x58454853, 0x00000040, 0x00010050, 0x00000010,
0x0100086a, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x08000036, 0x001020f2, 0x00000000,
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
};
#if 0
float4 main() : SV_TARGET {
return float4(1.0f, 1.0f, 1.0f, 1.0f);
}
#endif
static const DWORD ps_dxbc[] =
{
0x43425844, 0x29b14cf3, 0xb991cf90, 0x9e455ffc, 0x4675b046, 0x00000001, 0x000000b4, 0x00000003,
0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f,
0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0100003e,
};
const WCHAR *graphics_name = u"GRAPHICS";
const WCHAR *compute_name = u"COMPUTE";
if (!init_test_context(&context, NULL))
return;
device = context.device;
if (FAILED(hr = ID3D12Device_QueryInterface(device, &IID_ID3D12Device1, (void**)&device1)))
{
skip("ID3D12Device1 not available.\n");
return;
}
/* Test adding pipelines to an empty pipeline library */
hr = ID3D12Device1_CreatePipelineLibrary(device1, NULL, 0, &IID_ID3D12PipelineLibrary, (void**)&pipeline_library);
ok(hr == S_OK, "Failed to create pipeline library, hr %#x.\n");
memset(&root_signature_desc, 0, sizeof(root_signature_desc));
hr = create_root_signature(device, &root_signature_desc, &root_signature);
ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
memset(&compute_desc, 0, sizeof(compute_desc));
compute_desc.pRootSignature = root_signature;
compute_desc.CS.pShaderBytecode = cs_dxbc;
compute_desc.CS.BytecodeLength = sizeof(cs_dxbc);
hr = ID3D12PipelineLibrary_LoadComputePipeline(pipeline_library,
compute_name, &compute_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
hr = ID3D12Device_CreateComputePipelineState(device,
&compute_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to create compute pipeline, hr %#x.\n", hr);
hr = ID3D12PipelineLibrary_StorePipeline(pipeline_library, compute_name, state);
ok(hr == S_OK, "Failed to store compute pipeline, hr %x.\n", hr);
ID3D12PipelineState_Release(state);
memset(&graphics_desc, 0, sizeof(graphics_desc));
graphics_desc.pRootSignature = root_signature;
graphics_desc.VS.pShaderBytecode = vs_dxbc;
graphics_desc.VS.BytecodeLength = sizeof(vs_dxbc);
graphics_desc.PS.pShaderBytecode = ps_dxbc;
graphics_desc.PS.BytecodeLength = sizeof(ps_dxbc);
graphics_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
graphics_desc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK;
graphics_desc.RasterizerState.FrontCounterClockwise = true;
graphics_desc.SampleMask = 0x1;
graphics_desc.SampleDesc.Count = 1;
graphics_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
graphics_desc.NumRenderTargets = 1;
graphics_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
hr = ID3D12PipelineLibrary_LoadGraphicsPipeline(pipeline_library,
graphics_name, &graphics_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
hr = ID3D12Device_CreateGraphicsPipelineState(device,
&graphics_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to create graphics pipeline, hr %#x.\n", hr);
hr = ID3D12PipelineLibrary_StorePipeline(pipeline_library, graphics_name, state);
ok(hr == S_OK, "Failed to store compute pipeline, hr %x.\n", hr);
hr = ID3D12PipelineLibrary_StorePipeline(pipeline_library, compute_name, state);
ok(hr == E_INVALIDARG, "Storing pipeline with already existing name succeeded, hr %x.\n", hr);
ID3D12PipelineState_Release(state);
/* Test looking up pipelines in a new pipeline library */
hr = ID3D12PipelineLibrary_LoadComputePipeline(pipeline_library,
compute_name, &compute_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to load compute pipeline from pipeline library, hr %#x.\n", hr);
ID3D12PipelineState_Release(state);
hr = ID3D12PipelineLibrary_LoadGraphicsPipeline(pipeline_library,
graphics_name, &graphics_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to load graphics pipeline from pipeline library, hr %#x.\n", hr);
ID3D12PipelineState_Release(state);
serialized_size = ID3D12PipelineLibrary_GetSerializedSize(pipeline_library);
ok(serialized_size > 0, "Serialized size for pipeline library is 0.\n");
serialized_data = malloc(serialized_size);
hr = ID3D12PipelineLibrary_Serialize(pipeline_library, serialized_data, serialized_size - 1);
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
hr = ID3D12PipelineLibrary_Serialize(pipeline_library, serialized_data, serialized_size);
ok(hr == S_OK, "Failed to serialize pipeline library, hr %#x.\n", hr);
ID3D12PipelineLibrary_Release(pipeline_library);
/* Test deserializing a pipeline library */
hr = ID3D12Device1_CreatePipelineLibrary(device1, serialized_data,
serialized_size, &IID_ID3D12PipelineLibrary, (void**)&pipeline_library);
ok(hr == S_OK, "Failed to create pipeline library, hr %#x.\n");
hr = ID3D12PipelineLibrary_LoadGraphicsPipeline(pipeline_library,
graphics_name, &graphics_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to load graphics pipeline from pipeline library, hr %#x.\n", hr);
ID3D12PipelineState_Release(state);
hr = ID3D12PipelineLibrary_LoadComputePipeline(pipeline_library,
compute_name, &compute_desc, &IID_ID3D12PipelineState, (void**)&state);
ok(hr == S_OK, "Failed to load compute pipeline from pipeline library, hr %#x.\n", hr);
ID3D12PipelineState_Release(state);
hr = ID3D12PipelineLibrary_LoadComputePipeline(pipeline_library,
graphics_name, &compute_desc, &IID_ID3D12PipelineState, (void**)&state);
todo ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr))
ID3D12PipelineState_Release(state);
ID3D12PipelineLibrary_Release(pipeline_library);
free(serialized_data);
ID3D12RootSignature_Release(root_signature);
ID3D12Device1_Release(device1);
destroy_test_context(&context);
}

722
tests/d3d12_query.c Normal file
View File

@ -0,0 +1,722 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
void test_create_query_heap(void)
{
ID3D12Device *device;
D3D12_QUERY_HEAP_DESC heap_desc;
ID3D12QueryHeap *query_heap;
ULONG refcount;
unsigned int i;
HRESULT hr;
static const D3D12_QUERY_HEAP_TYPE types[] =
{
D3D12_QUERY_HEAP_TYPE_OCCLUSION,
D3D12_QUERY_HEAP_TYPE_TIMESTAMP,
D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS,
};
if (!(device = create_device()))
{
skip("Failed to create device.\n");
return;
}
for (i = 0; i < ARRAY_SIZE(types); ++i)
{
heap_desc.Type = types[i];
heap_desc.Count = 1;
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
ok(hr == S_OK, "Failed to create query heap, type %u, hr %#x.\n", types[i], hr);
ID3D12QueryHeap_Release(query_heap);
}
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_SO_STATISTICS;
heap_desc.Count = 1;
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
if (hr != E_NOTIMPL)
{
ok(hr == S_OK, "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
ID3D12QueryHeap_Release(query_heap);
}
else
{
skip("Stream output is not supported.\n");
}
refcount = ID3D12Device_Release(device);
ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
}
void test_query_timestamp(void)
{
uint64_t timestamps[4], timestamp_frequency, timestamp_diff, time_diff;
ID3D12GraphicsCommandList *command_list;
D3D12_QUERY_HEAP_DESC heap_desc;
struct test_context_desc desc;
ID3D12QueryHeap *query_heap;
struct resource_readback rb;
struct test_context context;
time_t time_start, time_end;
ID3D12CommandQueue *queue;
ID3D12Resource *resource;
ID3D12Device *device;
unsigned int i;
HRESULT hr;
time_start = time(NULL);
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
hr = ID3D12CommandQueue_GetTimestampFrequency(queue, &timestamp_frequency);
ok(SUCCEEDED(hr), "Failed to get timestamp frequency, hr %#x.\n", hr);
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
heap_desc.Count = ARRAY_SIZE(timestamps);
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
ok(SUCCEEDED(hr), "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
resource = create_readback_buffer(device, sizeof(timestamps));
for (i = 0; i < ARRAY_SIZE(timestamps); ++i)
ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_TIMESTAMP, i);
ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap,
D3D12_QUERY_TYPE_TIMESTAMP, 0, 1, resource, 0);
ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap,
D3D12_QUERY_TYPE_TIMESTAMP, 1, 3, resource, sizeof(uint64_t));
get_buffer_readback_with_command_list(resource, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
time_end = time(NULL) + 1;
for (i = 0; i < ARRAY_SIZE(timestamps); ++i)
timestamps[i] = get_readback_uint64(&rb, i, 0);
for (i = 0; i < ARRAY_SIZE(timestamps) - 1; ++i)
{
ok(timestamps[i] <= timestamps[i + 1], "Expected timestamps to monotonically increase, "
"but got %"PRIu64" > %"PRIu64".\n", timestamps[i], timestamps[i + 1]);
}
time_diff = (uint64_t)difftime(time_end, time_start) * timestamp_frequency;
timestamp_diff = timestamps[ARRAY_SIZE(timestamps) - 1] - timestamps[0];
ok(timestamp_diff <= time_diff, "Expected timestamp difference to be bounded by CPU time difference, "
"but got %"PRIu64" > %"PRIu64".\n", timestamp_diff, time_diff);
release_resource_readback(&rb);
ID3D12QueryHeap_Release(query_heap);
ID3D12Resource_Release(resource);
destroy_test_context(&context);
}
void test_query_pipeline_statistics(void)
{
D3D12_QUERY_DATA_PIPELINE_STATISTICS *pipeline_statistics;
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
ID3D12GraphicsCommandList *command_list;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
D3D12_QUERY_HEAP_DESC heap_desc;
ID3D12QueryHeap *query_heap;
ID3D12Resource *resource;
struct resource_readback rb;
unsigned int pixel_count, i;
HRESULT hr;
if (!init_test_context(&context, NULL))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
heap_desc.Count = 2;
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
ok(SUCCEEDED(hr), "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
resource = create_readback_buffer(device, 2 * sizeof(struct D3D12_QUERY_DATA_PIPELINE_STATISTICS));
/* First query: do nothing. */
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0, 1,
resource, 0);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
/* Second query: draw something simple. */
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 1);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 1);
ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 1, 1,
resource, sizeof(struct D3D12_QUERY_DATA_PIPELINE_STATISTICS));
get_buffer_readback_with_command_list(resource, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
for (i = 0; i < sizeof(struct D3D12_QUERY_DATA_PIPELINE_STATISTICS) / sizeof(uint64_t); ++i)
{
uint64_t value = get_readback_uint64(&rb, i, 0);
ok(!value, "Element %d: Got %"PRIu64", expected 0.\n", i, value);
}
pipeline_statistics = get_readback_data(&rb, 1, 0, 0, sizeof(*pipeline_statistics));
/* We read 3 vertices that formed one primitive. */
ok(pipeline_statistics->IAVertices == 3, "IAVertices: Got %"PRIu64", expected 3.\n",
pipeline_statistics->IAVertices);
ok(pipeline_statistics->IAPrimitives == 1, "IAPrimitives: Got %"PRIu64", expected 1.\n",
pipeline_statistics->IAPrimitives);
ok(pipeline_statistics->VSInvocations == 3, "VSInvocations: Got %"PRIu64", expected 3.\n",
pipeline_statistics->VSInvocations);
/* No geometry shader output primitives.
* Depending on the graphics card, the geometry shader might still have been invoked, so
* GSInvocations might be whatever. */
ok(pipeline_statistics->GSPrimitives == 0, "GSPrimitives: Got %"PRIu64", expected 0.\n",
pipeline_statistics->GSPrimitives);
/* One primitive sent to the rasterizer, but it might have been broken up into smaller pieces then. */
ok(pipeline_statistics->CInvocations == 1, "CInvocations: Got %"PRIu64", expected 1.\n",
pipeline_statistics->CInvocations);
ok(pipeline_statistics->CPrimitives > 0, "CPrimitives: Got %"PRIu64", expected > 0.\n",
pipeline_statistics->CPrimitives);
/* Exact number of pixel shader invocations depends on the graphics card. */
pixel_count = context.render_target_desc.Width * context.render_target_desc.Height;
ok(pipeline_statistics->PSInvocations >= pixel_count, "PSInvocations: Got %"PRIu64", expected >= %u.\n",
pipeline_statistics->PSInvocations, pixel_count);
/* We used no tessellation or compute shaders at all. */
ok(pipeline_statistics->HSInvocations == 0, "HSInvocations: Got %"PRIu64", expected 0.\n",
pipeline_statistics->HSInvocations);
ok(pipeline_statistics->DSInvocations == 0, "DSInvocations: Got %"PRIu64", expected 0.\n",
pipeline_statistics->DSInvocations);
ok(pipeline_statistics->CSInvocations == 0, "CSInvocations: Got %"PRIu64", expected 0.\n",
pipeline_statistics->CSInvocations);
release_resource_readback(&rb);
ID3D12QueryHeap_Release(query_heap);
ID3D12Resource_Release(resource);
destroy_test_context(&context);
}
void test_query_occlusion(void)
{
struct test_context_desc desc;
ID3D12GraphicsCommandList *command_list;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
struct depth_stencil_resource ds;
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
D3D12_QUERY_HEAP_DESC heap_desc;
ID3D12QueryHeap *query_heap;
ID3D12Resource *resource;
struct resource_readback rb;
unsigned int i;
HRESULT hr;
static const DWORD ps_code[] =
{
#if 0
float depth;
float main() : SV_Depth
{
return depth;
}
#endif
0x43425844, 0x91af6cd0, 0x7e884502, 0xcede4f54, 0x6f2c9326, 0x00000001, 0x000000b0, 0x00000003,
0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff,
0x00000e01, 0x445f5653, 0x68747065, 0xababab00, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x02000065, 0x0000c001, 0x05000036, 0x0000c001,
0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
static const struct
{
D3D12_QUERY_TYPE type;
bool draw;
float clear_depth;
float depth;
}
tests[] =
{
{D3D12_QUERY_TYPE_OCCLUSION, false, 1.0f, 0.5f},
{D3D12_QUERY_TYPE_OCCLUSION, true, 1.0f, 0.5f},
{D3D12_QUERY_TYPE_BINARY_OCCLUSION, false, 1.0f, 0.5f},
{D3D12_QUERY_TYPE_BINARY_OCCLUSION, true, 1.0f, 0.5f},
{D3D12_QUERY_TYPE_OCCLUSION, false, 0.0f, 0.5f},
{D3D12_QUERY_TYPE_OCCLUSION, true, 0.0f, 0.5f},
{D3D12_QUERY_TYPE_BINARY_OCCLUSION, false, 0.0f, 0.5f},
{D3D12_QUERY_TYPE_BINARY_OCCLUSION, true, 0.0f, 0.5f},
};
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
init_depth_stencil(&ds, context.device, 640, 480, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
set_viewport(&context.viewport, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
set_rect(&context.scissor_rect, 0, 0, 640, 480);
context.root_signature = create_32bit_constants_root_signature(context.device,
0, 1, D3D12_SHADER_VISIBILITY_PIXEL);
init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
pso_desc.NumRenderTargets = 0;
pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
pso_desc.DepthStencilState.DepthEnable = true;
pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
heap_desc.Count = ARRAY_SIZE(tests);
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
ok(SUCCEEDED(hr), "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
resource = create_readback_buffer(device, ARRAY_SIZE(tests) * sizeof(uint64_t));
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds.dsv_handle);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
vkd3d_test_set_context("Test %u", i);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, tests[i].clear_depth, 0, 0, NULL);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, tests[i].type, i);
if (tests[i].draw)
{
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &tests[i].depth, 0);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
}
ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, tests[i].type, i);
ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap, tests[i].type, i, 1,
resource, i * sizeof(uint64_t));
}
vkd3d_test_set_context(NULL);
get_buffer_readback_with_command_list(resource, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
const bool samples_passed = tests[i].draw && tests[i].clear_depth > tests[i].depth;
const uint64_t result = get_readback_uint64(&rb, i, 0);
uint64_t expected_result;
if (tests[i].type == D3D12_QUERY_TYPE_BINARY_OCCLUSION)
expected_result = samples_passed ? 1 : 0;
else
expected_result = samples_passed ? 640 * 480 : 0;
ok(result == expected_result, "Test %u: Got unexpected result %"PRIu64".\n", i, result);
}
release_resource_readback(&rb);
ID3D12QueryHeap_Release(query_heap);
ID3D12Resource_Release(resource);
destroy_depth_stencil(&ds);
destroy_test_context(&context);
}
void test_resolve_non_issued_query_data(void)
{
static const uint64_t initial_data[] = {0xdeadbeef, 0xdeadbeef, 0xdeadbabe, 0xdeadbeef};
ID3D12Resource *readback_buffer, *upload_buffer;
ID3D12GraphicsCommandList *command_list;
D3D12_QUERY_HEAP_DESC heap_desc;
struct test_context_desc desc;
ID3D12QueryHeap *query_heap;
struct resource_readback rb;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
uint64_t *timestamps;
HRESULT hr;
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
heap_desc.Count = ARRAY_SIZE(initial_data);
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
ok(SUCCEEDED(hr), "Failed to create query heap, hr %#x.\n", hr);
readback_buffer = create_readback_buffer(device, sizeof(initial_data));
upload_buffer = create_upload_buffer(context.device, sizeof(initial_data), initial_data);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_TIMESTAMP, 0);
ID3D12GraphicsCommandList_CopyResource(command_list, readback_buffer, upload_buffer);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_TIMESTAMP, 3);
ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap,
D3D12_QUERY_TYPE_TIMESTAMP, 0, 4, readback_buffer, 0);
get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
timestamps = get_readback_data(&rb, 0, 0, 0, sizeof(*timestamps));
ok(timestamps[0] != initial_data[0] && timestamps[0] > 0,
"Got unexpected timestamp %#"PRIx64".\n", timestamps[0]);
todo ok(!timestamps[1], "Got unexpected timestamp %#"PRIx64".\n", timestamps[1]);
todo ok(!timestamps[2], "Got unexpected timestamp %#"PRIx64".\n", timestamps[2]);
ok(timestamps[3] != initial_data[3] && timestamps[3] > 0,
"Got unexpected timestamp %#"PRIx64".\n", timestamps[3]);
release_resource_readback(&rb);
ID3D12QueryHeap_Release(query_heap);
ID3D12Resource_Release(readback_buffer);
ID3D12Resource_Release(upload_buffer);
destroy_test_context(&context);
}
void test_resolve_query_data_in_different_command_list(void)
{
ID3D12GraphicsCommandList *command_list;
D3D12_QUERY_HEAP_DESC heap_desc;
ID3D12Resource *readback_buffer;
struct resource_readback rb;
ID3D12QueryHeap *query_heap;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
unsigned int i;
HRESULT hr;
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
const unsigned int readback_buffer_capacity = 4;
if (!init_test_context(&context, NULL))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
heap_desc.Count = 1;
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
ok(SUCCEEDED(hr), "Failed to create query heap, hr %#x.\n", hr);
readback_buffer = create_readback_buffer(device, readback_buffer_capacity * sizeof(uint64_t));
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
reset_command_list(command_list, context.allocator);
for (i = 0; i < readback_buffer_capacity / 2; ++i)
{
ID3D12GraphicsCommandList_ResolveQueryData(command_list,
query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0, 1, readback_buffer, i * sizeof(uint64_t));
}
hr = ID3D12GraphicsCommandList_Close(command_list);
ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
exec_command_list(queue, command_list);
wait_queue_idle(context.device, queue);
reset_command_list(command_list, context.allocator);
for (; i < readback_buffer_capacity; ++i)
{
ID3D12GraphicsCommandList_ResolveQueryData(command_list,
query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0, 1, readback_buffer, i * sizeof(uint64_t));
}
get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
for (i = 0; i < readback_buffer_capacity; ++i)
{
uint64_t expected_result = context.render_target_desc.Width * context.render_target_desc.Height;
uint64_t result = get_readback_uint64(&rb, i, 0);
ok(result == expected_result, "Got unexpected result %"PRIu64" at %u.\n", result, i);
}
release_resource_readback(&rb);
ID3D12QueryHeap_Release(query_heap);
ID3D12Resource_Release(readback_buffer);
destroy_test_context(&context);
}
void test_resolve_query_data_in_reordered_command_list(void)
{
ID3D12GraphicsCommandList *command_lists[2];
ID3D12CommandAllocator *command_allocator;
D3D12_QUERY_HEAP_DESC heap_desc;
ID3D12Resource *readback_buffer;
struct resource_readback rb;
ID3D12QueryHeap *query_heap;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
uint64_t result;
HRESULT hr;
if (!init_test_context(&context, NULL))
return;
device = context.device;
command_lists[0] = context.list;
queue = context.queue;
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);
hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_lists[1]);
ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
heap_desc.Count = 1;
heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
ok(SUCCEEDED(hr), "Failed to create query heap, hr %#x.\n", hr);
readback_buffer = create_readback_buffer(device, sizeof(uint64_t));
/* Read query results in the second command list. */
ID3D12GraphicsCommandList_ResolveQueryData(command_lists[1],
query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0, 1, readback_buffer, 0);
hr = ID3D12GraphicsCommandList_Close(command_lists[1]);
ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
/* Produce query results in the first command list. */
ID3D12GraphicsCommandList_OMSetRenderTargets(command_lists[0], 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_lists[0], context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_lists[0], context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_lists[0], D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_lists[0], 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_lists[0], 1, &context.scissor_rect);
ID3D12GraphicsCommandList_BeginQuery(command_lists[0], query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
ID3D12GraphicsCommandList_DrawInstanced(command_lists[0], 3, 1, 0, 0);
ID3D12GraphicsCommandList_EndQuery(command_lists[0], query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
hr = ID3D12GraphicsCommandList_Close(command_lists[0]);
ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
ID3D12CommandQueue_ExecuteCommandLists(queue,
ARRAY_SIZE(command_lists), (ID3D12CommandList **)command_lists);
wait_queue_idle(device, queue);
reset_command_list(command_lists[0], context.allocator);
get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_lists[0]);
result = get_readback_uint64(&rb, 0, 0);
ok(result == context.render_target_desc.Width * context.render_target_desc.Height,
"Got unexpected result %"PRIu64".\n", result);
release_resource_readback(&rb);
ID3D12GraphicsCommandList_Release(command_lists[1]);
ID3D12CommandAllocator_Release(command_allocator);
ID3D12QueryHeap_Release(query_heap);
ID3D12Resource_Release(readback_buffer);
destroy_test_context(&context);
}
void test_virtual_queries(void)
{
struct test_context_desc desc;
ID3D12GraphicsCommandList *command_list;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
struct depth_stencil_resource ds[2];
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
D3D12_QUERY_HEAP_DESC heap_desc;
ID3D12QueryHeap *query_heaps[2];
ID3D12Resource *resource;
struct resource_readback rb;
unsigned int i;
HRESULT hr;
static const DWORD ps_code[] =
{
#if 0
float depth;
float main() : SV_Depth
{
return depth;
}
#endif
0x43425844, 0x91af6cd0, 0x7e884502, 0xcede4f54, 0x6f2c9326, 0x00000001, 0x000000b0, 0x00000003,
0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff,
0x00000e01, 0x445f5653, 0x68747065, 0xababab00, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x02000065, 0x0000c001, 0x05000036, 0x0000c001,
0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
static const uint32_t expected_results[] = {1,0,1,1,614400,0,307200,307200};
static const float depth_one = 1.0f;
static const float depth_zero = 0.0f;
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
for (i = 0; i < ARRAY_SIZE(ds); i++)
init_depth_stencil(&ds[i], context.device, 640, 480, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
set_viewport(&context.viewport, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
set_rect(&context.scissor_rect, 0, 0, 640, 480);
context.root_signature = create_32bit_constants_root_signature(context.device,
0, 1, D3D12_SHADER_VISIBILITY_PIXEL);
init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
pso_desc.NumRenderTargets = 0;
pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
pso_desc.DepthStencilState.DepthEnable = true;
pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
heap_desc.Count = ARRAY_SIZE(expected_results) / 2;
heap_desc.NodeMask = 0;
for (i = 0; i < ARRAY_SIZE(query_heaps); i++)
{
hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heaps[i]);
ok(SUCCEEDED(hr), "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
}
resource = create_readback_buffer(device, ARRAY_SIZE(expected_results) * sizeof(uint64_t));
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds[0].dsv_handle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds[1].dsv_handle, D3D12_CLEAR_FLAG_DEPTH, 0.5f, 0, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds[0].dsv_handle);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 1);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 2);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 0);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 1);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 2);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 1);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 1);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &depth_zero, 0);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 2);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 2);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds[1].dsv_handle);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 3);
ID3D12GraphicsCommandList_BeginQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 3);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 0);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &depth_one, 0);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[0], D3D12_QUERY_TYPE_BINARY_OCCLUSION, 3);
ID3D12GraphicsCommandList_EndQuery(command_list, query_heaps[1], D3D12_QUERY_TYPE_OCCLUSION, 3);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds[1].dsv_handle);
for (i = 0; i < ARRAY_SIZE(query_heaps); i++)
{
ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heaps[i],
i ? D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_BINARY_OCCLUSION,
0, 4, resource, i * 4 * sizeof(uint64_t));
}
get_buffer_readback_with_command_list(resource, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
for (i = 0; i < ARRAY_SIZE(expected_results); ++i)
{
const uint64_t result = get_readback_uint64(&rb, i, 0);
ok(result == expected_results[i], "Test %u: Got unexpected result %"PRIu64".\n", i, result);
}
release_resource_readback(&rb);
for (i = 0; i < ARRAY_SIZE(query_heaps); i++)
ID3D12QueryHeap_Release(query_heaps[i]);
ID3D12Resource_Release(resource);
for (i = 0; i < ARRAY_SIZE(ds); i++)
destroy_depth_stencil(&ds[i]);
destroy_test_context(&context);
}

1199
tests/d3d12_raytracing.c Normal file

File diff suppressed because it is too large Load Diff

673
tests/d3d12_render_target.c Normal file
View File

@ -0,0 +1,673 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
void test_unknown_rtv_format(void)
{
static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
struct vec4 expected_vec4 = {0.0f, 0.0f, 0.0f, 1.0f};
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12GraphicsCommandList *command_list;
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
D3D12_CPU_DESCRIPTOR_HANDLE rtvs[3];
ID3D12Resource *render_targets[2];
struct depth_stencil_resource ds;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
unsigned int i;
HRESULT hr;
static const DWORD ps_code[] =
{
#if 0
void main(out float4 target1 : SV_Target1, out float4 target2 : SV_Target2)
{
target1 = float4(2.0f, 0.0f, 0.0f, 1.0f);
target2 = float4(3.0f, 0.0f, 0.0f, 1.0f);
}
#endif
0x43425844, 0x980554be, 0xb8743fb0, 0xf5bb8deb, 0x639feaf8, 0x00000001, 0x000000f4, 0x00000003,
0x0000002c, 0x0000003c, 0x00000088, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000001, 0x00000000, 0x00000003, 0x00000001,
0x0000000f, 0x00000038, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x545f5653,
0x65677261, 0xabab0074, 0x52444853, 0x00000064, 0x00000040, 0x00000019, 0x03000065, 0x001020f2,
0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x08000036, 0x001020f2, 0x00000001, 0x00004002,
0x40000000, 0x00000000, 0x00000000, 0x3f800000, 0x08000036, 0x001020f2, 0x00000002, 0x00004002,
0x40400000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
memset(&desc, 0, sizeof(desc));
desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.rt_descriptor_count = 16;
desc.no_pipeline = true;
if (!init_test_context(&context, &desc))
return;
command_list = context.list;
queue = context.queue;
init_depth_stencil(&ds, context.device, 32, 32, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
pso_desc.NumRenderTargets = ARRAY_SIZE(rtvs);
for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
pso_desc.RTVFormats[i] = desc.rt_format;
pso_desc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN;
pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
pso_desc.DepthStencilState.DepthEnable = true;
pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
rtvs[0] = get_cpu_rtv_handle(&context, context.rtv_heap, 0);
rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
rtvs[2] = get_cpu_rtv_handle(&context, context.rtv_heap, 2);
create_render_target(&context, &desc, &render_targets[0], &rtvs[1]);
create_render_target(&context, &desc, &render_targets[1], &rtvs[2]);
for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[i], &white.x, 0, NULL);
/* NULL RTV */
memset(&rtv_desc, 0, sizeof(rtv_desc));
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rtv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
rtv_desc.Texture2D.MipSlice = 0;
rtv_desc.Texture2D.PlaneSlice = 0;
ID3D12Device_CreateRenderTargetView(context.device, NULL, &rtv_desc,
get_cpu_rtv_handle(&context, context.rtv_heap, 0));
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, ARRAY_SIZE(rtvs), rtvs, false, &ds.dsv_handle);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.5f, 0.5f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
transition_resource_state(command_list, render_targets[0],
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
transition_resource_state(command_list, render_targets[1],
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_vec4(context.render_target, 0, queue, command_list, &white, 0);
reset_command_list(command_list, context.allocator);
expected_vec4.x = 2.0f;
check_sub_resource_vec4(render_targets[0], 0, queue, command_list, &expected_vec4, 0);
reset_command_list(command_list, context.allocator);
expected_vec4.x = 3.0f;
check_sub_resource_vec4(render_targets[1], 0, queue, command_list, &expected_vec4, 0);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, ds.texture,
D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_float(ds.texture, 0, queue, command_list, 0.5f, 1);
for (i = 0; i < ARRAY_SIZE(render_targets); ++i)
ID3D12Resource_Release(render_targets[i]);
destroy_depth_stencil(&ds);
destroy_test_context(&context);
}
void test_unknown_dsv_format(void)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12GraphicsCommandList *command_list;
struct depth_stencil_resource ds;
D3D12_CLEAR_VALUE clear_value;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
HRESULT hr;
static const DWORD ps_color_code[] =
{
#if 0
float4 color;
float4 main(float4 position : SV_POSITION) : SV_Target
{
return color;
}
#endif
0x43425844, 0xd18ead43, 0x8b8264c1, 0x9c0a062d, 0xfc843226, 0x00000001, 0x000000e0, 0x00000003,
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050,
0x00000011, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps_color = {ps_color_code, sizeof(ps_color_code)};
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
static const struct vec4 red = {1.0f, 0.0f, 0.0f, 1.0f};
memset(&desc, 0, sizeof(desc));
desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.no_root_signature = true;
if (!init_test_context(&context, &desc))
return;
command_list = context.list;
queue = context.queue;
clear_value.Format = DXGI_FORMAT_D32_FLOAT;
clear_value.DepthStencil.Depth = 0.5f;
clear_value.DepthStencil.Stencil = 0;
init_depth_stencil(&ds, context.device, 32, 32, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, &clear_value);
context.root_signature = create_32bit_constants_root_signature(context.device,
0, 4, D3D12_SHADER_VISIBILITY_PIXEL);
/* DSVFormat = DXGI_FORMAT_UNKNOWN and D3D12_DEPTH_WRITE_MASK_ZERO */
init_pipeline_state_desc(&pso_desc, context.root_signature, desc.rt_format, NULL, &ps_color, NULL);
pso_desc.DSVFormat = DXGI_FORMAT_UNKNOWN;
pso_desc.DepthStencilState.DepthEnable = true;
pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_EQUAL;
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, 0.5f, 0, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.5f, 0.5f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 1.0f, 1.0f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.0f, 0.0f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.55f, 0.55f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, ds.texture,
D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_float(ds.texture, 0, queue, command_list, 0.5f, 1);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
/* DSVFormat = DXGI_FORMAT_UNKNOWN and no DSV */
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, ds.texture,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.0f, 0.0f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.5f, 0.5f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
/* DSVFormat = DXGI_FORMAT_UNKNOWN and D3D12_COMPARISON_FUNC_ALWAYS */
ID3D12PipelineState_Release(context.pipeline_state);
pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.0f, 0.0f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.6f, 0.6f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
/* DSVFormat = DXGI_FORMAT_UNKNOWN and depth write */
ID3D12PipelineState_Release(context.pipeline_state);
pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
D3D12_CLEAR_FLAG_DEPTH, 0.0f, 0, 0, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 1.0f, 1.0f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.6f, 0.6f);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, ds.texture,
D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_float(ds.texture, 0, queue, command_list, 1.0f, 1);
destroy_depth_stencil(&ds);
destroy_test_context(&context);
}
void test_render_a8_dxbc(void)
{
static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
ID3D12GraphicsCommandList *command_list;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
static const DWORD ps_code[] =
{
#if 0
void main(out float4 target : SV_Target)
{
target = float4(0.0f, 0.25f, 0.5f, 1.0f);
}
#endif
0x43425844, 0x2f09e5ff, 0xaa135d5e, 0x7860f4b5, 0x5c7b8cbc, 0x00000001, 0x000000b4, 0x00000003,
0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f,
0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
0x00000000, 0x3e800000, 0x3f000000, 0x3f800000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
memset(&desc, 0, sizeof(desc));
desc.rt_format = DXGI_FORMAT_A8_UNORM;
desc.ps = &ps;
if (!init_test_context(&context, &desc))
return;
command_list = context.list;
queue = context.queue;
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, black, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint8(context.render_target, 0, queue, command_list, 0xff, 0);
destroy_test_context(&context);
}
void test_render_a8_dxil(void)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
ID3D12GraphicsCommandList *command_list;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
ID3D12Device *device;
HRESULT hr;
static const BYTE ps_code_dxil[] =
{
#if 0
void main(out float4 target : SV_Target)
{
target = float4(0.0f, 0.25f, 0.5f, 1.0f);
}
#endif
0x44, 0x58, 0x42, 0x43, 0x21, 0x97, 0x41, 0xc7, 0x9f, 0x1a, 0xed, 0x0b, 0xa5, 0x57, 0x8b, 0x4b, 0xd2, 0x3f, 0xe9, 0x18, 0x01, 0x00, 0x00, 0x00, 0x32, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x50, 0x53, 0x56, 0x30, 0x50, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x44, 0x04, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x2c, 0x04, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81,
0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10,
0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51,
0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1b, 0x88, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0x00, 0x00, 0x49, 0x18,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x82, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13,
0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, 0x23, 0x00, 0x25, 0x00, 0x8a, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x66, 0x00, 0x8a, 0x01, 0x33,
0x43, 0x45, 0x36, 0x10, 0x90, 0x02, 0x03, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d,
0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07,
0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60,
0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76,
0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x81, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09,
0x26, 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x12, 0x18, 0x01, 0x28, 0x84, 0x62, 0x20, 0x2a, 0x89, 0x02, 0x19, 0x01, 0x28, 0x04, 0xca, 0xb1, 0x04, 0x80, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x3e, 0x00,
0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0xc4, 0x88, 0x0c, 0x6f, 0xec, 0xed, 0x4d, 0x0c, 0x44, 0x06, 0x26, 0x26, 0xc7, 0x05, 0xa6, 0xc6, 0x05, 0x06, 0x66, 0x43, 0x10, 0x4c, 0x10,
0x06, 0x61, 0x82, 0x30, 0x0c, 0x1b, 0x84, 0x81, 0x98, 0x20, 0x0c, 0xc4, 0x06, 0x61, 0x30, 0x28, 0xc0, 0xcd, 0x4d, 0x10, 0x86, 0x62, 0xc3, 0x80, 0x24, 0xc4, 0x04, 0x41, 0x00, 0x36, 0x00, 0x1b,
0x06, 0x82, 0x61, 0x36, 0x04, 0xcd, 0x86, 0x61, 0x58, 0x9c, 0x09, 0x42, 0xa2, 0x6c, 0x08, 0x20, 0x12, 0x6d, 0x61, 0x69, 0x6e, 0x4c, 0xa6, 0xac, 0xbe, 0xa8, 0xc2, 0xe4, 0xce, 0xca, 0xe8, 0x26,
0x08, 0x84, 0x31, 0x41, 0x20, 0x8e, 0x0d, 0x01, 0x31, 0x41, 0x20, 0x90, 0x09, 0x02, 0x91, 0x6c, 0x58, 0x88, 0x89, 0xaa, 0xac, 0x6b, 0xc0, 0x88, 0x0b, 0xd8, 0x10, 0x64, 0x1b, 0x06, 0x40, 0x03,
0x36, 0x14, 0x8b, 0xb4, 0x01, 0x40, 0x15, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x29, 0x41, 0x50, 0x85, 0x0c, 0xcf, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x4a,
0x40, 0x34, 0x21, 0xc3, 0x73, 0xb1, 0x0b, 0x63, 0xb3, 0x2b, 0x93, 0x9b, 0x12, 0x18, 0x75, 0xc8, 0xf0, 0x5c, 0xe6, 0xd0, 0xc2, 0xc8, 0xca, 0xe4, 0x9a, 0xde, 0xc8, 0xca, 0xd8, 0xa6, 0x04, 0x49,
0x25, 0x32, 0x3c, 0x17, 0xba, 0x3c, 0xb8, 0xb2, 0x20, 0x37, 0xb7, 0x37, 0xba, 0x30, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x29, 0x81, 0x53, 0x87, 0x0c, 0xcf, 0xc5, 0x2e, 0xad, 0xec, 0x2e, 0x89, 0x6c,
0x8a, 0x2e, 0x8c, 0xae, 0x6c, 0x4a, 0x00, 0xd5, 0x21, 0xc3, 0x73, 0x29, 0x73, 0xa3, 0x93, 0xcb, 0x83, 0x7a, 0x4b, 0x73, 0xa3, 0x9b, 0x9b, 0x12, 0x6c, 0x00, 0x79, 0x18, 0x00, 0x00, 0x42, 0x00,
0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f,
0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d,
0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec,
0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc,
0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87,
0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee,
0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81,
0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c,
0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0x03, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52, 0xd3, 0x43,
0x4d, 0x7e, 0x71, 0xdb, 0x06, 0x40, 0x30, 0x00, 0xd2, 0x00, 0x61, 0x20, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x34, 0xa5,
0x40, 0x54, 0x02, 0x45, 0x50, 0x06, 0x54, 0x23, 0x00, 0x63, 0x04, 0x20, 0x08, 0x82, 0xe8, 0x37, 0x46, 0x00, 0x82, 0x20, 0x08, 0x7f, 0x63, 0x04, 0x20, 0x08, 0x82, 0xf8, 0x07, 0x00, 0x23, 0x06,
0x09, 0x00, 0x82, 0x60, 0x60, 0x48, 0x08, 0x04, 0x2d, 0xc4, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x18, 0x12, 0x02, 0x41, 0xc7, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x84, 0x40, 0x90,
0x21, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0x21, 0x21, 0x10, 0x54, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00,
};
memset(&desc, 0, sizeof(desc));
desc.rt_format = DXGI_FORMAT_A8_UNORM;
desc.no_pipeline = true;
if (!init_test_context(&context, &desc))
return;
if (!context_supports_dxil(&context))
{
destroy_test_context(&context);
return;
}
device = context.device;
command_list = context.list;
queue = context.queue;
init_pipeline_state_desc_dxil(&pso_desc, context.root_signature, 0, NULL, NULL, NULL);
pso_desc.RTVFormats[0] = DXGI_FORMAT_A8_UNORM;
pso_desc.NumRenderTargets = 1;
pso_desc.PS.pShaderBytecode = ps_code_dxil;
pso_desc.PS.BytecodeLength = sizeof(ps_code_dxil);
hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, black, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint8(context.render_target, 0, queue, command_list, 0xff, 0);
destroy_test_context(&context);
}
void test_multisample_rendering(void)
{
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12GraphicsCommandList *command_list;
ID3D12PipelineState *ms_pipeline_state;
D3D12_CPU_DESCRIPTOR_HANDLE ms_rtv;
ID3D12Resource *ms_render_target;
struct test_context_desc desc;
struct test_context context;
ID3D12DescriptorHeap *heap;
ID3D12CommandQueue *queue;
uint32_t sample;
unsigned int i;
HRESULT hr;
static const DWORD ps_color_code[] =
{
#if 0
float4 main(uint id : SV_SampleIndex) : SV_Target
{
switch (id)
{
case 0: return float4(1.0f, 0.0f, 0.0f, 1.0f);
case 1: return float4(0.0f, 1.0f, 0.0f, 1.0f);
case 2: return float4(0.0f, 0.0f, 1.0f, 1.0f);
default: return float4(0.0f, 0.0f, 0.0f, 1.0f);
}
}
#endif
0x43425844, 0x94c35f48, 0x04c6b0f7, 0x407d8214, 0xc24f01e5, 0x00000001, 0x00000194, 0x00000003,
0x0000002c, 0x00000064, 0x00000098, 0x4e475349, 0x00000030, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x0000000a, 0x00000001, 0x00000000, 0x00000101, 0x535f5653, 0x6c706d61, 0x646e4965,
0xab007865, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000f4,
0x00000050, 0x0000003d, 0x0100086a, 0x04000863, 0x00101012, 0x00000000, 0x0000000a, 0x03000065,
0x001020f2, 0x00000000, 0x0300004c, 0x0010100a, 0x00000000, 0x03000006, 0x00004001, 0x00000000,
0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000,
0x0100003e, 0x03000006, 0x00004001, 0x00000001, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, 0x03000006, 0x00004001, 0x00000002,
0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,
0x0100003e, 0x0100000a, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
0x00000000, 0x3f800000, 0x0100003e, 0x01000017, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps_color = {ps_color_code, sizeof(ps_color_code)};
static const DWORD ps_resolve_code[] =
{
#if 0
Texture2DMS<float4> t;
uint sample;
uint rt_size;
float4 main(float4 position : SV_Position) : SV_Target
{
float3 p;
t.GetDimensions(p.x, p.y, p.z);
p *= float3(position.x / rt_size, position.y / rt_size, 0);
return t.Load((int2)p.xy, sample);
}
#endif
0x43425844, 0x68a4590b, 0xc1ec3070, 0x1b957c43, 0x0c080741, 0x00000001, 0x000001c8, 0x00000003,
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000012c, 0x00000050,
0x0000004b, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04002058, 0x00107000,
0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
0x00000000, 0x02000068, 0x00000001, 0x06000056, 0x00100012, 0x00000000, 0x0020801a, 0x00000000,
0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00100006, 0x00000000,
0x8900003d, 0x80000102, 0x00155543, 0x001000c2, 0x00000000, 0x00004001, 0x00000000, 0x001074e6,
0x00000000, 0x07000038, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00100ae6, 0x00000000,
0x0500001b, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x08000036, 0x001000c2, 0x00000000,
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8c00002e, 0x80000102, 0x00155543,
0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0020800a, 0x00000000,
0x00000000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps_resolve = {ps_resolve_code, sizeof(ps_resolve_code)};
static const unsigned int expected_colors[] = {0xff0000ff, 0xff00ff00, 0xffff0000, 0xff000000};
if (use_warp_device)
{
skip("Sample shading tests fail on WARP.\n");
return;
}
memset(&desc, 0, sizeof(desc));
desc.rt_width = desc.rt_height = 32;
desc.rt_descriptor_count = 2;
desc.no_root_signature = true;
if (!init_test_context(&context, &desc))
return;
command_list = context.list;
queue = context.queue;
context.root_signature = create_texture_root_signature(context.device,
D3D12_SHADER_VISIBILITY_PIXEL, 2, 0);
init_pipeline_state_desc(&pso_desc, context.root_signature,
context.render_target_desc.Format, NULL, &ps_resolve, NULL);
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
pso_desc.PS = ps_color;
pso_desc.SampleDesc.Count = 4;
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&ms_pipeline_state);
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
ms_rtv = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
desc.sample_desc.Count = 4;
create_render_target(&context, &desc, &ms_render_target, &ms_rtv);
heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
ID3D12Device_CreateShaderResourceView(context.device, ms_render_target, NULL,
get_cpu_descriptor_handle(&context, heap, 0));
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, ms_rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &ms_rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, ms_pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
get_gpu_descriptor_handle(&context, heap, 0));
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, ms_render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_DEST);
ID3D12GraphicsCommandList_ResolveSubresource(command_list,
context.render_target, 0, ms_render_target, 0, context.render_target_desc.Format);
transition_resource_state(command_list, ms_render_target,
D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff404040, 2);
for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
{
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
get_gpu_descriptor_handle(&context, heap, 0));
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &desc.rt_width, 1);
sample = i;
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &sample, 0);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, command_list, expected_colors[i], 0);
}
ID3D12DescriptorHeap_Release(heap);
ID3D12Resource_Release(ms_render_target);
ID3D12PipelineState_Release(ms_pipeline_state);
destroy_test_context(&context);
}

2559
tests/d3d12_resource.c Normal file

File diff suppressed because it is too large Load Diff

1031
tests/d3d12_robustness.c Normal file

File diff suppressed because it is too large Load Diff

1469
tests/d3d12_root_signature.c Normal file

File diff suppressed because it is too large Load Diff

13801
tests/d3d12_shaders.c Normal file

File diff suppressed because it is too large Load Diff

1795
tests/d3d12_sm_advanced.c Normal file

File diff suppressed because it is too large Load Diff

3373
tests/d3d12_sparse.c Normal file

File diff suppressed because it is too large Load Diff

295
tests/d3d12_streamout.c Normal file
View File

@ -0,0 +1,295 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
static void test_vertex_shader_stream_output(bool use_dxil)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12Resource *counter_buffer, *so_buffer;
ID3D12GraphicsCommandList *command_list;
D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv;
ID3D12Resource *upload_buffer;
struct test_context_desc desc;
struct resource_readback rb;
struct test_context context;
ID3D12CommandQueue *queue;
unsigned int counter, i;
const struct vec4 *data;
ID3D12Device *device;
HRESULT hr;
static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
{
{0, "SV_Position", 0, 0, 4, 0},
};
static const struct vec4 expected_output[] =
{
{-1.0f, 1.0f, 0.0f, 1.0f},
{ 3.0f, 1.0f, 0.0f, 1.0f},
{-1.0f,-3.0f, 0.0f, 1.0f},
};
unsigned int strides[] = {16};
memset(&desc, 0, sizeof(desc));
desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
desc.no_pipeline = true;
if (!init_test_context(&context, &desc))
return;
if (use_dxil && !context_supports_dxil(&context))
{
destroy_test_context(&context);
return;
}
device = context.device;
command_list = context.list;
queue = context.queue;
if (use_dxil)
init_pipeline_state_desc_dxil(&pso_desc, context.root_signature, 0, NULL, NULL, NULL);
else
init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, NULL, NULL);
pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
pso_desc.StreamOutput.pSODeclaration = so_declaration;
pso_desc.StreamOutput.pBufferStrides = strides;
pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM;
hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
if (hr == E_NOTIMPL)
{
skip("Stream output is not supported.\n");
destroy_test_context(&context);
return;
}
ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
counter = 0;
upload_buffer = create_upload_buffer(device, sizeof(counter), &counter);
counter_buffer = create_default_buffer(device, 32,
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
so_buffer = create_default_buffer(device, 1024,
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer);
sobv.SizeInBytes = 1024;
sobv.BufferFilledSizeLocation = ID3D12Resource_GetGPUVirtualAddress(counter_buffer);
ID3D12GraphicsCommandList_CopyBufferRegion(command_list, counter_buffer, 0,
upload_buffer, 0, sizeof(counter));
transition_resource_state(command_list, counter_buffer,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, counter_buffer,
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
transition_resource_state(command_list, so_buffer,
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(counter_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
counter = get_readback_uint(&rb, 0, 0, 0);
ok(counter == 3 * sizeof(struct vec4), "Got unexpected counter %u.\n", counter);
release_resource_readback(&rb);
reset_command_list(command_list, context.allocator);
get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
for (i = 0; i < ARRAY_SIZE(expected_output); ++i)
{
const struct vec4 *expected = &expected_output[i];
data = get_readback_vec4(&rb, i, 0);
ok(compare_vec4(data, expected, 1),
"Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w);
}
release_resource_readback(&rb);
ID3D12Resource_Release(counter_buffer);
ID3D12Resource_Release(upload_buffer);
ID3D12Resource_Release(so_buffer);
destroy_test_context(&context);
}
void test_index_buffer_edge_case_stream_output(void)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12Resource *counter_buffer, *so_buffer;
ID3D12GraphicsCommandList *command_list;
D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv;
ID3D12Resource *upload_buffer;
struct test_context_desc desc;
ID3D12Resource *index_buffer;
struct resource_readback rb;
D3D12_INDEX_BUFFER_VIEW ibv;
struct test_context context;
ID3D12CommandQueue *queue;
unsigned int counter, i;
const struct vec4 *data;
ID3D12Device *device;
HRESULT hr;
static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
{
{0, "SV_Position", 0, 0, 4, 0},
};
static const struct vec4 expected_output[] =
{
{-1.0f, 1.0f, 0.0f, 1.0f},
{ 3.0f, 1.0f, 0.0f, 1.0f},
{-1.0f,-3.0f, 0.0f, 1.0f},
{-1.0f, 1.0f, 0.0f, 1.0f}, /* For the case where we are rendering with NULL index. The first vertex is always picked. */
{-1.0f, 1.0f, 0.0f, 1.0f},
{-1.0f, 1.0f, 0.0f, 1.0f},
{-1.0f, 1.0f, 0.0f, 1.0f}, /* For DrawInstanced with NULL index buffer, which should work just fine. */
{ 3.0f, 1.0f, 0.0f, 1.0f},
{-1.0f,-3.0f, 0.0f, 1.0f},
{-1.0f, 1.0f, 0.0f, 1.0f}, /* For the case where we are rendering with NULL GPU VA for index. */
{-1.0f, 1.0f, 0.0f, 1.0f},
{-1.0f, 1.0f, 0.0f, 1.0f},
{-1.0f,-3.0f, 0.0f, 1.0f}, /* For the case where we are rendering with UNKNOWN index format. It is actually R16_UINT. */
{ 3.0f, 1.0f, 0.0f, 1.0f},
{-1.0f, 1.0f, 0.0f, 1.0f},
};
unsigned int strides[] = {16};
static const uint16_t index_data[3] = { 2, 1, 0 };
memset(&desc, 0, sizeof(desc));
desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
desc.no_pipeline = true;
if (!init_test_context(&context, &desc))
return;
device = context.device;
command_list = context.list;
queue = context.queue;
index_buffer = create_upload_buffer(device, sizeof(index_data), index_data);
init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, NULL, NULL);
pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
pso_desc.StreamOutput.pSODeclaration = so_declaration;
pso_desc.StreamOutput.pBufferStrides = strides;
pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM;
hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
if (hr == E_NOTIMPL)
{
skip("Stream output is not supported.\n");
destroy_test_context(&context);
return;
}
ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
counter = 0;
upload_buffer = create_upload_buffer(device, sizeof(counter), &counter);
counter_buffer = create_default_buffer(device, 32,
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
so_buffer = create_default_buffer(device, 1024,
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer);
sobv.SizeInBytes = 1024;
sobv.BufferFilledSizeLocation = ID3D12Resource_GetGPUVirtualAddress(counter_buffer);
ID3D12GraphicsCommandList_CopyBufferRegion(command_list, counter_buffer, 0,
upload_buffer, 0, sizeof(counter));
transition_resource_state(command_list, counter_buffer,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
/* Should render all 0 indices. */
ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, NULL);
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 3, 1, 1, 1, 0);
/* Should still render. */
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
ibv.BufferLocation = 0;
ibv.Format = DXGI_FORMAT_R32_UINT;
ibv.SizeInBytes = 0;
/* Should render all 0 indices. */
ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 3, 1, 2, 1, 0);
/* This is supposed to be illegal, but works anyways. UNKNOWN is R16_UINT on AMD at least. */
ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(index_buffer);
ibv.Format = DXGI_FORMAT_UNKNOWN;
ibv.SizeInBytes = sizeof(index_data);
ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 3, 1, 0, 0, 0);
transition_resource_state(command_list, counter_buffer,
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
transition_resource_state(command_list, so_buffer,
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(counter_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
counter = get_readback_uint(&rb, 0, 0, 0);
todo ok(counter == 15 * sizeof(struct vec4), "Got unexpected counter %u.\n", counter);
release_resource_readback(&rb);
reset_command_list(command_list, context.allocator);
get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
for (i = 0; i < ARRAY_SIZE(expected_output); ++i)
{
const struct vec4 *expected = &expected_output[i];
data = get_readback_vec4(&rb, i, 0);
todo_if(i >= 4 && i != 7) ok(compare_vec4(data, expected, 1),
"Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w);
}
release_resource_readback(&rb);
ID3D12Resource_Release(counter_buffer);
ID3D12Resource_Release(upload_buffer);
ID3D12Resource_Release(so_buffer);
ID3D12Resource_Release(index_buffer);
destroy_test_context(&context);
}
void test_vertex_shader_stream_output_dxbc(void)
{
test_vertex_shader_stream_output(false);
}
void test_vertex_shader_stream_output_dxil(void)
{
test_vertex_shader_stream_output(true);
}

1196
tests/d3d12_sync.c Normal file

File diff suppressed because it is too large Load Diff

3697
tests/d3d12_tessellation.c Normal file

File diff suppressed because it is too large Load Diff

151
tests/d3d12_va.c Normal file
View File

@ -0,0 +1,151 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
void test_gpu_virtual_address(void)
{
D3D12_GPU_VIRTUAL_ADDRESS vb_offset, ib_offset;
ID3D12GraphicsCommandList *command_list;
D3D12_INPUT_LAYOUT_DESC input_layout;
struct test_context_desc desc;
D3D12_VERTEX_BUFFER_VIEW vbv;
struct test_context context;
D3D12_INDEX_BUFFER_VIEW ibv;
ID3D12CommandQueue *queue;
ID3D12Resource *buffer;
HRESULT hr;
BYTE *ptr;
static const DWORD vs_code[] =
{
#if 0
void main(float4 in_position : POSITION, float4 in_color : COLOR,
out float4 out_position : SV_POSITION, out float4 out_color : COLOR)
{
out_position = in_position;
out_color = in_color;
}
#endif
0x43425844, 0xa58fc911, 0x280038e9, 0x14cfff54, 0xe43fc328, 0x00000001, 0x00000144, 0x00000003,
0x0000002c, 0x0000007c, 0x000000d0, 0x4e475349, 0x00000048, 0x00000002, 0x00000008, 0x00000038,
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000,
0x00000003, 0x00000001, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0x4c4f4300, 0xab00524f, 0x4e47534f,
0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653,
0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x58454853, 0x0000006c, 0x00010050, 0x0000001b,
0x0100086a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067,
0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2,
0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001,
0x0100003e,
};
static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
static const DWORD ps_code[] =
{
#if 0
void main(float4 in_position : SV_POSITION, float4 in_color : COLOR,
out float4 out_color : SV_TARGET)
{
out_color = in_color;
}
#endif
0x43425844, 0x1a6def50, 0x9c069300, 0x7cce68f0, 0x621239b9, 0x00000001, 0x000000f8, 0x00000003,
0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x58454853, 0x0000003c, 0x00000050,
0x0000000f, 0x0100086a, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
static const uint32_t indices[] = {0, 1, 2, 3};
static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
};
static const struct
{
struct vec2 position;
struct vec4 color;
}
quad[] =
{
{{-1.0f, -1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
{{-1.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
{{ 1.0f, -1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
{{ 1.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
};
memset(&desc, 0, sizeof(desc));
desc.no_root_signature = true;
if (!init_test_context(&context, &desc))
return;
command_list = context.list;
queue = context.queue;
context.root_signature = create_empty_root_signature(context.device,
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
input_layout.pInputElementDescs = layout_desc;
input_layout.NumElements = ARRAY_SIZE(layout_desc);
context.pipeline_state = create_pipeline_state(context.device,
context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
vb_offset = 0x200;
ib_offset = 0x500;
buffer = create_upload_buffer(context.device, ib_offset + sizeof(indices), NULL);
hr = ID3D12Resource_Map(buffer, 0, NULL, (void **)&ptr);
ok(SUCCEEDED(hr), "Failed to map upload buffer, hr %#x.\n", hr);
memcpy(ptr + vb_offset, quad, sizeof(quad));
memcpy(ptr + ib_offset, indices, sizeof(indices));
ID3D12Resource_Unmap(buffer, 0, NULL);
vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(buffer) + vb_offset;
vbv.StrideInBytes = sizeof(*quad);
vbv.SizeInBytes = sizeof(quad);
ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(buffer) + ib_offset;
ibv.SizeInBytes = sizeof(indices);
ibv.Format = DXGI_FORMAT_R32_UINT;
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 4, 1, 0, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
ID3D12Resource_Release(buffer);
destroy_test_context(&context);
}

905
tests/d3d12_vrs.c Normal file
View File

@ -0,0 +1,905 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
void test_vrs(void)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12GraphicsCommandList5 *command_list;
bool additional_shading_rates_supported;
ID3D12PipelineState *pipeline_state = NULL;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
unsigned int i;
HRESULT hr;
#if 0
void main(in float4 vPos : SV_POSITION, out float4 o0 : SV_Target0)
{
o0 = float4(ddx(vPos.x) / 255.0, ddy(vPos.y) / 255.0, 0.0, 0.0);
}
#endif
static const DWORD ps_code_dxbc[] =
{
0x43425844, 0x1cf58366, 0x02883b19, 0xd5e18634, 0xeea3d29b, 0x00000001, 0x00000150, 0x00000003,
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000b4, 0x00000050,
0x0000002d, 0x0100086a, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
0x00000000, 0x02000068, 0x00000001, 0x0500007a, 0x00100012, 0x00000000, 0x0010100a, 0x00000000,
0x07000038, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3b808081, 0x0500007c,
0x00100012, 0x00000000, 0x0010101a, 0x00000000, 0x07000038, 0x00102022, 0x00000000, 0x0010000a,
0x00000000, 0x00004001, 0x3b808081, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x0100003e,
};
const D3D12_SHADER_BYTECODE ps = {
(const void*)ps_code_dxbc,
sizeof(ps_code_dxbc)
};
static const struct
{
D3D12_SHADING_RATE shading_rate;
D3D12_SHADING_RATE_COMBINER combiners[2];
unsigned int expected_color;
bool additional_shading_rate;
}
tests[] =
{
{D3D12_SHADING_RATE_1X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000101},
{D3D12_SHADING_RATE_1X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000201},
{D3D12_SHADING_RATE_2X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000102},
{D3D12_SHADING_RATE_2X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000202},
{D3D12_SHADING_RATE_2X4, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000402, true},
{D3D12_SHADING_RATE_4X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000204, true},
{D3D12_SHADING_RATE_4X4, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000404, true},
};
memset(&desc, 0, sizeof(desc));
if (!init_test_context(&context, &desc))
return;
if (!is_vrs_tier1_supported(context.device, &additional_shading_rates_supported))
{
skip("VariableRateShading not supported.\n");
destroy_test_context(&context);
return;
}
hr = ID3D12GraphicsCommandList_QueryInterface(context.list, &IID_ID3D12GraphicsCommandList5, (void **)&command_list);
ok(hr == S_OK, "Couldn't get GraphicsCommandList5, hr %#x.\n", hr);
ID3D12GraphicsCommandList5_Release(command_list);
queue = context.queue;
init_pipeline_state_desc(&pso_desc, context.root_signature,
context.render_target_desc.Format, NULL, &ps, NULL);
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&pipeline_state);
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
vkd3d_test_set_context("Test %u", i);
if (!additional_shading_rates_supported)
{
skip("Skipped test %u, AdditionalShadingRates not supported.\n");
continue;
}
ID3D12GraphicsCommandList5_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList5_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList5_SetPipelineState(command_list, pipeline_state);
ID3D12GraphicsCommandList5_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList5_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList5_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList5_RSSetShadingRate(command_list, tests[i].shading_rate, tests[i].combiners);
ID3D12GraphicsCommandList5_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(context.list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, context.list, tests[i].expected_color, 0);
reset_command_list(context.list, context.allocator);
transition_resource_state(context.list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
vkd3d_test_set_context(NULL);
if (pipeline_state)
ID3D12PipelineState_Release(pipeline_state);
destroy_test_context(&context);
}
void test_vrs_dxil(void)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12GraphicsCommandList5 *command_list;
ID3D12PipelineState *pipeline_state = NULL;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
unsigned int i;
HRESULT hr;
#if 0
void main(uint id : SV_VertexID, out uint shading_rate : SV_ShadingRate, out float4 position : SV_Position)
{
shading_rate = 0x1; // 1x2
float2 coords = float2((id << 1) & 2, id & 2);
position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);
}
#endif
static const BYTE vs_code_dxil[] =
{
0x44, 0x58, 0x42, 0x43, 0x85, 0xd5, 0x9c, 0x59, 0x67, 0x32, 0x49, 0x5a,
0x01, 0x03, 0xb0, 0xf0, 0x4b, 0x22, 0x08, 0xdc, 0x01, 0x00, 0x00, 0x00,
0x3f, 0x0c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x4c, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00,
0x7b, 0x01, 0x00, 0x00, 0xb7, 0x06, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x00,
0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x56, 0x65, 0x72, 0x74, 0x65,
0x78, 0x49, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x63, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x53, 0x56, 0x5f, 0x53, 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x61,
0x74, 0x65, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x00, 0x50, 0x53, 0x56, 0x30, 0x80, 0x00, 0x00, 0x00, 0x24,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x41, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x1d, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x44, 0x03, 0x03,
0x04, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, 0x34,
0x05, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x4d, 0x01, 0x00, 0x00, 0x44,
0x58, 0x49, 0x4c, 0x04, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1c,
0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x44,
0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84,
0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48,
0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x01,
0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
0x82, 0x60, 0x42, 0x20, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x11,
0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x3c, 0x23, 0x00, 0x25,
0x00, 0x8a, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x8a, 0x31, 0x33, 0x43,
0x43, 0x55, 0x0c, 0x98, 0x19, 0x1a, 0xba, 0x19, 0x80, 0x62, 0xc0, 0xcc,
0x50, 0x92, 0x0e, 0x04, 0xe4, 0xc0, 0xcc, 0x11, 0x80, 0x02, 0x00, 0x13,
0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68,
0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a,
0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d,
0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71,
0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72,
0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a,
0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73,
0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72,
0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d,
0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72,
0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x05, 0x10, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x0e, 0x20, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x28, 0x40,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x05, 0x02,
0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19,
0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x12,
0x28, 0x84, 0x11, 0x80, 0x62, 0x28, 0x83, 0xf2, 0x28, 0x90, 0x52, 0x20,
0x2a, 0x85, 0x12, 0x18, 0x01, 0x28, 0x9d, 0x92, 0x28, 0x83, 0x42, 0x20,
0x2f, 0x40, 0x40, 0x40, 0x08, 0xea, 0xb1, 0x86, 0x00, 0x81, 0x03, 0x00,
0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1a,
0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73,
0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71,
0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a,
0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b,
0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0x81, 0x98, 0x20, 0x0c, 0xc5,
0x06, 0x61, 0x20, 0x26, 0x08, 0x83, 0xb1, 0x41, 0x30, 0x0c, 0x0a, 0x76,
0x73, 0x13, 0x84, 0xe1, 0xd8, 0x30, 0x20, 0x09, 0x31, 0x41, 0x10, 0x80,
0x0d, 0xc0, 0x86, 0xc1, 0x60, 0x98, 0x0d, 0x41, 0xb3, 0x61, 0x18, 0x16,
0x67, 0x82, 0xd0, 0x50, 0x1b, 0x02, 0x88, 0x44, 0x5b, 0x58, 0x9a, 0x1b,
0x97, 0x29, 0xab, 0x2f, 0xab, 0x32, 0x39, 0xba, 0x32, 0xbc, 0x24, 0xa2,
0x09, 0x02, 0xc1, 0x4c, 0x10, 0x88, 0x66, 0x43, 0x60, 0x4c, 0x10, 0x08,
0x67, 0x82, 0x30, 0x20, 0x1b, 0x04, 0x6c, 0xd8, 0xb0, 0x18, 0x13, 0x55,
0x59, 0xd7, 0x50, 0x19, 0x57, 0xb6, 0x21, 0xd0, 0xe8, 0x4c, 0x59, 0x7d,
0x4d, 0xa1, 0x85, 0x91, 0xa5, 0xb9, 0x9d, 0x49, 0x85, 0xd1, 0x95, 0x4d,
0x10, 0x88, 0x67, 0xc3, 0x62, 0x70, 0x54, 0x67, 0x55, 0x43, 0x65, 0x5c,
0x19, 0x97, 0x29, 0xab, 0x2f, 0xa8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37,
0xb7, 0x09, 0x02, 0x01, 0x4d, 0x10, 0x88, 0x68, 0x82, 0x40, 0x48, 0x13,
0x84, 0x21, 0xd9, 0x20, 0x60, 0x63, 0xb0, 0x61, 0x19, 0x3e, 0x30, 0x08,
0x03, 0x4b, 0x0c, 0x06, 0x31, 0x18, 0x2e, 0x32, 0xd8, 0x20, 0x78, 0x65,
0xb0, 0x61, 0xd8, 0xcc, 0x00, 0x98, 0x20, 0x38, 0xd3, 0x06, 0xc1, 0x40,
0x83, 0x0d, 0xc5, 0x22, 0x9d, 0x01, 0x90, 0x06, 0x34, 0xcc, 0xd8, 0xde,
0xc2, 0xe8, 0xe6, 0x58, 0xa4, 0xb9, 0xcd, 0xd1, 0xcd, 0x4d, 0x10, 0x06,
0x85, 0xc6, 0x5c, 0xda, 0xd9, 0x17, 0x1b, 0x19, 0x8d, 0xb9, 0xb4, 0xb3,
0xaf, 0x39, 0xba, 0x09, 0xc2, 0xb0, 0xb0, 0xa8, 0x4b, 0x73, 0xa3, 0x9b,
0xdb, 0xa0, 0xac, 0x41, 0xc2, 0x06, 0x6d, 0xe0, 0x06, 0xc3, 0x1b, 0xc0,
0x41, 0x1c, 0x60, 0x55, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8, 0xca,
0xdc, 0xe8, 0xa6, 0x04, 0x41, 0x15, 0x32, 0x3c, 0x17, 0xbb, 0x32, 0xb9,
0xb9, 0xb4, 0x37, 0xb7, 0x29, 0x01, 0xd1, 0x84, 0x0c, 0xcf, 0xc5, 0x2e,
0x8c, 0xcd, 0xae, 0x4c, 0x6e, 0x4a, 0x60, 0xd4, 0x21, 0xc3, 0x73, 0x99,
0x43, 0x0b, 0x23, 0x2b, 0x93, 0x6b, 0x7a, 0x23, 0x2b, 0x63, 0x9b, 0x12,
0x24, 0x95, 0xc8, 0xf0, 0x5c, 0xe8, 0xf2, 0xe0, 0xca, 0x82, 0xdc, 0xdc,
0xde, 0xe8, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0xa6, 0x04, 0x4e, 0x1d,
0x32, 0x3c, 0x17, 0xbb, 0xb4, 0xb2, 0xbb, 0x24, 0xb2, 0x29, 0xba, 0x30,
0xba, 0xb2, 0x29, 0x01, 0x54, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e,
0x2e, 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0x90, 0x06, 0x5d,
0xc8, 0xf0, 0x5c, 0xc6, 0xde, 0xea, 0xdc, 0xe8, 0xca, 0xe4, 0xe6, 0xa6,
0x04, 0x71, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33,
0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43,
0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98,
0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33,
0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05,
0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43,
0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08,
0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78,
0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1,
0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33,
0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e,
0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03,
0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60,
0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80,
0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8,
0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18,
0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee,
0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c,
0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c,
0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43,
0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3,
0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83,
0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21,
0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1,
0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6,
0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4,
0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16,
0x30, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0xe2, 0x00, 0x83, 0xd8, 0x3c, 0xd4,
0xe4, 0x23, 0xb7, 0x6d, 0x03, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93,
0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x02, 0xd5,
0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4,
0xe4, 0x23, 0xb7, 0x6d, 0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xa3, 0x37, 0x5b, 0x4b, 0x55, 0x51, 0xd0, 0xf7, 0x03,
0x00, 0x09, 0x7e, 0x48, 0xdb, 0xec, 0x8c, 0x44, 0x58, 0x49, 0x4c, 0x64,
0x05, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x59, 0x01, 0x00, 0x00, 0x44,
0x58, 0x49, 0x4c, 0x04, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x4c,
0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x50,
0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84,
0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48,
0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x01,
0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
0x82, 0x60, 0x42, 0x20, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x11,
0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x3c, 0x23, 0x00, 0x25,
0x00, 0x8a, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x8a, 0x31, 0x33, 0x43,
0x43, 0x55, 0x0c, 0x98, 0x19, 0x1a, 0xba, 0x19, 0x80, 0x62, 0xc0, 0xcc,
0x50, 0x92, 0x0e, 0x04, 0xe4, 0xc0, 0xcc, 0x11, 0x80, 0x02, 0x00, 0x13,
0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68,
0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a,
0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d,
0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71,
0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72,
0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a,
0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73,
0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72,
0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d,
0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72,
0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x05, 0x10, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x0e, 0x20, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x28, 0x40,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x05, 0x02,
0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19,
0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x12,
0x28, 0x84, 0x62, 0x18, 0x01, 0x28, 0x83, 0xf2, 0x20, 0x2a, 0x85, 0x12,
0x18, 0x01, 0x28, 0x9d, 0x92, 0x28, 0x83, 0x42, 0x20, 0x2f, 0x40, 0x40,
0x40, 0x08, 0xea, 0xb1, 0x86, 0x00, 0x81, 0x03, 0x00, 0x00, 0x00, 0x79,
0x18, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46,
0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b,
0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1,
0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa,
0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10,
0x04, 0x13, 0x84, 0x81, 0x98, 0x20, 0x0c, 0xc5, 0x06, 0x61, 0x20, 0x26,
0x08, 0x83, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x76, 0x73, 0x1b, 0x06, 0xc4,
0x20, 0x26, 0x08, 0x8d, 0xb4, 0x21, 0x50, 0x26, 0x08, 0x02, 0x40, 0xa2,
0x2d, 0x2c, 0xcd, 0x6d, 0x82, 0x30, 0x1c, 0x5c, 0xa6, 0xac, 0xbe, 0xac,
0xca, 0xe4, 0xe8, 0xca, 0xf0, 0x92, 0x88, 0x26, 0x08, 0x84, 0x32, 0x41,
0x20, 0x96, 0x0d, 0x81, 0x33, 0x41, 0x20, 0x98, 0x09, 0xc2, 0x80, 0x6c,
0x10, 0xa8, 0x61, 0xc3, 0xe2, 0x3c, 0x50, 0x24, 0x4d, 0x43, 0xe4, 0x4c,
0xd5, 0x86, 0xc0, 0xa2, 0x33, 0x65, 0xf5, 0x35, 0x85, 0x16, 0x46, 0x96,
0xe6, 0x76, 0x26, 0x15, 0x46, 0x57, 0x36, 0x41, 0x20, 0x9a, 0x0d, 0x8b,
0x83, 0x41, 0x99, 0x14, 0x0d, 0x91, 0x33, 0x55, 0x5c, 0xa6, 0xac, 0xbe,
0xa0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, 0xdc, 0x26, 0x08, 0x84, 0x33,
0x41, 0x20, 0x9e, 0x09, 0x02, 0x01, 0x4d, 0x10, 0x86, 0x64, 0x83, 0x40,
0x7d, 0x1b, 0x96, 0x61, 0xe3, 0x3a, 0xc9, 0x1b, 0xbc, 0x61, 0x02, 0x83,
0x0d, 0x82, 0x16, 0x06, 0x1b, 0x86, 0x4b, 0x0c, 0x80, 0x09, 0x82, 0x13,
0x6d, 0x10, 0x1c, 0x32, 0xd8, 0x50, 0x30, 0xcd, 0x18, 0x00, 0x65, 0x50,
0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a,
0x10, 0x54, 0x21, 0xc3, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73,
0x9b, 0x12, 0x10, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca,
0xe4, 0xa6, 0x04, 0x46, 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2,
0x32, 0xb9, 0xa6, 0x37, 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x87, 0x0c,
0xcf, 0xc5, 0x2e, 0xad, 0xec, 0x2e, 0x89, 0x6c, 0x8a, 0x2e, 0x8c, 0xae,
0x6c, 0x4a, 0xa0, 0xd4, 0x21, 0xc3, 0x73, 0x29, 0x73, 0xa3, 0x93, 0xcb,
0x83, 0x7a, 0x4b, 0x73, 0xa3, 0x9b, 0x9b, 0x12, 0x94, 0x01, 0x00, 0x79,
0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4,
0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c,
0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00,
0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2,
0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38,
0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d,
0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87,
0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87,
0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30,
0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde,
0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b,
0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c,
0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07,
0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87,
0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87,
0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87,
0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0,
0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc,
0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4,
0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39,
0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38,
0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b,
0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03,
0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0,
0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0,
0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71,
0x20, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16, 0x30, 0x0d, 0x97, 0xef,
0x3c, 0xfe, 0xe2, 0x00, 0x83, 0xd8, 0x3c, 0xd4, 0xe4, 0x23, 0xb7, 0x6d,
0x03, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35,
0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x02, 0xd5, 0x70, 0xf9, 0xce, 0xe3,
0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, 0xe4, 0x23, 0xb7, 0x6d,
0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x26,
0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x34, 0xa5, 0x50, 0x04, 0x33, 0x00, 0x44, 0x45, 0x40,
0x39, 0x46, 0x00, 0x82, 0x20, 0x08, 0x82, 0xc1, 0x18, 0x01, 0x08, 0x82,
0x20, 0xfe, 0x8d, 0x11, 0x80, 0x20, 0x08, 0xe2, 0xbf, 0x30, 0x02, 0x00,
0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x50, 0x68, 0x16,
0x45, 0x3d, 0xc6, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x1c, 0x5a, 0x52,
0x55, 0x10, 0x56, 0x01, 0x76, 0x15, 0x24, 0x7a, 0x41, 0x56, 0x11, 0x8b,
0x5e, 0x90, 0x65, 0x83, 0x22, 0x1f, 0x13, 0x16, 0xf9, 0x98, 0xa0, 0xc0,
0xc7, 0x18, 0x21, 0x3e, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0xa0, 0x88,
0x81, 0x14, 0x06, 0x5e, 0x26, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81,
0x22, 0x06, 0x52, 0x18, 0x78, 0x5a, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08,
0x06, 0x8a, 0x18, 0x48, 0x61, 0xe0, 0x3d, 0xcb, 0x88, 0x41, 0x02, 0x80,
0x20, 0x18, 0x28, 0x62, 0x20, 0x85, 0x81, 0x67, 0x35, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00
};
const D3D12_SHADER_BYTECODE vs = {
(const void*)vs_code_dxil,
sizeof(vs_code_dxil)
};
#if 0
void main(in uint shading_rate : SV_ShadingRate, out float4 o0 : SV_Target0)
{
const uint D3D12_SHADING_RATE_VALID_MASK = 0x3;
const uint D3D12_SHADING_RATE_X_AXIS_SHIFT = 2;
o0 = float4(
((shading_rate >> D3D12_SHADING_RATE_X_AXIS_SHIFT) & D3D12_SHADING_RATE_VALID_MASK) / 255.0,
(shading_rate & D3D12_SHADING_RATE_VALID_MASK) / 255.0,
0.0,
0.0);
}
#endif
static const BYTE ps_code_dxil[] =
{
0x44, 0x58, 0x42, 0x43, 0xa3, 0x20, 0x80, 0x72, 0xdd, 0x03, 0x63, 0xab,
0xf7, 0x83, 0xd8, 0xdf, 0xa9, 0xf5, 0xfc, 0x85, 0x01, 0x00, 0x00, 0x00,
0x59, 0x0b, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x4c, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00,
0x3d, 0x01, 0x00, 0x00, 0x35, 0x06, 0x00, 0x00, 0x51, 0x06, 0x00, 0x00,
0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x37, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x53, 0x68, 0x61, 0x64, 0x69,
0x6e, 0x67, 0x52, 0x61, 0x74, 0x65, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61,
0x72, 0x67, 0x65, 0x74, 0x00, 0x50, 0x53, 0x56, 0x30, 0x70, 0x00, 0x00,
0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x41, 0x1d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, 0xf0, 0x04, 0x00,
0x00, 0x64, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49,
0x4c, 0x04, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xd8, 0x04, 0x00,
0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x33, 0x01, 0x00,
0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32,
0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b,
0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32,
0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14,
0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e,
0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5,
0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8,
0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x01, 0x00, 0x00,
0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60,
0x42, 0x20, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00,
0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, 0xa4,
0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x88,
0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x34, 0x23, 0x00, 0x25, 0x00, 0x8a,
0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x8a, 0x31, 0x33, 0x43, 0x43, 0x35,
0x03, 0x50, 0x0c, 0x98, 0x19, 0x3a, 0xc2, 0x81, 0x80, 0x1c, 0x98, 0x39,
0x02, 0x50, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60,
0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf,
0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a,
0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71,
0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73,
0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72,
0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d,
0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6,
0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73,
0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74,
0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71,
0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43,
0x9e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x86, 0x3c, 0x05, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc8, 0x02, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98,
0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43,
0x9a, 0x12, 0x28, 0x84, 0x11, 0x80, 0x62, 0x28, 0x83, 0xf2, 0x28, 0x0d,
0xa2, 0x52, 0x28, 0x9d, 0x12, 0x18, 0x01, 0x28, 0x89, 0x02, 0x29, 0x04,
0xe2, 0x02, 0x04, 0x04, 0x84, 0xa0, 0x1d, 0x6b, 0x08, 0x88, 0x01, 0x00,
0x00, 0x79, 0x18, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c,
0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03,
0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01,
0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a,
0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b,
0xd9, 0x10, 0x04, 0x13, 0x84, 0x61, 0x98, 0x20, 0x0c, 0xc4, 0x06, 0x61,
0x20, 0x26, 0x08, 0x43, 0xb1, 0x41, 0x30, 0x0c, 0x0a, 0x70, 0x73, 0x13,
0x84, 0xc1, 0xd8, 0x30, 0x20, 0x09, 0x31, 0x41, 0x10, 0x80, 0x0d, 0xc0,
0x86, 0xc1, 0x60, 0x98, 0x0d, 0x41, 0xb3, 0x61, 0x18, 0x16, 0x67, 0x82,
0xb0, 0x48, 0x1b, 0x02, 0x88, 0x44, 0x5b, 0x58, 0x9a, 0x1b, 0x9d, 0x29,
0xab, 0xaf, 0x29, 0xb4, 0x30, 0xb2, 0x34, 0xb7, 0x33, 0xa9, 0x30, 0xba,
0xb2, 0x09, 0x02, 0xa1, 0x4c, 0x10, 0x88, 0x65, 0x43, 0x60, 0x4c, 0x10,
0x08, 0x66, 0x82, 0x40, 0x34, 0x13, 0x84, 0xe1, 0xd8, 0x20, 0x64, 0xc3,
0x86, 0xc5, 0x98, 0xa8, 0xca, 0xba, 0x86, 0xcb, 0xc0, 0xb4, 0x0d, 0xc1,
0xc6, 0x64, 0xca, 0xea, 0x8b, 0x2a, 0x4c, 0xee, 0xac, 0x8c, 0x6e, 0x82,
0x40, 0x38, 0x13, 0x04, 0xe2, 0x99, 0x20, 0x10, 0xd0, 0x04, 0x61, 0x40,
0x36, 0x08, 0x59, 0x18, 0x6c, 0x58, 0x8c, 0xce, 0xfb, 0x2c, 0x6c, 0x00,
0x03, 0x03, 0x13, 0x83, 0x0d, 0xc1, 0x18, 0x6c, 0x18, 0x38, 0x32, 0x00,
0x26, 0x08, 0x4c, 0xb4, 0x41, 0x30, 0xcc, 0x60, 0x43, 0xb1, 0x48, 0x65,
0x00, 0x9c, 0x01, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0xba, 0x39, 0x16, 0x69,
0x6e, 0x73, 0x74, 0x73, 0x13, 0x84, 0x21, 0xa1, 0x31, 0x97, 0x76, 0xf6,
0xc5, 0x46, 0x46, 0x63, 0x2e, 0xed, 0xec, 0x6b, 0x8e, 0x8e, 0x45, 0x5d,
0x9a, 0x1b, 0xdd, 0xdc, 0x06, 0x25, 0x0d, 0x08, 0x35, 0x58, 0x03, 0x36,
0x18, 0xda, 0x80, 0x70, 0x83, 0xac, 0x0a, 0x1b, 0x9b, 0x5d, 0x9b, 0x4b,
0x1a, 0x59, 0x99, 0x1b, 0xdd, 0x94, 0x20, 0xa8, 0x42, 0x86, 0xe7, 0x62,
0x57, 0x26, 0x37, 0x97, 0xf6, 0xe6, 0x36, 0x25, 0x20, 0x9a, 0x90, 0xe1,
0xb9, 0xd8, 0x85, 0xb1, 0xd9, 0x95, 0xc9, 0x4d, 0x09, 0x8c, 0x3a, 0x64,
0x78, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65,
0x6c, 0x53, 0x82, 0xa4, 0x12, 0x19, 0x9e, 0x0b, 0x5d, 0x1e, 0x5c, 0x59,
0x90, 0x9b, 0xdb, 0x1b, 0x5d, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0xdc, 0x94,
0xc0, 0xa9, 0x43, 0x86, 0xe7, 0x62, 0x97, 0x56, 0x76, 0x97, 0x44, 0x36,
0x45, 0x17, 0x46, 0x57, 0x36, 0x25, 0x80, 0xea, 0x90, 0xe1, 0xb9, 0x94,
0xb9, 0xd1, 0xc9, 0xe5, 0x41, 0xbd, 0xa5, 0xb9, 0xd1, 0xcd, 0x4d, 0x09,
0xce, 0xa0, 0x0b, 0x19, 0x9e, 0xcb, 0xd8, 0x5b, 0x9d, 0x1b, 0x5d, 0x99,
0xdc, 0xdc, 0x94, 0xc0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00,
0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c,
0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80,
0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed,
0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d,
0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83,
0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78,
0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70,
0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc,
0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3,
0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c,
0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83,
0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03,
0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68,
0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60,
0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80,
0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98,
0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec,
0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c,
0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d,
0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43,
0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03,
0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03,
0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28,
0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4,
0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1,
0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00,
0x00, 0x0b, 0x00, 0x00, 0x00, 0x16, 0x30, 0x0d, 0x97, 0xef, 0x3c, 0xfe,
0xe2, 0x00, 0x83, 0xd8, 0x3c, 0xd4, 0xe4, 0x23, 0xb7, 0x6d, 0x02, 0xd5,
0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4,
0xe4, 0x17, 0xb7, 0x6d, 0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xd2, 0x28, 0x6f, 0x23, 0xe2, 0xd1,
0x35, 0x09, 0x66, 0x7e, 0x72, 0x05, 0x2e, 0xab, 0x7f, 0x44, 0x58, 0x49,
0x4c, 0x00, 0x05, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
0x00, 0x44, 0x58, 0x49, 0x4c, 0x04, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
0x00, 0xe8, 0x04, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00,
0x00, 0x37, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00,
0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04,
0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08,
0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b,
0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42,
0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32,
0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81,
0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00,
0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff,
0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03,
0x20, 0x01, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00,
0x00, 0x10, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85,
0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90,
0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x34, 0x23,
0x00, 0x25, 0x00, 0x8a, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x8a, 0x31,
0x33, 0x43, 0x43, 0x35, 0x03, 0x50, 0x0c, 0x98, 0x19, 0x3a, 0xc2, 0x81,
0x80, 0x1c, 0x98, 0x39, 0x02, 0x50, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72,
0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72,
0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e,
0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07,
0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07,
0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07,
0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07,
0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07,
0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06,
0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e,
0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07,
0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x05, 0x10, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x0d, 0x00, 0x00,
0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26,
0x47, 0xc6, 0x04, 0x43, 0x9a, 0x12, 0x28, 0x84, 0x62, 0x18, 0x01, 0x28,
0x83, 0xf2, 0x20, 0x2a, 0x85, 0xd2, 0x29, 0x81, 0x11, 0x80, 0x92, 0x28,
0x90, 0x42, 0x20, 0x2e, 0x40, 0x40, 0x40, 0x08, 0xda, 0xb1, 0x86, 0x80,
0x18, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00,
0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63,
0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03,
0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a,
0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b,
0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0x61, 0x98, 0x20,
0x0c, 0xc4, 0x06, 0x61, 0x20, 0x26, 0x08, 0x43, 0xb1, 0x41, 0x18, 0x0c,
0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x4b, 0xb4, 0x21,
0x50, 0x26, 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x6d, 0x82, 0x30,
0x18, 0x74, 0xa6, 0xac, 0xbe, 0xa6, 0xd0, 0xc2, 0xc8, 0xd2, 0xdc, 0xce,
0xa4, 0xc2, 0xe8, 0xca, 0x26, 0x08, 0x44, 0x32, 0x41, 0x20, 0x94, 0x0d,
0x81, 0x33, 0x41, 0x20, 0x96, 0x09, 0x02, 0xc1, 0x4c, 0x10, 0x86, 0x63,
0x83, 0x50, 0x0d, 0x1b, 0x16, 0xe7, 0x81, 0x22, 0x69, 0x1a, 0x26, 0x87,
0xb2, 0x36, 0x04, 0x17, 0x93, 0x29, 0xab, 0x2f, 0xaa, 0x30, 0xb9, 0xb3,
0x32, 0xba, 0x09, 0x02, 0xd1, 0x4c, 0x10, 0x08, 0x67, 0x82, 0x40, 0x3c,
0x13, 0x84, 0x01, 0xd9, 0x20, 0x54, 0xdd, 0x86, 0xc5, 0xc9, 0xb4, 0x4d,
0xa2, 0x06, 0xce, 0xa1, 0xbc, 0x0d, 0xc1, 0xb7, 0x61, 0xc0, 0xc0, 0x00,
0x98, 0x20, 0x30, 0xd0, 0x06, 0xc1, 0x11, 0x83, 0x0d, 0x05, 0xd3, 0x84,
0x01, 0x30, 0x06, 0x55, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8, 0xca,
0xdc, 0xe8, 0xa6, 0x04, 0x41, 0x15, 0x32, 0x3c, 0x17, 0xbb, 0x32, 0xb9,
0xb9, 0xb4, 0x37, 0xb7, 0x29, 0x01, 0xd1, 0x84, 0x0c, 0xcf, 0xc5, 0x2e,
0x8c, 0xcd, 0xae, 0x4c, 0x6e, 0x4a, 0x60, 0xd4, 0x21, 0xc3, 0x73, 0x99,
0x43, 0x0b, 0x23, 0x2b, 0x93, 0x6b, 0x7a, 0x23, 0x2b, 0x63, 0x9b, 0x12,
0x20, 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92, 0xc8, 0xa6,
0xe8, 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x4a, 0x1d, 0x32, 0x3c, 0x97, 0x32,
0x37, 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, 0xb9, 0x29, 0xc1,
0x18, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00,
0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d,
0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07,
0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80,
0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66,
0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d,
0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07,
0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03,
0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90,
0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50,
0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2,
0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39,
0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14,
0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07,
0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07,
0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87,
0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0,
0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8,
0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc,
0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6,
0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39,
0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f,
0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c,
0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87,
0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0,
0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50,
0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0b, 0x00, 0x00,
0x00, 0x16, 0x30, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0xe2, 0x00, 0x83, 0xd8,
0x3c, 0xd4, 0xe4, 0x23, 0xb7, 0x6d, 0x02, 0xd5, 0x70, 0xf9, 0xce, 0xe3,
0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x6d,
0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00,
0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0xa5, 0x30, 0x03, 0x50, 0x04, 0x44,
0x45, 0x50, 0x06, 0x74, 0x63, 0x04, 0x21, 0x09, 0x86, 0x78, 0x37, 0x02,
0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x50, 0x60, 0xd5, 0x34, 0x35,
0x46, 0x05, 0x06, 0x56, 0x40, 0xe9, 0x05, 0x57, 0x16, 0x18, 0xf2, 0xa9,
0xe2, 0xd2, 0x0b, 0xae, 0x2c, 0x48, 0xe4, 0x33, 0x62, 0x90, 0x00, 0x20,
0x08, 0x06, 0xc8, 0xf7, 0x6c, 0x5b, 0x45, 0x8c, 0x18, 0x24, 0x00, 0x08,
0x82, 0x01, 0xf2, 0x3d, 0xdb, 0x66, 0x05, 0x23, 0x06, 0x09, 0x00, 0x82,
0x60, 0x80, 0x7c, 0xcf, 0xb6, 0x31, 0xc9, 0x88, 0x41, 0x02, 0x80, 0x20,
0x18, 0x20, 0xdf, 0xb3, 0x6d, 0x4b, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
};
const D3D12_SHADER_BYTECODE ps = {
(const void*)ps_code_dxil,
sizeof(ps_code_dxil)
};
static const struct
{
D3D12_SHADING_RATE shading_rate;
D3D12_SHADING_RATE_COMBINER combiners[2];
unsigned int expected_color;
}
tests[] =
{
{D3D12_SHADING_RATE_1X1, {D3D12_SHADING_RATE_COMBINER_MAX, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_1X2, {D3D12_SHADING_RATE_COMBINER_MAX, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_2X1, {D3D12_SHADING_RATE_COMBINER_MAX, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000101},
{D3D12_SHADING_RATE_2X2, {D3D12_SHADING_RATE_COMBINER_MAX, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000101},
{D3D12_SHADING_RATE_1X1, {D3D12_SHADING_RATE_COMBINER_MIN, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000000},
{D3D12_SHADING_RATE_1X2, {D3D12_SHADING_RATE_COMBINER_MIN, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_2X1, {D3D12_SHADING_RATE_COMBINER_MIN, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000000},
{D3D12_SHADING_RATE_2X2, {D3D12_SHADING_RATE_COMBINER_MIN, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_1X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000000},
{D3D12_SHADING_RATE_1X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_2X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000001},
{D3D12_SHADING_RATE_2X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000101},
{D3D12_SHADING_RATE_1X1, {D3D12_SHADING_RATE_COMBINER_OVERRIDE, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_1X2, {D3D12_SHADING_RATE_COMBINER_OVERRIDE, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_2X1, {D3D12_SHADING_RATE_COMBINER_OVERRIDE, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
{D3D12_SHADING_RATE_2X2, {D3D12_SHADING_RATE_COMBINER_OVERRIDE, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000100},
};
memset(&desc, 0, sizeof(desc));
if (!init_test_context(&context, &desc))
return;
if (!context_supports_dxil(&context))
{
destroy_test_context(&context);
return;
}
if (!is_vrs_tier2_supported(context.device))
{
skip("VariableRateShading TIER_2 not supported.\n");
destroy_test_context(&context);
return;
}
hr = ID3D12GraphicsCommandList_QueryInterface(context.list, &IID_ID3D12GraphicsCommandList5, (void **)&command_list);
ok(hr == S_OK, "Couldn't get GraphicsCommandList5, hr %#x.\n", hr);
ID3D12GraphicsCommandList5_Release(command_list);
queue = context.queue;
init_pipeline_state_desc_dxil(&pso_desc, context.root_signature,
context.render_target_desc.Format, &vs, &ps, NULL);
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&pipeline_state);
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
vkd3d_test_set_context("Test %u", i);
ID3D12GraphicsCommandList5_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList5_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList5_SetPipelineState(command_list, pipeline_state);
ID3D12GraphicsCommandList5_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList5_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList5_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList5_RSSetShadingRate(command_list, tests[i].shading_rate, tests[i].combiners);
ID3D12GraphicsCommandList5_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(context.list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, context.list, tests[i].expected_color, 0);
reset_command_list(context.list, context.allocator);
transition_resource_state(context.list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
vkd3d_test_set_context(NULL);
if (pipeline_state)
ID3D12PipelineState_Release(pipeline_state);
destroy_test_context(&context);
}
void test_vrs_image(void)
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
ID3D12PipelineState *pipeline_state = NULL;
ID3D12GraphicsCommandList5 *command_list;
struct test_context_desc desc;
struct test_context context;
ID3D12CommandQueue *queue;
unsigned int i;
HRESULT hr;
#if 0
void main(in float4 vPos : SV_POSITION, out float4 o0 : SV_Target0)
{
o0 = float4(ddx(vPos.x) / 255.0, ddy(vPos.y) / 255.0, 0.0, 0.0);
}
#endif
static const DWORD ps_code_dxbc[] =
{
0x43425844, 0x1cf58366, 0x02883b19, 0xd5e18634, 0xeea3d29b, 0x00000001, 0x00000150, 0x00000003,
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000b4, 0x00000050,
0x0000002d, 0x0100086a, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
0x00000000, 0x02000068, 0x00000001, 0x0500007a, 0x00100012, 0x00000000, 0x0010100a, 0x00000000,
0x07000038, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3b808081, 0x0500007c,
0x00100012, 0x00000000, 0x0010101a, 0x00000000, 0x07000038, 0x00102022, 0x00000000, 0x0010000a,
0x00000000, 0x00004001, 0x3b808081, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x0100003e,
};
const D3D12_SHADER_BYTECODE ps = {
(const void*)ps_code_dxbc,
sizeof(ps_code_dxbc)
};
static const struct
{
D3D12_SHADING_RATE base_shading_rate;
D3D12_SHADING_RATE tex_shading_rate;
D3D12_SHADING_RATE_COMBINER combiners[2];
unsigned int expected_color;
}
tests[] =
{
{D3D12_SHADING_RATE_1X1, D3D12_SHADING_RATE_1X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_OVERRIDE}, 0x00000201},
{D3D12_SHADING_RATE_1X2, D3D12_SHADING_RATE_2X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_OVERRIDE}, 0x00000102},
{D3D12_SHADING_RATE_2X1, D3D12_SHADING_RATE_2X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_OVERRIDE}, 0x00000202},
{D3D12_SHADING_RATE_2X2, D3D12_SHADING_RATE_1X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_OVERRIDE}, 0x00000101},
{D3D12_SHADING_RATE_1X1, D3D12_SHADING_RATE_1X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000101},
{D3D12_SHADING_RATE_1X2, D3D12_SHADING_RATE_2X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000201},
{D3D12_SHADING_RATE_2X1, D3D12_SHADING_RATE_2X2, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000102},
{D3D12_SHADING_RATE_2X2, D3D12_SHADING_RATE_1X1, {D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, D3D12_SHADING_RATE_COMBINER_PASSTHROUGH}, 0x00000202},
};
memset(&desc, 0, sizeof(desc));
if (!init_test_context(&context, &desc))
return;
if (!is_vrs_tier2_supported(context.device))
{
skip("VariableRateShading TIER_2 not supported.\n");
destroy_test_context(&context);
return;
}
hr = ID3D12GraphicsCommandList_QueryInterface(context.list, &IID_ID3D12GraphicsCommandList5, (void **)&command_list);
ok(hr == S_OK, "Couldn't get GraphicsCommandList5, hr %#x.\n", hr);
ID3D12GraphicsCommandList5_Release(command_list);
queue = context.queue;
init_pipeline_state_desc(&pso_desc, context.root_signature,
context.render_target_desc.Format, NULL, &ps, NULL);
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
&IID_ID3D12PipelineState, (void **)&pipeline_state);
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
#define TEX_WIDTH (4u)
#define TEX_HEIGHT (4u)
ID3D12Resource *texture;
uint8_t shading_rate_data[TEX_WIDTH * TEX_HEIGHT] =
{
tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate,
tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate,
tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate,
tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate, tests[i].tex_shading_rate,
};
D3D12_SUBRESOURCE_DATA tex_data = { shading_rate_data, TEX_WIDTH, TEX_WIDTH * TEX_HEIGHT };
vkd3d_test_set_context("Test %u", i);
texture = create_default_texture2d(context.device, 4, 4, 1, 1, DXGI_FORMAT_R8_UINT,
0, D3D12_RESOURCE_STATE_COPY_DEST);
upload_texture_data(texture, &tex_data, 1, queue, context.list);
reset_command_list(context.list, context.allocator);
transition_resource_state(context.list, texture,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE);
ID3D12GraphicsCommandList5_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
ID3D12GraphicsCommandList5_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList5_SetPipelineState(command_list, pipeline_state);
ID3D12GraphicsCommandList5_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList5_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList5_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList5_RSSetShadingRate(command_list, tests[i].base_shading_rate, tests[i].combiners);
ID3D12GraphicsCommandList5_RSSetShadingRateImage(command_list, NULL);
ID3D12GraphicsCommandList5_RSSetShadingRateImage(command_list, texture);
ID3D12GraphicsCommandList5_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(context.list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, context.list, tests[i].expected_color, 0);
reset_command_list(context.list, context.allocator);
transition_resource_state(context.list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12Resource_Release(texture);
#undef TEX_WIDTH
#undef TEX_HEIGHT
}
vkd3d_test_set_context(NULL);
if (pipeline_state)
ID3D12PipelineState_Release(pipeline_state);
destroy_test_context(&context);
}

View File

@ -0,0 +1,289 @@
/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
void test_clock_calibration(void)
{
#ifndef _WIN32
skip("Clock calibration tests cannot pass on native Linux. Skipping.\n");
#else
uint64_t cpu_times[2], gpu_times[2];
struct test_context context;
HRESULT hr;
if (!init_test_context(&context, NULL))
return;
hr = ID3D12CommandQueue_GetClockCalibration(context.queue, &gpu_times[0], &cpu_times[0]);
ok(hr == S_OK, "Failed retrieve calibrated timestamps, hr %#x.\n", hr);
vkd3d_sleep(100);
hr = ID3D12CommandQueue_GetClockCalibration(context.queue, &gpu_times[1], &cpu_times[1]);
ok(hr == S_OK, "Failed retrieve calibrated timestamps, hr %#x.\n", hr);
ok(gpu_times[1] > gpu_times[0], "Inconsistent GPU timestamps.\n");
ok(cpu_times[1] > cpu_times[0], "Inconsistent CPU timestamps.\n");
destroy_test_context(&context);
#endif
}
void test_open_heap_from_address(void)
{
#ifdef _WIN32
ID3D12Resource *readback_resource;
struct test_context context;
struct resource_readback rb;
D3D12_HEAP_DESC heap_desc;
ID3D12Resource *resource;
unsigned int heap_size;
ID3D12Device3 *device3;
ID3D12Device *device;
HANDLE file_handle;
ID3D12Heap *heap;
unsigned int i;
uint32_t *addr;
HRESULT hr;
if (!init_test_context(&context, NULL))
return;
device = context.device;
hr = ID3D12Device_QueryInterface(device, &IID_ID3D12Device3, (void **)&device3);
ok(hr == S_OK, "Failed to query ID3D12Device3, hr #%x.\n", hr);
/* Simple case, import directly from VirtualAlloc. */
{
heap_size = 64 * 1024;
addr = VirtualAlloc(NULL, heap_size, MEM_COMMIT, PAGE_READWRITE);
ok(!!addr, "Failed to VirtualAllocate.\n");
for (i = 0; i < heap_size / sizeof(uint32_t); i++)
addr[i] = i;
hr = ID3D12Device3_OpenExistingHeapFromAddress(device3, addr, &IID_ID3D12Heap, (void **)&heap);
ok(hr == S_OK, "Failed to open heap from address: hr #%x.\n", hr);
if (heap)
{
heap_desc = ID3D12Heap_GetDesc(heap);
ok(heap_desc.SizeInBytes == heap_size, "Expected heap size of %u, but got %u.\n", heap_size, (unsigned int)heap_desc.SizeInBytes);
ok(!!(heap_desc.Flags & D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER), "Expected Heap desc to have SHARED_CROSS_ADAPTER flag set.\n");
ok(!!(heap_desc.Flags & D3D12_HEAP_FLAG_SHARED), "Expected heap desc to have SHARED flag set.\n");
resource = create_placed_buffer(device, heap, 0, heap_size, D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER, D3D12_RESOURCE_STATE_COPY_SOURCE);
ok(!!resource, "Failed to create resource.\n");
readback_resource = create_default_buffer(device, heap_size, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
ID3D12GraphicsCommandList_CopyResource(context.list, readback_resource, resource);
transition_resource_state(context.list, readback_resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(readback_resource, DXGI_FORMAT_UNKNOWN, &rb, context.queue, context.list);
reset_command_list(context.list, context.allocator);
ok(!memcmp(rb.data, addr, heap_size), "Expected exact copy.\n");
release_resource_readback(&rb);
ID3D12Heap_Release(heap);
ID3D12Resource_Release(readback_resource);
ID3D12Resource_Release(resource);
}
VirtualFree(addr, 0, MEM_RELEASE);
}
/* Import at offset, which should fail. */
{
heap_size = 64 * 1024;
addr = VirtualAlloc(NULL, heap_size, MEM_COMMIT, PAGE_READWRITE);
ok(!!addr, "Failed to VirtualAllocate.\n");
hr = ID3D12Device3_OpenExistingHeapFromAddress(device3, addr + 1024, &IID_ID3D12Heap, (void **)&heap);
ok(hr == E_INVALIDARG, "Should not be able to open heap at offset from VirtualAlloc.\n");
}
/* HANDLE variant. */
{
heap_size = 256 * 1024;
file_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, heap_size, "foobar");
ok(!!file_handle, "Failed to open file mapping.\n");
addr = MapViewOfFile(file_handle, FILE_MAP_ALL_ACCESS, 0, 0, heap_size);
ok(!!addr, "Failed to map view of file.\n");
for (i = 0; i < heap_size / sizeof(uint32_t); i++)
addr[i] = i;
hr = ID3D12Device3_OpenExistingHeapFromFileMapping(device3, file_handle, &IID_ID3D12Heap, (void **)&heap);
ok(hr == S_OK, "Failed to open heap from file mapping: hr #%x.\n", hr);
if (heap)
{
heap_desc = ID3D12Heap_GetDesc(heap);
ok(heap_desc.SizeInBytes == heap_size, "Expected heap size of %u, but got %u.\n", heap_size, (unsigned int)heap_desc.SizeInBytes);
ok(!!(heap_desc.Flags & D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER), "Expected Heap desc to have SHARED_CROSS_ADAPTER flag set.\n");
ok(!!(heap_desc.Flags & D3D12_HEAP_FLAG_SHARED), "Expected heap desc to have SHARED flag set.\n");
resource = create_placed_buffer(device, heap, 0, heap_size, D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER, D3D12_RESOURCE_STATE_COPY_SOURCE);
ok(!!resource, "Failed to create resource.\n");
readback_resource = create_default_buffer(device, heap_size, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
ID3D12GraphicsCommandList_CopyResource(context.list, readback_resource, resource);
transition_resource_state(context.list, readback_resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(readback_resource, DXGI_FORMAT_UNKNOWN, &rb, context.queue, context.list);
reset_command_list(context.list, context.allocator);
for (i = 0; i < heap_size / sizeof(uint32_t); i++)
{
uint32_t v = get_readback_uint(&rb, i, 0, 0);
ok(v == i, "Expected %u, got %u.\n", i, v);
}
release_resource_readback(&rb);
ID3D12Heap_Release(heap);
ID3D12Resource_Release(readback_resource);
ID3D12Resource_Release(resource);
}
UnmapViewOfFile(addr);
CloseHandle(file_handle);
}
ID3D12Device3_Release(device3);
destroy_test_context(&context);
#else
skip("Cannot test OpenExistingHeapFrom* on non-native Win32 platforms.\n");
#endif
}
void test_write_watch(void)
{
#ifndef _WIN32
skip("WRITE_WATCH tests cannot pass on native Linux. Skipping.\n");
#else
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_RESOURCE_DESC resource_desc;
struct test_context_desc desc;
void **dirty_addresses = NULL;
struct test_context context;
ULONG_PTR address_count;
ID3D12Resource *buffer;
size_t mapping_size;
DWORD page_size;
char *map_ptr;
UINT result;
HRESULT hr;
mapping_size = 64 * 1024;
memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
desc.no_pipeline = true;
desc.no_root_signature = true;
if (!init_test_context(&context, &desc))
return;
memset(&heap_properties, 0, sizeof(heap_properties));
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resource_desc.Alignment = 0;
resource_desc.Width = mapping_size;
resource_desc.Height = 1;
resource_desc.DepthOrArraySize = 1;
resource_desc.MipLevels = 1;
resource_desc.Format = DXGI_FORMAT_UNKNOWN;
resource_desc.SampleDesc.Count = 1;
resource_desc.SampleDesc.Quality = 0;
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
buffer = NULL;
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
hr = ID3D12Device_CreateCommittedResource(context.device, &heap_properties,
D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH, &resource_desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
NULL, &IID_ID3D12Resource, (void **)&buffer);
ok(hr == E_INVALIDARG, "Got hr %#x, expected %#x.\n", hr, E_INVALIDARG);
if (buffer)
ID3D12Resource_Release(buffer);
buffer = NULL;
heap_properties.Type = D3D12_HEAP_TYPE_UPLOAD;
resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
hr = ID3D12Device_CreateCommittedResource(context.device, &heap_properties,
D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH, &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ,
NULL, &IID_ID3D12Resource, (void **)&buffer);
ok(hr == S_OK, "Got hr %#x, expected %#x.\n", hr, S_OK);
if (FAILED(hr))
{
skip("Failed to create write watch buffer.\n");
goto done;
}
/* Do some basic write watch testing... */
hr = ID3D12Resource_Map(buffer, 0, NULL, (void**) &map_ptr);
ok(hr == S_OK, "Got hr %#x, expected %#x.\n", hr, S_OK);
if (FAILED(hr))
{
skip("Failed to map write watch resource.\n");
goto done;
}
result = ResetWriteWatch((void*) map_ptr, mapping_size);
ok(!result, "Failed to ResetWriteWatch %#x.\n", GetLastError());
if (result)
{
skip("Failed to ResetWriteWatch, skipping the rest of the WRITE_WATCH tests.\n");
goto done;
}
page_size = 0x1000;
address_count = mapping_size / (DWORD_PTR)page_size;
dirty_addresses = malloc(sizeof(void*) * address_count);
/* Dirty it a bit, in some pages... */
map_ptr[0 * page_size] = 'a';
map_ptr[1 * page_size] = 'b';
map_ptr[5 * page_size] = 'c';
map_ptr[9 * page_size] = 'd';
result = GetWriteWatch(WRITE_WATCH_FLAG_RESET, (void*) map_ptr, mapping_size, dirty_addresses, &address_count, &page_size);
ok(!result, "Failed to GetWriteWatch %#x.\n", GetLastError());
if (result)
{
skip("Failed to GetWriteWatch, skipping the rest of the WRITE_WATCH tests.\n");
goto done;
}
ok(address_count == 4, "Expected address_count of %p, got %p\n", 4, address_count);
ok(page_size == 0x1000, "Expected page_size of %u, got %u\n", 0x1000, page_size);
ok(dirty_addresses[0] == (void*)&map_ptr[0 * page_size], "Expected dirty address 0 to be %p, got %p\n",
(void*)&map_ptr[0 * page_size], dirty_addresses[0]);
ok(dirty_addresses[1] == (void*)&map_ptr[1 * page_size], "Expected dirty address 1 to be %p, got %p\n",
(void*)&map_ptr[1 * page_size], dirty_addresses[1]);
ok(dirty_addresses[2] == (void*)&map_ptr[5 * page_size], "Expected dirty address 2 to be %p, got %p\n",
(void*)&map_ptr[5 * page_size], dirty_addresses[2]);
ok(dirty_addresses[3] == (void*)&map_ptr[9 * page_size], "Expected dirty address 3 to be %p, got %p\n",
(void*)&map_ptr[9 * page_size], dirty_addresses[3]);
done:
free(dirty_addresses);
if (buffer)
ID3D12Resource_Release(buffer);
destroy_test_context(&context);
#endif
}

View File

@ -16,7 +16,37 @@ d3d12_test_utils_lib = static_library('d3d12-test-utils', 'd3d12_test_utils.c',
include_directories : vkd3d_private_includes,
override_options : [ 'c_std='+vkd3d_c_std ])
executable('d3d12', 'd3d12.c',
d3d12_test_src = [
'd3d12_clip_cull_distance.c',
'd3d12_geometry_shader.c',
'd3d12_win32_exclusive.c',
'd3d12_root_signature.c',
'd3d12_depth_stencil.c',
'd3d12_render_target.c',
'd3d12_tessellation.c',
'd3d12_sm_advanced.c',
'd3d12_descriptors.c',
'd3d12_raytracing.c',
'd3d12_robustness.c',
'd3d12_streamout.c',
'd3d12_pso_blob.c',
'd3d12_resource.c',
'd3d12_bindless.c',
'd3d12_shaders.c',
'd3d12_command.c',
'd3d12_sparse.c',
'd3d12_device.c',
'd3d12_clear.c',
'd3d12_query.c',
'd3d12_sync.c',
'd3d12_copy.c',
'd3d12_vrs.c',
'd3d12_pso.c',
'd3d12_va.c',
'd3d12.c',
]
executable('d3d12', d3d12_test_src,
dependencies : vkd3d_test_deps,
include_directories : vkd3d_private_includes,
install : false,