From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- This supersedes patch 172977.
libs/vkd3d/device.c | 66 ++++++++++++++++++++++++++++++++++++++-------- libs/vkd3d/resource.c | 11 +------- libs/vkd3d/vkd3d_private.h | 1 + tests/d3d12.c | 48 +++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 13ebc70..0624318 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2398,11 +2398,29 @@ done: return S_OK; }
+bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) +{ + unsigned int i; + + if (coherent) + *coherent = true; + + for (i = 0; i < device->memory_properties.memoryTypeCount; ++i) + { + if (!(device->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) + return false; + if (coherent && !(device->memory_properties.memoryTypes[i].propertyFlags + & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) + *coherent = false; + } + + return true; +} + static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *iface, D3D12_FEATURE feature, void *feature_data, UINT feature_data_size) { struct d3d12_device *device = impl_from_ID3D12Device(iface); - unsigned int i;
TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n", iface, feature, feature_data, feature_data_size); @@ -2443,6 +2461,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * case D3D12_FEATURE_ARCHITECTURE: { D3D12_FEATURE_DATA_ARCHITECTURE *data = feature_data; + bool coherent;
if (feature_data_size != sizeof(*data)) { @@ -2459,15 +2478,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * WARN("Assuming device does not support tile based rendering.\n"); data->TileBasedRenderer = FALSE;
- data->UMA = TRUE; - data->CacheCoherentUMA = TRUE; - for (i = 0; i < device->memory_properties.memoryTypeCount; ++i) - { - if (!(device->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) - data->UMA = FALSE; - if (!(device->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) - data->CacheCoherentUMA = FALSE; - } + data->UMA = d3d12_device_is_uma(device, &coherent); + data->CacheCoherentUMA = data->UMA ? coherent : FALSE;
TRACE("Tile based renderer %#x, UMA %#x, cache coherent UMA %#x.\n", data->TileBasedRenderer, data->UMA, data->CacheCoherentUMA); @@ -2975,11 +2987,43 @@ invalid: static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device *iface, D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type) { - FIXME("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x stub!\n", + struct d3d12_device *device = impl_from_ID3D12Device(iface); + bool coherent; + + TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n", iface, heap_properties, node_mask, heap_type);
debug_ignored_node_mask(node_mask);
+ heap_properties->Type = D3D12_HEAP_TYPE_CUSTOM; + + switch (heap_type) + { + case D3D12_HEAP_TYPE_DEFAULT: + heap_properties->CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE; + heap_properties->MemoryPoolPreference = d3d12_device_is_uma(device, NULL) + ? D3D12_MEMORY_POOL_L0 : D3D12_MEMORY_POOL_L1; + break; + + case D3D12_HEAP_TYPE_UPLOAD: + heap_properties->CPUPageProperty = d3d12_device_is_uma(device, &coherent) && coherent + ? D3D12_CPU_PAGE_PROPERTY_WRITE_BACK : D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE; + heap_properties->MemoryPoolPreference = D3D12_MEMORY_POOL_L0; + break; + + case D3D12_HEAP_TYPE_READBACK: + heap_properties->CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK; + heap_properties->MemoryPoolPreference = D3D12_MEMORY_POOL_L0; + break; + + default: + FIXME("Unhandled heap type %#x.\n", heap_type); + break; + }; + + heap_properties->CreationNodeMask = 1; + heap_properties->VisibleNodeMask = 1; + return heap_properties; }
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index d6e999e..e93d50b 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -34,15 +34,6 @@ static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *propertie return true; }
-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) { @@ -69,7 +60,7 @@ static HRESULT vkd3d_select_memory_type(struct d3d12_device *device, uint32_t me case D3D12_HEAP_TYPE_CUSTOM: 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)))) + && (is_cpu_accessible_heap(heap_properties) || d3d12_device_is_uma(device, NULL)))) { WARN("Invalid memory pool preference.\n"); return E_INVALIDARG; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 2d62fda..daa521d 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1102,6 +1102,7 @@ HRESULT d3d12_device_create(struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info, struct d3d12_device **device) DECLSPEC_HIDDEN; struct vkd3d_queue *d3d12_device_get_vkd3d_queue(struct d3d12_device *device, D3D12_COMMAND_LIST_TYPE type) DECLSPEC_HIDDEN; +bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) DECLSPEC_HIDDEN; void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason, const char *message, ...) VKD3D_PRINTF_FUNC(3, 4) DECLSPEC_HIDDEN; struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) DECLSPEC_HIDDEN; diff --git a/tests/d3d12.c b/tests/d3d12.c index 858cf99..0f843b4 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -1991,6 +1991,7 @@ static void test_create_committed_resource(void)
static void test_create_heap(void) { + D3D12_FEATURE_DATA_ARCHITECTURE architecture; D3D12_FEATURE_DATA_D3D12_OPTIONS options; D3D12_HEAP_DESC desc, result_desc; ID3D12Device *device, *tmp_device; @@ -2137,6 +2138,53 @@ static void test_create_heap(void) refcount = ID3D12Heap_Release(heap); ok(!refcount, "ID3D12Heap has %u references left.\n", (unsigned int)refcount);
+ memset(&architecture, 0, sizeof(architecture)); + hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ARCHITECTURE, &architecture, sizeof(architecture)); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + for (i = D3D12_HEAP_TYPE_DEFAULT; i < D3D12_HEAP_TYPE_CUSTOM; ++i) + { + vkd3d_test_set_context("Test %u\n", i); + desc.Properties = ID3D12Device_GetCustomHeapProperties(device, 1, i); + ok(desc.Properties.Type == D3D12_HEAP_TYPE_CUSTOM, "Got unexpected heap type %#x.\n", desc.Properties.Type); + + switch (i) + { + case D3D12_HEAP_TYPE_DEFAULT: + ok(desc.Properties.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, + "Got unexpected CPUPageProperty %#x.\n", desc.Properties.CPUPageProperty); + ok(desc.Properties.MemoryPoolPreference == (architecture.UMA + ? D3D12_MEMORY_POOL_L0 : D3D12_MEMORY_POOL_L1), + "Got unexpected MemoryPoolPreference %#x.\n", desc.Properties.MemoryPoolPreference); + break; + + case D3D12_HEAP_TYPE_UPLOAD: + ok(desc.Properties.CPUPageProperty == (architecture.CacheCoherentUMA + ? D3D12_CPU_PAGE_PROPERTY_WRITE_BACK : D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE), + "Got unexpected CPUPageProperty %#x.\n", desc.Properties.CPUPageProperty); + ok(desc.Properties.MemoryPoolPreference == D3D12_MEMORY_POOL_L0, + "Got unexpected MemoryPoolPreference %#x.\n", desc.Properties.MemoryPoolPreference); + break; + + case D3D12_HEAP_TYPE_READBACK: + ok(desc.Properties.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK, + "Got unexpected CPUPageProperty %#x.\n", desc.Properties.CPUPageProperty); + ok(desc.Properties.MemoryPoolPreference == D3D12_MEMORY_POOL_L0, + "Got unexpected MemoryPoolPreference %#x.\n", desc.Properties.MemoryPoolPreference); + break; + + default: + ok(0, "Invalid heap type %#x.\n", i); + continue; + } + + hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + result_desc = ID3D12Heap_GetDesc(heap); + check_heap_desc(&result_desc, &desc); + ID3D12Heap_Release(heap); + } + vkd3d_test_set_context(NULL); + is_pool_L1_supported = is_memory_pool_L1_supported(device); desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM; desc.Properties.CreationNodeMask = 1;