tests: Add test for texturing.

This commit is contained in:
Józef Kucia 2017-07-17 16:25:29 +02:00
parent cc536e72ab
commit da6c724c3b

View File

@ -147,10 +147,9 @@ static void check_interface_(unsigned int line, IUnknown *iface, REFIID riid, bo
IUnknown_Release(unk);
}
#define create_root_signature(a, b, c) create_root_signature_(__LINE__, a, b, c)
#if _WIN32
static HRESULT create_root_signature_(unsigned int line, ID3D12Device *device,
const D3D12_ROOT_SIGNATURE_DESC *desc, ID3D12RootSignature **root_signature)
static HRESULT create_root_signature(ID3D12Device *device, const D3D12_ROOT_SIGNATURE_DESC *desc,
ID3D12RootSignature **root_signature)
{
ID3DBlob *blob;
HRESULT hr;
@ -166,8 +165,8 @@ static HRESULT create_root_signature_(unsigned int line, ID3D12Device *device,
#else
/* XXX: Root signature byte code is not supported yet. We allow to pass D3D12_ROOT_SIGNATURE_DESC
* directly to CreateRootSignature(). */
static HRESULT create_root_signature_(unsigned int line, ID3D12Device *device,
const D3D12_ROOT_SIGNATURE_DESC *desc, ID3D12RootSignature **root_signature)
static HRESULT create_root_signature(ID3D12Device *device, const D3D12_ROOT_SIGNATURE_DESC *desc,
ID3D12RootSignature **root_signature)
{
return ID3D12Device_CreateRootSignature(device, 0, desc, ~(SIZE_T)0,
&IID_ID3D12RootSignature, (void **)root_signature);
@ -426,6 +425,101 @@ static ID3D12Resource *create_upload_buffer_(unsigned int line, ID3D12Device *de
return buffer;
}
#define create_texture(a, b, c, d, e) create_texture_(__LINE__, a, b, c, d, e)
static ID3D12Resource *create_texture_(unsigned int line, ID3D12Device *device,
unsigned int width, unsigned int height, DXGI_FORMAT format, D3D12_RESOURCE_STATES initial_state)
{
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_RESOURCE_DESC resource_desc;
ID3D12Resource *texture;
HRESULT hr;
memset(&heap_properties, 0, sizeof(heap_properties));
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
memset(&resource_desc, 0, sizeof(resource_desc));
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resource_desc.Width = width;
resource_desc.Height = height;
resource_desc.DepthOrArraySize = 1;
resource_desc.MipLevels = 1;
resource_desc.Format = format;
resource_desc.SampleDesc.Count = 1;
hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
&resource_desc, initial_state, NULL, &IID_ID3D12Resource, (void **)&texture);
ok_(line)(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
return texture;
}
static void copy_sub_resource_data(const D3D12_MEMCPY_DEST *dst, const D3D12_SUBRESOURCE_DATA *src,
unsigned int row_count, unsigned int slice_count, size_t row_size)
{
const BYTE *src_slice_ptr;
BYTE *dst_slice_ptr;
unsigned int z, y;
for (z = 0; z < slice_count; ++z)
{
dst_slice_ptr = (BYTE *)dst->pData + z * dst->SlicePitch;
src_slice_ptr = (const BYTE*)src->pData + z * src->SlicePitch;
for (y = 0; y < row_count; ++y)
memcpy(dst_slice_ptr + y * dst->RowPitch, src_slice_ptr + y * src->RowPitch, row_size);
}
}
#define upload_texture_data(a, b, c, d) upload_texture_data_(__LINE__, a, b, c, d)
static void upload_texture_data_(unsigned int line, ID3D12Resource *texture,
D3D12_SUBRESOURCE_DATA *data, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list)
{
D3D12_TEXTURE_COPY_LOCATION dst_location, src_location;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout;
D3D12_RESOURCE_DESC resource_desc;
UINT64 row_size, required_size;
ID3D12Resource *upload_buffer;
D3D12_MEMCPY_DEST dst_data;
ID3D12Device *device;
UINT row_count;
HRESULT hr;
void *ptr;
resource_desc = ID3D12Resource_GetDesc(texture);
hr = ID3D12Resource_GetDevice(texture, &IID_ID3D12Device, (void **)&device);
ok_(line)(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, 1, 0, &layout,
&row_count, &row_size, &required_size);
upload_buffer = create_upload_buffer_(line, device, required_size, NULL);
hr = ID3D12Resource_Map(upload_buffer, 0, NULL, (void **)&ptr);
ok_(line)(SUCCEEDED(hr), "Failed to map upload buffer, hr %#x.\n", hr);
dst_data.pData = (BYTE *)ptr + layout.Offset;
dst_data.RowPitch = layout.Footprint.RowPitch;
dst_data.SlicePitch = layout.Footprint.RowPitch * row_count;
copy_sub_resource_data(&dst_data, data, row_count, layout.Footprint.Depth, row_size);
ID3D12Resource_Unmap(upload_buffer, 0, NULL);
dst_location.pResource = texture;
dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dst_location.SubresourceIndex = 0;
src_location.pResource = upload_buffer;
src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
src_location.PlacedFootprint = layout;
ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0, &src_location, NULL);
hr = ID3D12GraphicsCommandList_Close(command_list);
ok_(line)(SUCCEEDED(hr), "Close failed, hr %#x.\n", hr);
exec_command_list(queue, command_list);
wait_queue_idle(device, queue);
ID3D12Resource_Release(upload_buffer);
ID3D12Device_Release(device);
}
static unsigned int format_size(DXGI_FORMAT format)
{
switch (format)
@ -661,6 +755,50 @@ static ID3D12RootSignature *create_cb_root_signature_(unsigned int line,
return root_signature;
}
#define create_texture_root_signature(a, b, c) create_texture_root_signature_(__LINE__, a, b, c)
static ID3D12RootSignature *create_texture_root_signature_(unsigned int line,
ID3D12Device *device, D3D12_SHADER_VISIBILITY shader_visibility, D3D12_ROOT_SIGNATURE_FLAGS flags)
{
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
ID3D12RootSignature *root_signature = NULL;
D3D12_DESCRIPTOR_RANGE descriptor_range;
D3D12_STATIC_SAMPLER_DESC sampler_desc;
D3D12_ROOT_PARAMETER root_parameter;
HRESULT hr;
memset(&sampler_desc, 0, sizeof(sampler_desc));
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_desc.ShaderRegister = 1;
sampler_desc.RegisterSpace = 0;
sampler_desc.ShaderVisibility = shader_visibility;
descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
descriptor_range.NumDescriptors = 1;
descriptor_range.BaseShaderRegister = 0;
descriptor_range.RegisterSpace = 0;
descriptor_range.OffsetInDescriptorsFromTableStart = 0;
root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameter.DescriptorTable.NumDescriptorRanges = 1;
root_parameter.DescriptorTable.pDescriptorRanges = &descriptor_range;
root_parameter.ShaderVisibility = shader_visibility;
memset(&root_signature_desc, 0, sizeof(root_signature_desc));
root_signature_desc.NumParameters = 1;
root_signature_desc.pParameters = &root_parameter;
root_signature_desc.NumStaticSamplers = 1;
root_signature_desc.pStaticSamplers = &sampler_desc;
root_signature_desc.Flags = flags;
hr = create_root_signature(device, &root_signature_desc, &root_signature);
ok_(line)(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
return root_signature;
}
#define create_pipeline_state(a, b, c, d, e, f) create_pipeline_state_(__LINE__, a, b, c, d, e, f)
static ID3D12PipelineState *create_pipeline_state_(unsigned int line, ID3D12Device *device,
ID3D12RootSignature *root_signature, DXGI_FORMAT rt_format,
@ -5372,6 +5510,125 @@ static void test_immediate_constant_buffer(void)
destroy_test_context(&context);
}
static void test_texture(void)
{
ID3D12GraphicsCommandList *command_list;
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
D3D12_SUBRESOURCE_DATA texture_data;
struct test_context_desc desc;
struct resource_readback rb;
struct test_context context;
ID3D12DescriptorHeap *heap;
ID3D12CommandQueue *queue;
ID3D12Resource *texture;
unsigned int x, y;
HRESULT hr;
static const DWORD ps_code[] =
{
#if 0
Texture2D t : register(t0);
SamplerState s : register(s1);
float4 main(float4 position : SV_POSITION) : SV_Target
{
float2 p;
p.x = position.x / 32.0f;
p.y = position.y / 32.0f;
return t.Sample(s, p);
}
#endif
0x43425844, 0xc5df85e3, 0x32854510, 0xedd54782, 0x20bf84ff, 0x00000001, 0x00000140, 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, 0x000000a4, 0x00000050,
0x00000029, 0x0100086a, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000,
0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001020f2,
0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000001, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f};
static const unsigned int bitmap_data[] =
{
0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f,
0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
0xffffffff, 0xff000000, 0xff000000, 0xff000000,
};
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_texture_root_signature(context.device, D3D12_SHADER_VISIBILITY_PIXEL, 0);
context.pipeline_state = create_pipeline_state(context.device,
context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
memset(&heap_desc, 0, sizeof(heap_desc));
heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
heap_desc.NumDescriptors = 1;
heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
hr = ID3D12Device_CreateDescriptorHeap(context.device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
ok(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr);
cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
texture = create_texture(context.device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RESOURCE_STATE_COPY_DEST);
texture_data.pData = bitmap_data;
texture_data.RowPitch = 4 * sizeof(*bitmap_data);
texture_data.SlicePitch = texture_data.RowPitch * 4;
upload_texture_data(texture, &texture_data, queue, command_list);
hr = ID3D12CommandAllocator_Reset(context.allocator);
ok(SUCCEEDED(hr), "Command allocator reset failed, hr %#x.\n", hr);
hr = ID3D12GraphicsCommandList_Reset(command_list, context.allocator, NULL);
ok(SUCCEEDED(hr), "Command list reset failed, hr %#x.\n", hr);
transition_resource_state(command_list, texture,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
ID3D12Device_CreateShaderResourceView(context.device, texture, NULL, cpu_handle);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, red, 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_SetDescriptorHeaps(command_list, 1, &heap);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
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);
get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
for (y = 0; y < 4; ++y)
{
for (x = 0; x < 4; ++x)
{
unsigned int color = get_readback_uint(&rb, 4 + 8 * x, 4 + 8 * y);
ok(compare_color(color, bitmap_data[4 * y + x], 1),
"Got color 0x%08x, expected 0x%08x at (%u, %u).\n", color, bitmap_data[4 * y + x], x, y);
}
}
release_resource_readback(&rb);
ID3D12Resource_Release(texture);
ID3D12DescriptorHeap_Release(heap);
destroy_test_context(&context);
}
#define check_copyable_footprints(a, b, c, d, e, f, g) \
check_copyable_footprints_(__LINE__, a, b, c, d, e, f, g)
static void check_copyable_footprints_(unsigned int line, const D3D12_RESOURCE_DESC *desc,
@ -5646,5 +5903,6 @@ START_TEST(d3d12)
run_test(test_shader_interstage_interface);
run_test(test_root_signature_deserializer);
run_test(test_immediate_constant_buffer);
run_test(test_texture);
run_test(test_get_copyable_footprints);
}