vkd3d: Add support for custom heap properties.

Signed-off-by: Conor McCarthy <cmccarthy@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Conor McCarthy 2019-10-25 11:13:21 +10:00 committed by Alexandre Julliard
parent 832f47edd3
commit 87cc75b7e6
2 changed files with 49 additions and 16 deletions

View File

@ -309,6 +309,7 @@ typedef enum D3D12_HEAP_TYPE
typedef enum D3D12_CPU_PAGE_PROPERTY typedef enum D3D12_CPU_PAGE_PROPERTY
{ {
D3D12_CPU_PAGE_PROPERTY_UNKNOWN = 0, 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_COMBINE = 2,
D3D12_CPU_PAGE_PROPERTY_WRITE_BACK = 3, D3D12_CPU_PAGE_PROPERTY_WRITE_BACK = 3,
} D3D12_CPU_PAGE_PROPERTY; } D3D12_CPU_PAGE_PROPERTY;

View File

@ -34,8 +34,17 @@ static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *propertie
return true; return true;
} }
static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32_t memory_type_mask, static bool is_numa_device(struct d3d12_device *device)
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags) {
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; const VkPhysicalDeviceMemoryProperties *memory_info = &device->memory_properties;
VkMemoryPropertyFlags flags[3]; VkMemoryPropertyFlags flags[3];
@ -58,16 +67,36 @@ static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32
break; break;
case D3D12_HEAP_TYPE_CUSTOM: case D3D12_HEAP_TYPE_CUSTOM:
FIXME("Custom heaps not supported yet.\n"); if (heap_properties->MemoryPoolPreference == D3D12_MEMORY_POOL_UNKNOWN
flags[count++] = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT || (heap_properties->MemoryPoolPreference == D3D12_MEMORY_POOL_L1
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; && (is_cpu_accessible_heap(heap_properties) || !is_numa_device(device))))
flags[count++] = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; {
flags[count++] = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 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; break;
default: default:
WARN("Invalid heap type %#x.\n", heap_properties->Type); WARN("Invalid heap type %#x.\n", heap_properties->Type);
return ~0u; return E_INVALIDARG;
} }
for (j = 0; j < count; ++j) 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))) if (!(memory_type_mask & (1u << i)))
continue; continue;
if ((memory_info->memoryTypes[i].propertyFlags & preferred_flags) == preferred_flags) 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, 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; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
VkMemoryAllocateInfo allocate_info; VkMemoryAllocateInfo allocate_info;
VkResult vr; VkResult vr;
HRESULT hr;
TRACE("Memory requirements: size %#"PRIx64", alignment %#"PRIx64".\n", TRACE("Memory requirements: size %#"PRIx64", alignment %#"PRIx64".\n",
memory_requirements->size, memory_requirements->alignment); 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.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocate_info.pNext = dedicated_allocate_info; allocate_info.pNext = dedicated_allocate_info;
allocate_info.allocationSize = memory_requirements->size; allocate_info.allocationSize = memory_requirements->size;
allocate_info.memoryTypeIndex = vkd3d_select_memory_type(device, if (FAILED(hr = vkd3d_select_memory_type(device, memory_requirements->memoryTypeBits,
memory_requirements->memoryTypeBits, heap_properties, heap_flags); heap_properties, heap_flags, &allocate_info.memoryTypeIndex)))
if (allocate_info.memoryTypeIndex == ~0u)
{ {
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; *vk_memory = VK_NULL_HANDLE;
return E_FAIL; return hr;
} }
TRACE("Allocating memory type %u.\n", allocate_info.memoryTypeIndex); TRACE("Allocating memory type %u.\n", allocate_info.memoryTypeIndex);