dzn: Support device factories in addition to global device creation

Acked-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18306>
This commit is contained in:
Jesse Natalie 2022-08-29 12:57:41 -07:00 committed by Marge Bot
parent 4696aa484f
commit 74d1c72b35
3 changed files with 92 additions and 42 deletions

View file

@ -168,12 +168,33 @@ dzn_instance_destroy(struct dzn_instance *instance, const VkAllocationCallbacks
dzn_physical_device_destroy(pdev); dzn_physical_device_destroy(pdev);
} }
if (instance->factory)
ID3D12DeviceFactory_Release(instance->factory);
util_dl_close(instance->d3d12_mod); util_dl_close(instance->d3d12_mod);
vk_instance_finish(&instance->vk); vk_instance_finish(&instance->vk);
vk_free2(vk_default_allocator(), alloc, instance); 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 static VkResult
dzn_instance_create(const VkInstanceCreateInfo *pCreateInfo, dzn_instance_create(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, const VkAllocationCallbacks *pAllocator,
@ -246,10 +267,12 @@ dzn_instance_create(const VkInstanceCreateInfo *pCreateInfo,
return vk_error(NULL, VK_ERROR_INITIALIZATION_FAILED); return vk_error(NULL, VK_ERROR_INITIALIZATION_FAILED);
} }
instance->factory = try_create_device_factory(instance->d3d12_mod);
if (instance->debug_flags & DZN_DEBUG_D3D12) 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) 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); 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); mtx_lock(&pdev->dev_lock);
if (!pdev->dev) { 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_cache_caps(pdev);
dzn_physical_device_init_memory(pdev); dzn_physical_device_init_memory(pdev);

View file

@ -231,13 +231,13 @@ PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE
d3d12_get_serialize_root_sig(struct util_dl_library *d3d12_mod); d3d12_get_serialize_root_sig(struct util_dl_library *d3d12_mod);
void void
d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod); d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory);
void void
d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod); d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory);
ID3D12Device2 * 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 dzn_queue {
struct vk_queue vk; struct vk_queue vk;
@ -1048,6 +1048,7 @@ struct dzn_instance {
struct dxil_validator *dxil_validator; struct dxil_validator *dxil_validator;
struct util_dl_library *d3d12_mod; struct util_dl_library *d3d12_mod;
ID3D12DeviceFactory *factory;
struct { struct {
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE serialize_root_sig; PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE serialize_root_sig;
} d3d12; } d3d12;

View file

@ -297,30 +297,37 @@ dzn_translate_rect(D3D12_RECT *out,
} }
static ID3D12Debug * 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); typedef HRESULT(WINAPI *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID riid, void **ppFactory);
PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface; 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; ID3D12Debug *debug;
if (FAILED(D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug))) { if (factory) {
mesa_loge("D3D12GetDebugInterface failed\n"); if (FAILED(ID3D12DeviceFactory_GetConfigurationInterface(factory, &CLSID_D3D12Debug, &IID_ID3D12Debug, (void **)&debug))) {
return NULL; 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; return debug;
} }
void 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) { if (debug) {
ID3D12Debug_EnableDebugLayer(debug); ID3D12Debug_EnableDebugLayer(debug);
ID3D12Debug_Release(debug); ID3D12Debug_Release(debug);
@ -328,9 +335,9 @@ d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod)
} }
void 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) { if (debug) {
ID3D12Debug3 *debug3; ID3D12Debug3 *debug3;
if (SUCCEEDED(ID3D12Debug_QueryInterface(debug, if (SUCCEEDED(ID3D12Debug_QueryInterface(debug,
@ -344,38 +351,54 @@ d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod)
} }
ID3D12Device2 * 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 #ifdef _WIN32
if (experimental_features) if (experimental_features)
#endif #endif
{ {
typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID *, void *, UINT *); if (factory) {
PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures = if (FAILED(ID3D12DeviceFactory_EnableExperimentalFeatures(factory, 1, &D3D12ExperimentalShaderModels, NULL, NULL))) {
(PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures"); mesa_loge("failed to enable experimental shader models\n");
if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) { return 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; ID3D12Device2 *dev;
if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, if (factory) {
&IID_ID3D12Device2, if (FAILED(ID3D12DeviceFactory_CreateDevice(factory, adapter, D3D_FEATURE_LEVEL_11_0,
(void **)&dev))) &IID_ID3D12Device2,
return dev; (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"); D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice");
return NULL; 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 PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE