[PATCH v2 1/2] vkd3d: Add support for custom heap properties.

Conor McCarthy cmccarthy at codeweavers.com
Thu Oct 24 10:58:24 CDT 2019


Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
v2: Add validation and tests.
---
 libs/vkd3d/resource.c | 64 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 626772e..b63a578 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -34,8 +34,17 @@ static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *propertie
     return true;
 }
 
-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)
+static bool is_numa_device(struct d3d12_device *device)
+{
+    unsigned int i;
+    for (i = 0; i < device->memory_properties.memoryTypeCount; ++i)
+        if (!(device->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
+            return true;
+    return false;
+}
+
+static HRESULT vkd3d_select_memory_type(struct d3d12_device *device, uint32_t memory_type_mask,
+        const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, unsigned int *type_index)
 {
     const VkPhysicalDeviceMemoryProperties *memory_info = &device->memory_properties;
     VkMemoryPropertyFlags flags[3];
@@ -58,16 +67,36 @@ static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32
             break;
 
         case D3D12_HEAP_TYPE_CUSTOM:
-            FIXME("Custom heaps not supported yet.\n");
-            flags[count++] = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
-                    | VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
-            flags[count++] = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
-            flags[count++] = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+            if (heap_properties->MemoryPoolPreference == D3D12_MEMORY_POOL_UNKNOWN
+                    || (heap_properties->MemoryPoolPreference == D3D12_MEMORY_POOL_L1
+                    && (is_cpu_accessible_heap(heap_properties) || !is_numa_device(device))))
+            {
+                WARN("Invalid memory pool preference.\n");
+                return E_INVALIDARG;
+            }
+
+            switch (heap_properties->CPUPageProperty)
+            {
+                case D3D12_CPU_PAGE_PROPERTY_WRITE_BACK:
+                    flags[count++] = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
+                            | VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+                    /* Fall through. */
+                case D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE:
+                    flags[count++] = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+                    /* Fall through. */
+                case D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE:
+                    flags[count++] = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+                    break;
+                case D3D12_CPU_PAGE_PROPERTY_UNKNOWN:
+                default:
+                    WARN("Invalid CPU page property.\n");
+                    return E_INVALIDARG;
+            }
             break;
 
         default:
             WARN("Invalid heap type %#x.\n", heap_properties->Type);
-            return ~0u;
+            return E_INVALIDARG;
     }
 
     for (j = 0; j < count; ++j)
@@ -79,11 +108,14 @@ static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32
             if (!(memory_type_mask & (1u << i)))
                 continue;
             if ((memory_info->memoryTypes[i].propertyFlags & preferred_flags) == preferred_flags)
-                return i;
+            {
+                *type_index = i;
+                return S_OK;
+            }
         }
     }
 
-    return ~0u;
+    return E_FAIL;
 }
 
 static HRESULT vkd3d_allocate_device_memory(struct d3d12_device *device,
@@ -95,6 +127,7 @@ static HRESULT vkd3d_allocate_device_memory(struct d3d12_device *device,
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
     VkMemoryAllocateInfo allocate_info;
     VkResult vr;
+    HRESULT hr;
 
     TRACE("Memory requirements: size %#"PRIx64", alignment %#"PRIx64".\n",
             memory_requirements->size, memory_requirements->alignment);
@@ -102,14 +135,13 @@ static HRESULT vkd3d_allocate_device_memory(struct d3d12_device *device,
     allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
     allocate_info.pNext = dedicated_allocate_info;
     allocate_info.allocationSize = memory_requirements->size;
-    allocate_info.memoryTypeIndex = vkd3d_select_memory_type(device,
-            memory_requirements->memoryTypeBits, heap_properties, heap_flags);
-
-    if (allocate_info.memoryTypeIndex == ~0u)
+    if (FAILED(hr = vkd3d_select_memory_type(device, memory_requirements->memoryTypeBits,
+            heap_properties, heap_flags, &allocate_info.memoryTypeIndex)))
     {
-        FIXME("Failed to find suitable memory type (allowed types %#x).\n", memory_requirements->memoryTypeBits);
+        if (hr != E_INVALIDARG)
+            FIXME("Failed to find suitable memory type (allowed types %#x).\n", memory_requirements->memoryTypeBits);
         *vk_memory = VK_NULL_HANDLE;
-        return E_FAIL;
+        return hr;
     }
 
     TRACE("Allocating memory type %u.\n", allocate_info.memoryTypeIndex);
-- 
2.23.0




More information about the wine-devel mailing list