[PATCH vkd3d 1/4] vkd3d: Implement d3d12_device_CreateReservedResource().

Józef Kucia joseph.kucia at gmail.com
Wed Jun 5 06:02:21 CDT 2019


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 libs/vkd3d/device.c        |  18 ++++--
 libs/vkd3d/resource.c      | 129 ++++++++++++++++++++++++++++++-------
 libs/vkd3d/vkd3d_private.h |   3 +
 3 files changed, 119 insertions(+), 31 deletions(-)

diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index ddec0f7cae67..e83b7fa9258c 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -2780,14 +2780,20 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device
 
 static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device *iface,
         const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
-        const D3D12_CLEAR_VALUE *optimized_clear_value,
-        REFIID riid, void **resource)
+        const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource)
 {
-    FIXME("iface %p, desc %p, initial_state %#x, optimized_clear_value %p, "
-            "riid %s, resource %p stub!\n",
-            iface, desc, initial_state, optimized_clear_value, debugstr_guid(riid), resource);
+    struct d3d12_device *device = impl_from_ID3D12Device(iface);
+    struct d3d12_resource *object;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, desc %p, initial_state %#x, optimized_clear_value %p, iid %s, resource %p.\n",
+            iface, desc, initial_state, optimized_clear_value, debugstr_guid(iid), resource);
+
+    if (FAILED(hr = d3d12_reserved_resource_create(device,
+            desc, initial_state, optimized_clear_value, &object)))
+        return hr;
+
+    return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
 }
 
 static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device *iface,
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index c3c92386da08..30ef9018d775 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -21,6 +21,8 @@
 #define VKD3D_NULL_BUFFER_SIZE 16
 #define VKD3D_NULL_VIEW_FORMAT DXGI_FORMAT_R8G8B8A8_UNORM
 
+#define VKD3D_HEAP_TYPE_INVALID ((D3D12_HEAP_TYPE)~0u)
+
 static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32_t memory_type_mask,
         const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags)
 {
@@ -497,14 +499,25 @@ HRESULT vkd3d_create_buffer(struct d3d12_device *device,
         const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+    const bool sparse_resource = !heap_properties;
     VkBufferCreateInfo buffer_info;
+    D3D12_HEAP_TYPE heap_type;
     VkResult vr;
 
+    heap_type = heap_properties ? heap_properties->Type : D3D12_HEAP_TYPE_DEFAULT;
+
     buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
     buffer_info.pNext = NULL;
     buffer_info.flags = 0;
     buffer_info.size = desc->Width;
 
+    if (sparse_resource)
+    {
+        buffer_info.flags |= VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
+        if (device->vk_info.sparse_properties.residencyNonResidentStrict)
+            buffer_info.flags |= VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
+    }
+
     buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
             | VK_BUFFER_USAGE_TRANSFER_DST_BIT
             | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
@@ -512,16 +525,15 @@ HRESULT vkd3d_create_buffer(struct d3d12_device *device,
             | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
             | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
 
-    if (heap_properties->Type == D3D12_HEAP_TYPE_DEFAULT
-            && device->vk_info.EXT_transform_feedback)
+    if (heap_type == D3D12_HEAP_TYPE_DEFAULT && device->vk_info.EXT_transform_feedback)
     {
         buffer_info.usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT
                 | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
     }
 
-    if (heap_properties->Type == D3D12_HEAP_TYPE_UPLOAD)
+    if (heap_type == D3D12_HEAP_TYPE_UPLOAD)
         buffer_info.usage &= ~VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-    else if (heap_properties->Type == D3D12_HEAP_TYPE_READBACK)
+    else if (heap_type == D3D12_HEAP_TYPE_READBACK)
         buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
 
     if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
@@ -573,6 +585,7 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
         const D3D12_RESOURCE_DESC *desc, VkImage *vk_image)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+    const bool sparse_resource = !heap_properties;
     const struct vkd3d_format *format;
     VkImageCreateInfo image_info;
     VkResult vr;
@@ -595,6 +608,13 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
     if (desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
         image_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR;
 
+    if (sparse_resource)
+    {
+        image_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
+        if (device->vk_info.sparse_properties.residencyNonResidentStrict)
+            image_info.flags |= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
+    }
+
     image_info.imageType = vk_image_type_from_d3d12_resource_dimension(desc->Dimension);
     image_info.format = format->vk_format;
     image_info.extent.width = desc->Width;
@@ -614,7 +634,17 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
     image_info.mipLevels = min(desc->MipLevels, max_miplevel_count(desc));
     image_info.samples = vk_samples_from_dxgi_sample_desc(&desc->SampleDesc);
 
-    if (desc->Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN)
+    if (sparse_resource)
+    {
+        if (desc->Layout != D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE)
+        {
+            WARN("D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE must be used for reserved texture.\n");
+            return E_INVALIDARG;
+        }
+
+        image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    }
+    else if (desc->Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN)
     {
         image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
     }
@@ -652,7 +682,7 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
         image_info.pQueueFamilyIndices = NULL;
     }
 
-    image_info.initialLayout = is_cpu_accessible_heap(heap_properties) ?
+    image_info.initialLayout = heap_properties && is_cpu_accessible_heap(heap_properties) ?
             VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED;
 
     if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, vk_image))) < 0)
