From 74d1c72b353768197d56bdd492de105a688d90a5 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 29 Aug 2022 12:57:41 -0700 Subject: [PATCH] dzn: Support device factories in addition to global device creation Acked-by: Boris Brezillon Part-of: --- src/microsoft/vulkan/dzn_device.c | 32 +++++++++++-- src/microsoft/vulkan/dzn_private.h | 7 +-- src/microsoft/vulkan/dzn_util.c | 95 +++++++++++++++++++++++--------------- 3 files changed, 92 insertions(+), 42 deletions(-) diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c index edca4fb..6790e1d 100644 --- a/src/microsoft/vulkan/dzn_device.c +++ b/src/microsoft/vulkan/dzn_device.c @@ -168,12 +168,33 @@ dzn_instance_destroy(struct dzn_instance *instance, const VkAllocationCallbacks dzn_physical_device_destroy(pdev); } + if (instance->factory) + ID3D12DeviceFactory_Release(instance->factory); + util_dl_close(instance->d3d12_mod); vk_instance_finish(&instance->vk); vk_free2(vk_default_allocator(), alloc, instance); } +static ID3D12DeviceFactory * +try_create_device_factory(struct util_dl_library *d3d12_mod) +{ + /* A device factory allows us to isolate things like debug layer enablement from other callers, + * and can potentially even refer to a different D3D12 redist implementation from others. + */ + ID3D12DeviceFactory *factory = NULL; + + PFN_D3D12_GET_INTERFACE D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)util_dl_get_proc_address(d3d12_mod, "D3D12GetInterface"); + if (!D3D12GetInterface) { + mesa_loge("Failed to retrieve D3D12GetInterface\n"); + return NULL; + } + + (void)D3D12GetInterface(&CLSID_D3D12DeviceFactory, &IID_ID3D12DeviceFactory, (void **)&factory); + return factory; +} + static VkResult dzn_instance_create(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, @@ -246,10 +267,12 @@ dzn_instance_create(const VkInstanceCreateInfo *pCreateInfo, return vk_error(NULL, VK_ERROR_INITIALIZATION_FAILED); } + instance->factory = try_create_device_factory(instance->d3d12_mod); + if (instance->debug_flags & DZN_DEBUG_D3D12) - d3d12_enable_debug_layer(instance->d3d12_mod); + d3d12_enable_debug_layer(instance->d3d12_mod, instance->factory); if (instance->debug_flags & DZN_DEBUG_GBV) - d3d12_enable_gpu_validation(instance->d3d12_mod); + d3d12_enable_gpu_validation(instance->d3d12_mod, instance->factory); instance->sync_binary_type = vk_sync_binary_get_type(&dzn_sync_type); @@ -597,7 +620,10 @@ dzn_physical_device_get_d3d12_dev(struct dzn_physical_device *pdev) mtx_lock(&pdev->dev_lock); if (!pdev->dev) { - pdev->dev = d3d12_create_device(instance->d3d12_mod, pdev->adapter, !instance->dxil_validator); + pdev->dev = d3d12_create_device(instance->d3d12_mod, + pdev->adapter, + instance->factory, + !instance->dxil_validator); dzn_physical_device_cache_caps(pdev); dzn_physical_device_init_memory(pdev); diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index fd49531..ca780f1 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -231,13 +231,13 @@ PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE d3d12_get_serialize_root_sig(struct util_dl_library *d3d12_mod); void -d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod); +d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory); void -d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod); +d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory); ID3D12Device2 * -d3d12_create_device(struct util_dl_library *d3d12_mod, IUnknown *adapter, bool experimental_features); +d3d12_create_device(struct util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory *factory, bool experimental_features); struct dzn_queue { struct vk_queue vk; @@ -1048,6 +1048,7 @@ struct dzn_instance { struct dxil_validator *dxil_validator; struct util_dl_library *d3d12_mod; + ID3D12DeviceFactory *factory; struct { PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE serialize_root_sig; } d3d12; diff --git a/src/microsoft/vulkan/dzn_util.c b/src/microsoft/vulkan/dzn_util.c index 0dba79b..19a938d 100644 --- a/src/microsoft/vulkan/dzn_util.c +++ b/src/microsoft/vulkan/dzn_util.c @@ -297,30 +297,37 @@ dzn_translate_rect(D3D12_RECT *out, } static ID3D12Debug * -get_debug_interface(struct util_dl_library *d3d12_mod) +get_debug_interface(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory) { typedef HRESULT(WINAPI *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID riid, void **ppFactory); PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface; - D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)util_dl_get_proc_address(d3d12_mod, "D3D12GetDebugInterface"); - if (!D3D12GetDebugInterface) { - mesa_loge("failed to load D3D12GetDebugInterface from D3D12.DLL\n"); - return NULL; - } - ID3D12Debug *debug; - if (FAILED(D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug))) { - mesa_loge("D3D12GetDebugInterface failed\n"); - return NULL; + if (factory) { + if (FAILED(ID3D12DeviceFactory_GetConfigurationInterface(factory, &CLSID_D3D12Debug, &IID_ID3D12Debug, (void **)&debug))) { + mesa_loge("Failed to retrieve ID3D12Debug from device factory\n"); + return NULL; + } + } else { + D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)util_dl_get_proc_address(d3d12_mod, "D3D12GetDebugInterface"); + if (!D3D12GetDebugInterface) { + mesa_loge("failed to load D3D12GetDebugInterface from D3D12.DLL\n"); + return NULL; + } + + if (FAILED(D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug))) { + mesa_loge("D3D12GetDebugInterface failed\n"); + return NULL; + } } return debug; } void -d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod) +d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory) { - ID3D12Debug *debug = get_debug_interface(d3d12_mod); + ID3D12Debug *debug = get_debug_interface(d3d12_mod, factory); if (debug) { ID3D12Debug_EnableDebugLayer(debug); ID3D12Debug_Release(debug); @@ -328,9 +335,9 @@ d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod) } void -d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod) +d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory) { - ID3D12Debug *debug = get_debug_interface(d3d12_mod); + ID3D12Debug *debug = get_debug_interface(d3d12_mod, factory); if (debug) { ID3D12Debug3 *debug3; if (SUCCEEDED(ID3D12Debug_QueryInterface(debug, @@ -344,38 +351,54 @@ d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod) } ID3D12Device2 * -d3d12_create_device(struct util_dl_library *d3d12_mod, IUnknown *adapter, bool experimental_features) +d3d12_create_device(struct util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory *factory, bool experimental_features) { - typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown *, D3D_FEATURE_LEVEL, REFIID, void **); - PFN_D3D12CREATEDEVICE D3D12CreateDevice; - #ifdef _WIN32 if (experimental_features) #endif { - typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID *, void *, UINT *); - PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures = - (PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures"); - if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) { - mesa_loge("failed to enable experimental shader models\n"); - return NULL; + if (factory) { + if (FAILED(ID3D12DeviceFactory_EnableExperimentalFeatures(factory, 1, &D3D12ExperimentalShaderModels, NULL, NULL))) { + mesa_loge("failed to enable experimental shader models\n"); + return NULL; + } + } else { + typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID *, void *, UINT *); + PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures = + (PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures"); + if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) { + mesa_loge("failed to enable experimental shader models\n"); + return NULL; + } } } - D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice"); - if (!D3D12CreateDevice) { - mesa_loge("failed to load D3D12CreateDevice from D3D12\n"); - return NULL; - } - ID3D12Device2 *dev; - if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, - &IID_ID3D12Device2, - (void **)&dev))) - return dev; + if (factory) { + if (FAILED(ID3D12DeviceFactory_CreateDevice(factory, adapter, D3D_FEATURE_LEVEL_11_0, + &IID_ID3D12Device2, + (void **)&dev))) { + mesa_loge("ID3D12DeviceFactory::CreateDevice failed\n"); + return NULL; + } + } else { + typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown *, D3D_FEATURE_LEVEL, REFIID, void **); + PFN_D3D12CREATEDEVICE D3D12CreateDevice; - mesa_loge("D3D12CreateDevice failed\n"); - return NULL; + D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice"); + if (!D3D12CreateDevice) { + mesa_loge("failed to load D3D12CreateDevice from D3D12\n"); + return NULL; + } + + if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, + &IID_ID3D12Device2, + (void **)&dev))) { + mesa_loge("D3D12CreateDevice failed\n"); + return NULL; + } + } + return dev; } PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE -- 2.7.4