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);
}
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);

View file

@ -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;

View file

@ -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