@@ -1155,6 +1185,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource
     TRACE("iface %p, heap_properties %p, flags %p.\n",
             iface, heap_properties, flags);
 
+    if (resource->heap_properties.Type == VKD3D_HEAP_TYPE_INVALID)
+    {
+        WARN("Cannot get heap properties for reserved resources.\n");
+        return E_INVALIDARG;
+    }
+
     if (heap_properties)
         *heap_properties = resource->heap_properties;
     if (flags)
@@ -1255,46 +1291,55 @@ HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc)
     return S_OK;
 }
 
-static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12_device *device,
-        const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
-        const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
-        const D3D12_CLEAR_VALUE *optimized_clear_value)
+static bool d3d12_resource_validate_heap_properties(const struct d3d12_resource *resource,
+        const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_RESOURCE_STATES initial_state)
 {
-    HRESULT hr;
-
-    resource->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl;
-    resource->refcount = 1;
-    resource->internal_refcount = 1;
-
-    resource->desc = *desc;
-
     if (heap_properties->Type == D3D12_HEAP_TYPE_UPLOAD
             || heap_properties->Type == D3D12_HEAP_TYPE_READBACK)
     {
         if (d3d12_resource_is_texture(resource))
         {
             WARN("Textures cannot be created on upload/readback heaps.\n");
-            return E_INVALIDARG;
+            return false;
         }
 
-        if (desc->Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS))
+        if (resource->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;
+            return false;
         }
     }
 
     if (heap_properties->Type == D3D12_HEAP_TYPE_UPLOAD && initial_state != D3D12_RESOURCE_STATE_GENERIC_READ)
     {
         WARN("For D3D12_HEAP_TYPE_UPLOAD the state must be D3D12_RESOURCE_STATE_GENERIC_READ.\n");
-        return E_INVALIDARG;
+        return false;
     }
     if (heap_properties->Type == D3D12_HEAP_TYPE_READBACK && initial_state != D3D12_RESOURCE_STATE_COPY_DEST)
     {
         WARN("For D3D12_HEAP_TYPE_READBACK the state must be D3D12_RESOURCE_STATE_COPY_DEST.\n");
-        return E_INVALIDARG;
+        return false;
     }
 
+    return true;
+}
+
+static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12_device *device,
+        const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
+        const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
+        const D3D12_CLEAR_VALUE *optimized_clear_value)
+{
+    HRESULT hr;
+
+    resource->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl;
+    resource->refcount = 1;
+    resource->internal_refcount = 1;
+
+    resource->desc = *desc;
+
+    if (heap_properties && !d3d12_resource_validate_heap_properties(resource, heap_properties, initial_state))
+        return E_INVALIDARG;
+
     if (!is_valid_resource_state(initial_state))
     {
         WARN("Invalid initial resource state %#x.\n", initial_state);
@@ -1351,8 +1396,18 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
     resource->map_count = 0;
     resource->map_ptr = NULL;
 
-    resource->heap_properties = *heap_properties;
-    resource->heap_flags = heap_flags;
+    if (heap_properties)
+    {
+        resource->heap_properties = *heap_properties;
+        resource->heap_flags = heap_flags;
+    }
+    else
+    {
+        memset(&resource->heap_properties, 0, sizeof(resource->heap_properties));
+        resource->heap_properties.Type = VKD3D_HEAP_TYPE_INVALID;
+        resource->heap_flags = 0;
+    }
+
     resource->initial_state = initial_state;
 
     resource->heap = NULL;
@@ -1417,6 +1472,12 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
     struct d3d12_resource *object;
     HRESULT hr;
 
+    if (!heap_properties)
+    {
+        WARN("Heap properties are NULL.\n");
+        return E_INVALIDARG;
+    }
+
     if (FAILED(hr = d3d12_resource_create(device, heap_properties, heap_flags,
             desc, initial_state, optimized_clear_value, &object)))
         return hr;
@@ -1503,6 +1564,24 @@ HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_h
     return S_OK;
 }
 
+HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
+        const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
+        const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
+{
+    struct d3d12_resource *object;
+    HRESULT hr;
+
+    if (FAILED(hr = d3d12_resource_create(device, NULL, 0,
+            desc, initial_state, optimized_clear_value, &object)))
+        return hr;
+
+    TRACE("Created reserved resource %p.\n", object);
+
+    *resource = object;
+
+    return S_OK;
+}
+
 HRESULT vkd3d_create_image_resource(ID3D12Device *device,
         const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource)
 {
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 71e05b245230..2d31cacc101e 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -402,6 +402,9 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
 HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_heap *heap, UINT64 heap_offset,
         const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
         const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource) DECLSPEC_HIDDEN;
+HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
+        const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
+        const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource) DECLSPEC_HIDDEN;
 struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface) DECLSPEC_HIDDEN;
 
 HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_buffer,
-- 
2.21.0




More information about the wine-devel mailing list