diff --git a/src/d3d9/d3d9_interface.cpp b/src/d3d9/d3d9_interface.cpp index b729466fd..e78a7e32a 100644 --- a/src/d3d9/d3d9_interface.cpp +++ b/src/d3d9/d3d9_interface.cpp @@ -11,7 +11,8 @@ namespace dxvk { D3D9InterfaceEx::D3D9InterfaceEx(bool bExtended) : m_instance ( new DxvkInstance() ) , m_extended ( bExtended ) - , m_d3d9Options ( nullptr, m_instance->config() ) { + , m_d3d9Options ( nullptr, m_instance->config() ) + , m_d3d9Interop ( this ) { // D3D9 doesn't enumerate adapters like physical adapters... // only as connected displays. @@ -76,6 +77,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D9VkInteropInterface)) { + *ppvObject = ref(&m_d3d9Interop); + return S_OK; + } + Logger::warn("D3D9InterfaceEx::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); return E_NOINTERFACE; diff --git a/src/d3d9/d3d9_interface.h b/src/d3d9/d3d9_interface.h index 85cc5a036..3fc9a43d3 100644 --- a/src/d3d9/d3d9_interface.h +++ b/src/d3d9/d3d9_interface.h @@ -1,6 +1,7 @@ #pragma once #include "d3d9_adapter.h" +#include "d3d9_interop.h" #include "../dxvk/dxvk_instance.h" @@ -143,6 +144,8 @@ namespace dxvk { std::vector m_adapters; + D3D9VkInteropInterface m_d3d9Interop; + }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_interfaces.h b/src/d3d9/d3d9_interfaces.h new file mode 100644 index 000000000..9b4b77a2e --- /dev/null +++ b/src/d3d9/d3d9_interfaces.h @@ -0,0 +1,37 @@ +#pragma once + +#include "d3d9_include.h" +#include "../vulkan/vulkan_loader.h" + +/** + * \brief D3D9 interface for Vulkan interop + * + * Provides access to the instance and physical device + * handles for the given D3D9 interface and adapter ordinals. + */ +MIDL_INTERFACE("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd") +ID3D9VkInteropInterface : public IUnknown { + /** + * \brief Queries Vulkan handles used by DXVK + * + * \param [out] pInstance The Vulkan instance + */ + virtual void STDMETHODCALLTYPE GetInstanceHandle( + VkInstance* pInstance) = 0; + + /** + * \brief Queries Vulkan handles used by DXVK + * + * \param [in] Adapter Adapter ordinal + * \param [out] pInstance The Vulkan instance + */ + virtual void STDMETHODCALLTYPE GetPhysicalDeviceHandle( + UINT Adapter, + VkPhysicalDevice* pPhysicalDevice) = 0; +}; + +#ifdef _MSC_VER +struct __declspec(uuid("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd")) ID3D9VkInteropInterface; +#else +__CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd); +#endif diff --git a/src/d3d9/d3d9_interop.cpp b/src/d3d9/d3d9_interop.cpp new file mode 100644 index 000000000..efa0c7b15 --- /dev/null +++ b/src/d3d9/d3d9_interop.cpp @@ -0,0 +1,49 @@ +#include "d3d9_interop.h" +#include "d3d9_interface.h" + +namespace dxvk { + + //////////////////////////////// + // Interface Interop + /////////////////////////////// + + D3D9VkInteropInterface::D3D9VkInteropInterface( + D3D9InterfaceEx* pInterface) + : m_interface(pInterface) { + + } + + D3D9VkInteropInterface::~D3D9VkInteropInterface() { + + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropInterface::AddRef() { + return m_interface->AddRef(); + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropInterface::Release() { + return m_interface->Release(); + } + + HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_interface->QueryInterface(riid, ppvObject); + } + + void STDMETHODCALLTYPE D3D9VkInteropInterface::GetInstanceHandle( + VkInstance* pInstance) { + if (pInstance != nullptr) + *pInstance = m_interface->GetInstance()->handle(); + } + + void STDMETHODCALLTYPE D3D9VkInteropInterface::GetPhysicalDeviceHandle( + UINT Adapter, + VkPhysicalDevice* pPhysicalDevice) { + if (pPhysicalDevice != nullptr) { + D3D9Adapter* adapter = m_interface->GetAdapter(Adapter); + *pPhysicalDevice = adapter ? adapter->GetDXVKAdapter()->handle() : nullptr; + } + } + +} diff --git a/src/d3d9/d3d9_interop.h b/src/d3d9/d3d9_interop.h new file mode 100644 index 000000000..2f7f9b344 --- /dev/null +++ b/src/d3d9/d3d9_interop.h @@ -0,0 +1,39 @@ +#pragma once + +#include "d3d9_interfaces.h" + +namespace dxvk { + + class D3D9InterfaceEx; + + class D3D9VkInteropInterface final : public ID3D9VkInteropInterface { + + public: + + D3D9VkInteropInterface( + D3D9InterfaceEx* pInterface); + + ~D3D9VkInteropInterface(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + void STDMETHODCALLTYPE GetInstanceHandle( + VkInstance* pInstance); + + void STDMETHODCALLTYPE GetPhysicalDeviceHandle( + UINT Adapter, + VkPhysicalDevice* pPhysicalDevice); + + private: + + D3D9InterfaceEx* m_interface; + + }; + +} diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 1af266270..bb5f3f387 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -42,7 +42,8 @@ d3d9_src = [ 'd3d9_hud.cpp', 'd3d9_annotation.cpp', 'd3d9_mem.cpp', - 'd3d9_window.cpp' + 'd3d9_window.cpp', + 'd3d9_interop.cpp' ] d3d9_dll = shared_library('d3d9'+dll_ext, d3d9_src, glsl_generator.process(d3d9_shaders), d3d9_res,