diff --git a/src/d3d9/d3d9_interfaces.h b/src/d3d9/d3d9_interfaces.h index cb5d7db74a8..b9dd807e330 100644 --- a/src/d3d9/d3d9_interfaces.h +++ b/src/d3d9/d3d9_interfaces.h @@ -65,11 +65,13 @@ ID3D9VkInteropInterface : public IUnknown { * \param [in] Adapter Adapter ordinal * \param [out] pCreateInfo The Vulkan device create info * \param [out] pQueueFamilies The required queue families + * \param [out] pFeatures The required device features */ virtual HRESULT STDMETHODCALLTYPE GetDeviceCreateInfo( - UINT Adapter, - VkDeviceCreateInfo* pCreateInfo, - D3D9VkQueueFamilies* pQueueFamilies) = 0; + UINT Adapter, + VkDeviceCreateInfo* pCreateInfo, + D3D9VkQueueFamilies* pQueueFamilies, + VkPhysicalDeviceFeatures2* pFeatures) = 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..d4a8e72ac34 100644 --- a/src/d3d9/d3d9_interop.cpp +++ b/src/d3d9/d3d9_interop.cpp @@ -52,10 +52,11 @@ namespace dxvk { } HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::GetDeviceCreateInfo( - UINT Adapter, - VkDeviceCreateInfo* pCreateInfo, - D3D9VkQueueFamilies* pQueueFamilies) { - if (unlikely(pCreateInfo == nullptr && pQueueFamilies == nullptr)) + UINT Adapter, + VkDeviceCreateInfo* pCreateInfo, + D3D9VkQueueFamilies* pQueueFamilies, + VkPhysicalDeviceFeatures2* pFeatures) { + if (unlikely(pCreateInfo == nullptr && pQueueFamilies == nullptr && pFeatures == nullptr)) return D3DERR_INVALIDCALL; auto* adapter = m_interface->GetAdapter(Adapter); @@ -65,12 +66,16 @@ 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) + if (pCreateInfo != nullptr) { + createInfo.info.enabledLayerCount = 0; + createInfo.info.ppEnabledLayerNames = nullptr; + *pCreateInfo = createInfo.info; + } if (pQueueFamilies != nullptr) { pQueueFamilies->graphics = createInfo.queueFamilies.graphics; @@ -78,6 +83,10 @@ namespace dxvk { pQueueFamilies->sparse = createInfo.queueFamilies.sparse; } + if (pFeatures != nullptr) { + pFeatures = &createInfo.features.core; + } + return D3D_OK; } diff --git a/src/d3d9/d3d9_interop.h b/src/d3d9/d3d9_interop.h index 3a0786c322b..78b1f41c31e 100644 --- a/src/d3d9/d3d9_interop.h +++ b/src/d3d9/d3d9_interop.h @@ -9,6 +9,8 @@ namespace dxvk { class D3D9CommonTexture; class D3D9DeviceEx; struct D3D9_COMMON_TEXTURE_DESC; + struct DxvkDeviceCreateInfo; + struct DxvkDeviceFeatures; class D3D9VkInteropInterface final : public ID3D9VkInteropInterface { @@ -35,9 +37,10 @@ namespace dxvk { VkPhysicalDevice* pPhysicalDevice); HRESULT STDMETHODCALLTYPE GetDeviceCreateInfo( - UINT Adapter, - VkDeviceCreateInfo* pCreateInfo, - D3D9VkQueueFamilies* pQueueFamilies); + UINT Adapter, + VkDeviceCreateInfo* pCreateInfo, + D3D9VkQueueFamilies* pQueueFamilies, + VkPhysicalDeviceFeatures2* pFeatures); HRESULT STDMETHODCALLTYPE ImportDevice( UINT Adapter, @@ -52,6 +55,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; }; /**