From 9eaa64137673c8a049c4cdf2364c8eb67b1bbde9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 4 Dec 2018 15:55:56 +0100 Subject: [PATCH] vkd3d: Validate that command signature contains exactly one dispatch/draw command. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- libs/vkd3d/command.c | 20 +++++++++++++++++ tests/d3d12.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 06823c89..a175091b 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -4850,6 +4850,26 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_ struct d3d12_command_signature **signature) { struct d3d12_command_signature *object; + unsigned int i; + + for (i = 0; i < desc->NumArgumentDescs; ++i) + { + const D3D12_INDIRECT_ARGUMENT_DESC *argument_desc = &desc->pArgumentDescs[i]; + switch (argument_desc->Type) + { + case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW: + case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED: + case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: + if (i != desc->NumArgumentDescs - 1) + { + WARN("Draw/dispatch must be the last element of a command signature.\n"); + return E_INVALIDARG; + } + break; + default: + break; + } + } if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY; diff --git a/tests/d3d12.c b/tests/d3d12.c index 7ad03039..4344aa9f 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -1685,6 +1685,56 @@ static void test_create_command_queue(void) ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); } +static void test_create_command_signature(void) +{ + D3D12_INDIRECT_ARGUMENT_DESC argument_desc[3]; + D3D12_COMMAND_SIGNATURE_DESC signature_desc; + ID3D12CommandSignature *command_signature; + ID3D12Device *device; + unsigned int i; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device.\n"); + return; + } + + signature_desc.ByteStride = 1024; + signature_desc.NumArgumentDescs = ARRAY_SIZE(argument_desc); + signature_desc.pArgumentDescs = argument_desc; + signature_desc.NodeMask = 0; + + for (i = 0; i < ARRAY_SIZE(argument_desc); ++i) + argument_desc[i].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + hr = ID3D12Device_CreateCommandSignature(device, &signature_desc, + NULL, &IID_ID3D12CommandSignature, (void **)&command_signature); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(argument_desc); ++i) + argument_desc[i].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED; + hr = ID3D12Device_CreateCommandSignature(device, &signature_desc, + NULL, &IID_ID3D12CommandSignature, (void **)&command_signature); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(argument_desc); ++i) + argument_desc[i].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH; + hr = ID3D12Device_CreateCommandSignature(device, &signature_desc, + NULL, &IID_ID3D12CommandSignature, (void **)&command_signature); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + argument_desc[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH; + argument_desc[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + signature_desc.NumArgumentDescs = 2; + hr = ID3D12Device_CreateCommandSignature(device, &signature_desc, + NULL, &IID_ID3D12CommandSignature, (void **)&command_signature); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + refcount = ID3D12Device_Release(device); + ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); +} + static void test_create_committed_resource(void) { D3D12_GPU_VIRTUAL_ADDRESS gpu_address; @@ -22116,6 +22166,7 @@ START_TEST(d3d12) run_test(test_create_command_allocator); run_test(test_create_command_list); run_test(test_create_command_queue); + run_test(test_create_command_signature); run_test(test_create_committed_resource); run_test(test_create_heap); run_test(test_create_placed_resource);