=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d: Validate heap type for render target and unordered access buffers.

Alexandre Julliard julliard at winehq.org
Mon Nov 12 16:26:10 CST 2018


Module: vkd3d
Branch: master
Commit: b8a665e22980ec497959d9d206f2f8567c5c8f87
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=b8a665e22980ec497959d9d206f2f8567c5c8f87

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Fri Nov  9 18:06:24 2018 +0100

vkd3d: Validate heap type for render target and unordered access buffers.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d/resource.c | 18 +++++++---
 tests/d3d12.c         | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index a2a00d3..78101a5 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1051,12 +1051,20 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
 
     resource->desc = *desc;
 
-    if (d3d12_resource_is_texture(resource)
-            && (heap_properties->Type == D3D12_HEAP_TYPE_UPLOAD
-            || heap_properties->Type == D3D12_HEAP_TYPE_READBACK))
+    if (heap_properties->Type == D3D12_HEAP_TYPE_UPLOAD
+            || heap_properties->Type == D3D12_HEAP_TYPE_READBACK)
     {
-        WARN("Texture cannot be created on a UPLOAD/READBACK heap.\n");
-        return E_INVALIDARG;
+        if (d3d12_resource_is_texture(resource))
+        {
+            WARN("Textures cannot be created on upload/readback heaps.\n");
+            return E_INVALIDARG;
+        }
+
+        if (desc->Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS))
+        {
+            WARN("Render target and unordered access buffers cannot be created on upload/readback heaps.\n");
+            return E_INVALIDARG;
+        }
     }
 
     if (heap_properties->Type == D3D12_HEAP_TYPE_UPLOAD && initial_state != D3D12_RESOURCE_STATE_GENERIC_READ)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 92b37a3..1ddf7c2 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -1669,10 +1669,26 @@ static void test_create_committed_resource(void)
     D3D12_RESOURCE_DESC resource_desc;
     ID3D12Device *device, *tmp_device;
     D3D12_CLEAR_VALUE clear_value;
+    D3D12_RESOURCE_STATES state;
     ID3D12Resource *resource;
+    unsigned int i;
     ULONG refcount;
     HRESULT hr;
 
+    static const struct
+    {
+        D3D12_HEAP_TYPE heap_type;
+        D3D12_RESOURCE_FLAGS flags;
+    }
+    invalid_buffer_desc_tests[] =
+    {
+        /* Render target or unordered access resources are not allowed with UPLOAD or READBACK. */
+        {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
+        {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
+        {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
+        {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
+    };
+
     if (!(device = create_device()))
     {
         skip("Failed to create device.\n");
@@ -1876,6 +1892,33 @@ static void test_create_committed_resource(void)
             &IID_ID3D12Resource, (void **)&resource);
     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
 
+    for (i = 0; i < ARRAY_SIZE(invalid_buffer_desc_tests); ++i)
+    {
+        memset(&heap_properties, 0, sizeof(heap_properties));
+        heap_properties.Type = invalid_buffer_desc_tests[i].heap_type;
+
+        resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+        resource_desc.Alignment = 0;
+        resource_desc.Width = 32;
+        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;
+        resource_desc.Flags = invalid_buffer_desc_tests[i].flags;
+
+        if (invalid_buffer_desc_tests[i].heap_type == D3D12_HEAP_TYPE_UPLOAD)
+            state = D3D12_RESOURCE_STATE_GENERIC_READ;
+        else
+            state = D3D12_RESOURCE_STATE_COPY_DEST;
+
+        hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
+                &resource_desc, state, NULL, &IID_ID3D12Resource, (void **)&resource);
+        ok(hr == E_INVALIDARG, "Test %u: Got unexpected hr %#x.\n", i, hr);
+    }
+
     refcount = ID3D12Device_Release(device);
     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
 }
@@ -2014,12 +2057,28 @@ static void test_create_placed_resource(void)
     D3D12_RESOURCE_DESC resource_desc;
     ID3D12Device *device, *tmp_device;
     D3D12_CLEAR_VALUE clear_value;
+    D3D12_RESOURCE_STATES state;
     D3D12_HEAP_DESC heap_desc;
     ID3D12Resource *resource;
     ID3D12Heap *heap;
+    unsigned int i;
     ULONG refcount;
     HRESULT hr;
 
+    static const struct
+    {
+        D3D12_HEAP_TYPE heap_type;
+        D3D12_RESOURCE_FLAGS flags;
+    }
+    invalid_buffer_desc_tests[] =
+    {
+        /* Render target or unordered access resources are not allowed with UPLOAD or READBACK. */
+        {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
+        {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
+        {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
+        {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
+    };
+
     if (!(device = create_device()))
     {
         skip("Failed to create device.\n");
@@ -2090,6 +2149,41 @@ static void test_create_placed_resource(void)
     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
 
     ID3D12Heap_Release(heap);
+
+    for (i = 0; i < ARRAY_SIZE(invalid_buffer_desc_tests); ++i)
+    {
+        heap_desc.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
+        memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
+        heap_desc.Properties.Type = invalid_buffer_desc_tests[i].heap_type;
+        heap_desc.Alignment = 0;
+        heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
+        hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&heap);
+        ok(hr == S_OK, "Test %u: Failed to create heap, hr %#x.\n", i, hr);
+
+        resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+        resource_desc.Alignment = 0;
+        resource_desc.Width = 32;
+        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;
+        resource_desc.Flags = invalid_buffer_desc_tests[i].flags;
+
+        if (invalid_buffer_desc_tests[i].heap_type == D3D12_HEAP_TYPE_UPLOAD)
+            state = D3D12_RESOURCE_STATE_GENERIC_READ;
+        else
+            state = D3D12_RESOURCE_STATE_COPY_DEST;
+
+        hr = ID3D12Device_CreatePlacedResource(device, heap, 0,
+                &resource_desc, state, &clear_value, &IID_ID3D12Resource, (void **)&resource);
+        ok(hr == E_INVALIDARG, "Test %u: Got unexpected hr %#x.\n", i, hr);
+
+        ID3D12Heap_Release(heap);
+    }
+
     refcount = ID3D12Device_Release(device);
     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
 }




More information about the wine-cvs mailing list