diff --git a/src/d3d9/d3d9_interface.cpp b/src/d3d9/d3d9_interface.cpp index 1adca971a43..46ec5d65401 100644 --- a/src/d3d9/d3d9_interface.cpp +++ b/src/d3d9/d3d9_interface.cpp @@ -93,7 +93,8 @@ namespace dxvk { return S_OK; } - if (riid == __uuidof(ID3D9VkInteropInterface)) { + if (riid == __uuidof(ID3D9VkInteropInterface) + || riid == __uuidof(ID3D9VkInteropInterface1)) { *ppvObject = ref(&m_d3d9Interop); return S_OK; } diff --git a/src/d3d9/d3d9_interfaces.h b/src/d3d9/d3d9_interfaces.h index 0d1b363250a..c4956e597b3 100644 --- a/src/d3d9/d3d9_interfaces.h +++ b/src/d3d9/d3d9_interfaces.h @@ -30,6 +30,26 @@ ID3D9VkInteropInterface : public IUnknown { VkPhysicalDevice* pPhysicalDevice) = 0; }; +/** + * \brief D3D9 interface for Vulkan interop - extended + * + * Provides access to the instance extension lists + * and everything provided by ID3D9VkInteropInterface + */ +MIDL_INTERFACE("d6589ed4-7a37-4096-bac2-223b25ae31d2") +ID3D9VkInteropInterface1 : public ID3D9VkInteropInterface { + /** + * \brief Gets a list of enabled instance extensions + * + * \param [out] pExtensionCount Number of extensions + * \param [out] ppExtensions List of extension names + * \returns D3DERR_MOREDATA if the list was truncated + */ + virtual HRESULT STDMETHODCALLTYPE GetInstanceExtensions( + UINT* pExtensionCount, + const char** ppExtensions) = 0; +}; + /** * \brief D3D9 texture interface for Vulkan interop * @@ -263,6 +283,7 @@ ID3D9VkExtSwapchain : public IUnknown { #ifndef _MSC_VER __CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd); +__CRT_UUID_DECL(ID3D9VkInteropInterface1, 0xd6589ed4,0x7a37,0x4096,0xba,0xc2,0x22,0x3b,0x25,0xae,0x31,0xd2); __CRT_UUID_DECL(ID3D9VkInteropTexture, 0xd56344f5,0x8d35,0x46fd,0x80,0x6d,0x94,0xc3,0x51,0xb4,0x72,0xc1); __CRT_UUID_DECL(ID3D9VkInteropDevice, 0x2eaa4b89,0x0107,0x4bdb,0x87,0xf7,0x0f,0x54,0x1c,0x49,0x3c,0xe0); __CRT_UUID_DECL(ID3D9VkExtSwapchain, 0x13776e93,0x4aa9,0x430a,0xa4,0xec,0xfe,0x9e,0x28,0x11,0x81,0xd5); diff --git a/src/d3d9/d3d9_interop.cpp b/src/d3d9/d3d9_interop.cpp index 802c334c34a..079f2919a65 100644 --- a/src/d3d9/d3d9_interop.cpp +++ b/src/d3d9/d3d9_interop.cpp @@ -51,6 +51,31 @@ namespace dxvk { } } + HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::GetInstanceExtensions( + UINT* pExtensionCount, + const char** ppExtensions) { + if (pExtensionCount == nullptr) + return D3DERR_INVALIDCALL; + + const DxvkNameList& extensions = m_interface->GetInstance()->extensionNameList(); + + if (ppExtensions == nullptr) { + *pExtensionCount = extensions.count(); + return D3D_OK; + } + + // Write + UINT count = 0; + UINT maxCount = *pExtensionCount; + for (uint32_t i = 0; i < extensions.count() && i < maxCount; i++) { + ppExtensions[i] = extensions.name(i); + count++; + } + + *pExtensionCount = count; + return (count < maxCount) ? D3DERR_MOREDATA : D3D_OK; + } + //////////////////////////////// // Texture Interop /////////////////////////////// diff --git a/src/d3d9/d3d9_interop.h b/src/d3d9/d3d9_interop.h index b939b6f860e..b5ef1e2661d 100644 --- a/src/d3d9/d3d9_interop.h +++ b/src/d3d9/d3d9_interop.h @@ -10,7 +10,7 @@ namespace dxvk { class D3D9DeviceEx; struct D3D9_COMMON_TEXTURE_DESC; - class D3D9VkInteropInterface final : public ID3D9VkInteropInterface { + class D3D9VkInteropInterface final : public ID3D9VkInteropInterface1 { public: @@ -34,6 +34,10 @@ namespace dxvk { UINT Adapter, VkPhysicalDevice* pPhysicalDevice); + HRESULT STDMETHODCALLTYPE GetInstanceExtensions( + UINT* pExtensionCount, + const char** ppExtensions); + private: D3D9InterfaceEx* m_interface; diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 7a88e03e190..b13eb273295 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -115,15 +115,14 @@ namespace dxvk { void DxvkInstance::createInstanceLoader(const DxvkInstanceImportInfo& args, DxvkInstanceFlags flags) { DxvkNameList layerList; - DxvkNameList extensionList; DxvkNameSet extensionSet; bool enablePerfEvents = false; bool enableValidation = false; if (args.instance) { - extensionList = DxvkNameList(args.extensionCount, args.extensionNames); - extensionSet = getExtensionSet(extensionList); + m_extensionNames = DxvkNameList(args.extensionCount, args.extensionNames); + extensionSet = getExtensionSet(m_extensionNames); auto extensionInfos = getExtensionList(m_extensions, true); @@ -168,11 +167,11 @@ namespace dxvk { extensionSet.merge(provider->getInstanceExtensions()); // Generate list of extensions to enable - extensionList = extensionSet.toNameList(); + m_extensionNames = extensionSet.toNameList(); } Logger::info("Enabled instance extensions:"); - this->logNameList(extensionList); + this->logNameList(m_extensionNames); // If necessary, create a new Vulkan instance VkInstance instance = args.instance; @@ -191,8 +190,8 @@ namespace dxvk { info.pApplicationInfo = &appInfo; info.enabledLayerCount = layerList.count(); info.ppEnabledLayerNames = layerList.names(); - info.enabledExtensionCount = extensionList.count(); - info.ppEnabledExtensionNames = extensionList.names(); + info.enabledExtensionCount = m_extensionNames.count(); + info.ppEnabledExtensionNames = m_extensionNames.names(); VkResult status = m_vkl->vkCreateInstance(&info, nullptr, &instance); diff --git a/src/dxvk/dxvk_instance.h b/src/dxvk/dxvk_instance.h index cc0071e28f6..dd6e78dc7bd 100644 --- a/src/dxvk/dxvk_instance.h +++ b/src/dxvk/dxvk_instance.h @@ -144,6 +144,18 @@ namespace dxvk { const DxvkInstanceExtensions& extensions() const { return m_extensions; } + + /** + * \brief Instance extension name list + * + * Returns the list of extensions that the + * instance was created with, provided by + * both DXVK and any extension providers. + * \returns Instance extension name list + */ + const DxvkNameList& extensionNameList() const { + return m_extensionNames; + } private: @@ -153,6 +165,7 @@ namespace dxvk { Rc m_vkl; Rc m_vki; DxvkInstanceExtensions m_extensions; + DxvkNameList m_extensionNames; VkDebugUtilsMessengerEXT m_messenger = VK_NULL_HANDLE;