diff --git a/src/d3d9/d3d9_interfaces.h b/src/d3d9/d3d9_interfaces.h index cb5d7db74a8..f931bac8361 100644 --- a/src/d3d9/d3d9_interfaces.h +++ b/src/d3d9/d3d9_interfaces.h @@ -6,12 +6,14 @@ using D3D9VkQueueLockCallback = void(bool); /** - * \brief Device queue info + * \brief Device create info */ -struct D3D9VkQueueFamilies { - uint32_t graphics; - uint32_t transfer; - uint32_t sparse; +struct D3D9VkDeviceCreateInfo { + VkDeviceCreateInfo* info; + VkPhysicalDeviceFeatures2* features; + uint32_t graphics; + uint32_t transfer; + uint32_t sparse; }; /** @@ -62,14 +64,15 @@ ID3D9VkInteropInterface : public IUnknown { /** * \brief Gets the VkDeviceCreateInfo for a D3D9 adapter * + * Pointers returned are guaranteed to be valid until + * the next call to GetDeviceCreateInfo or Release. + * * \param [in] Adapter Adapter ordinal * \param [out] pCreateInfo The Vulkan device create info - * \param [out] pQueueFamilies The required queue families */ virtual HRESULT STDMETHODCALLTYPE GetDeviceCreateInfo( - UINT Adapter, - VkDeviceCreateInfo* pCreateInfo, - D3D9VkQueueFamilies* pQueueFamilies) = 0; + UINT Adapter, + D3D9VkDeviceCreateInfo* pCreateInfo) = 0; /** * \brief Create a D3D9 device for an existing Vulkan device diff --git a/src/d3d9/d3d9_interop.cpp b/src/d3d9/d3d9_interop.cpp index a1b7bbbe8ea..9b282ed1376 100644 --- a/src/d3d9/d3d9_interop.cpp +++ b/src/d3d9/d3d9_interop.cpp @@ -52,10 +52,9 @@ namespace dxvk { } HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::GetDeviceCreateInfo( - UINT Adapter, - VkDeviceCreateInfo* pCreateInfo, - D3D9VkQueueFamilies* pQueueFamilies) { - if (unlikely(pCreateInfo == nullptr && pQueueFamilies == nullptr)) + UINT Adapter, + D3D9VkDeviceCreateInfo* pCreateInfo) { + if (unlikely(pCreateInfo == nullptr)) return D3DERR_INVALIDCALL; auto* adapter = m_interface->GetAdapter(Adapter); @@ -65,18 +64,18 @@ namespace dxvk { auto dxvkAdapter = adapter->GetDXVKAdapter(); - DxvkDeviceCreateInfo createInfo; + DxvkDeviceCreateInfo& createInfo = m_deviceCreateInfos[Adapter]; if (!dxvkAdapter->getDeviceCreateInfo(m_interface->GetInstance(), D3D9DeviceEx::GetDeviceFeatures(dxvkAdapter), false, createInfo)) return D3DERR_INVALIDCALL; - if (pCreateInfo != nullptr) - *pCreateInfo = createInfo.info; + createInfo.info.enabledLayerCount = 0; + createInfo.info.ppEnabledLayerNames = nullptr; - if (pQueueFamilies != nullptr) { - pQueueFamilies->graphics = createInfo.queueFamilies.graphics; - pQueueFamilies->transfer = createInfo.queueFamilies.transfer; - pQueueFamilies->sparse = createInfo.queueFamilies.sparse; - } + pCreateInfo->info = &createInfo.info; + pCreateInfo->features = &createInfo.features.core; + pCreateInfo->graphics = createInfo.queueFamilies.graphics; + pCreateInfo->transfer = createInfo.queueFamilies.transfer; + pCreateInfo->sparse = createInfo.queueFamilies.sparse; return D3D_OK; } diff --git a/src/d3d9/d3d9_interop.h b/src/d3d9/d3d9_interop.h index 3a0786c322b..a6c0cccea76 100644 --- a/src/d3d9/d3d9_interop.h +++ b/src/d3d9/d3d9_interop.h @@ -2,6 +2,7 @@ #include "d3d9_interfaces.h" #include "d3d9_multithread.h" +#include "../dxvk/dxvk_adapter.h" namespace dxvk { @@ -35,9 +36,8 @@ namespace dxvk { VkPhysicalDevice* pPhysicalDevice); HRESULT STDMETHODCALLTYPE GetDeviceCreateInfo( - UINT Adapter, - VkDeviceCreateInfo* pCreateInfo, - D3D9VkQueueFamilies* pQueueFamilies); + UINT Adapter, + D3D9VkDeviceCreateInfo* pCreateInfo); HRESULT STDMETHODCALLTYPE ImportDevice( UINT Adapter, @@ -52,6 +52,7 @@ namespace dxvk { private: D3D9InterfaceEx* m_interface; + std::unordered_map m_deviceCreateInfos; }; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 947a9b3ded0..b04fe5a0089 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -274,10 +274,12 @@ namespace dxvk { bool DxvkAdapter::getDeviceCreateInfo( const Rc& instance, - DxvkDeviceFeatures enabledFeatures, + DxvkDeviceFeatures baseEnabledFeatures, bool logDeviceInfo, DxvkDeviceCreateInfo& createInfo) const { - auto& [info, queueFamilies, extensionsEnabled, devExtensions, enableCudaInterop] = createInfo; + auto& [info, queueFamilies, extensionsEnabled, extensionNameList, devExtensions, enableCudaInterop, queueInfos, enabledFeatures] = createInfo; + + enabledFeatures = baseEnabledFeatures; auto devExtensionList = getExtensionList(devExtensions); @@ -309,7 +311,7 @@ namespace dxvk { // Enable additional extensions if necessary extensionsEnabled.merge(m_extraExtensions); - DxvkNameList extensionNameList = extensionsEnabled.toNameList(); + extensionNameList = extensionsEnabled.toNameList(); // Always enable robust buffer access enabledFeatures.core.features.robustBufferAccess = VK_TRUE; @@ -461,8 +463,6 @@ namespace dxvk { // Create the requested queues float queuePriority = 1.0f; - std::vector queueInfos; - std::unordered_set queueFamiliySet; queueFamilies = findQueueFamilies(); @@ -504,7 +504,7 @@ namespace dxvk { if (!getDeviceCreateInfo(instance, enabledFeatures, true, createInfo)) throw DxvkError("DxvkAdapter: Failed to create device"); - auto& [info, queueFamilies, extensionsEnabled, devExtensions, enableCudaInterop] = createInfo; + auto& [info, queueFamilies, extensionsEnabled, extensionNameList, devExtensions, enableCudaInterop, queueInfos, features] = createInfo; VkDevice device = VK_NULL_HANDLE; VkResult vr = m_vki->vkCreateDevice(m_handle, &info, nullptr, &device); @@ -518,9 +518,8 @@ namespace dxvk { extensionsEnabled.disableExtension(devExtensions.nvxBinaryImport); extensionsEnabled.disableExtension(devExtensions.nvxImageViewHandle); - enabledFeatures.vk12.bufferDeviceAddress = VK_FALSE; + features.vk12.bufferDeviceAddress = VK_FALSE; - DxvkNameList extensionNameList = extensionsEnabled.toNameList(); info.enabledExtensionCount = extensionNameList.count(); info.ppEnabledExtensionNames = extensionNameList.names(); @@ -537,7 +536,7 @@ namespace dxvk { queues.transfer = getDeviceQueue(vkd, queueFamilies.transfer, 0); queues.sparse = getDeviceQueue(vkd, queueFamilies.sparse, 0); - return new DxvkDevice(instance, this, vkd, enabledFeatures, queues, DxvkQueueCallback()); + return new DxvkDevice(instance, this, vkd, features, queues, DxvkQueueCallback()); } diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index 90b6015c84e..760c57e4bf3 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -73,11 +73,14 @@ namespace dxvk { * \brief Device create info */ struct DxvkDeviceCreateInfo { - VkDeviceCreateInfo info; - DxvkAdapterQueueIndices queueFamilies; - DxvkNameSet extensionsEnabled; - DxvkDeviceExtensions devExtensions; - bool enableCudaInterop; + VkDeviceCreateInfo info; + DxvkAdapterQueueIndices queueFamilies; + DxvkNameSet extensionsEnabled; + DxvkNameList extensionNameList; + DxvkDeviceExtensions devExtensions; + bool enableCudaInterop; + std::vector queueInfos; + DxvkDeviceFeatures features; }; /**