Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- v3: Add D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE to interface definition. --- include/vkd3d_d3d12.idl | 1 + libs/vkd3d/resource.c | 64 ++++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 8489f56..ec8b83d 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -309,6 +309,7 @@ typedef enum D3D12_HEAP_TYPE typedef enum D3D12_CPU_PAGE_PROPERTY { D3D12_CPU_PAGE_PROPERTY_UNKNOWN = 0, + D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE = 1, D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE = 2, D3D12_CPU_PAGE_PROPERTY_WRITE_BACK = 3, } D3D12_CPU_PAGE_PROPERTY; 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);