From 1e393bf24d2e7a59f918e40e7e51cb676bfdfa10 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 21 Dec 2018 12:23:45 +0100 Subject: [PATCH] [d3d11] Implement IWineDXGISwapChainFactory See #822. --- src/d3d11/d3d11_device.cpp | 56 +++++++++++++++++++++++++++++++++++++- src/d3d11/d3d11_device.h | 35 ++++++++++++++++++++++++ src/d3d11/meson.build | 2 ++ src/dxgi/dxgi_interfaces.h | 22 +++++++++++++++ src/util/com/com_guid.cpp | 1 + 5 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 4fe92bff..ddb82b14 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1,6 +1,8 @@ #include #include +#include "../dxgi/dxgi_swapchain.h" + #include "../dxvk/dxvk_adapter.h" #include "../dxvk/dxvk_instance.h" @@ -1669,6 +1671,52 @@ namespace dxvk { + WineDXGISwapChainFactory::WineDXGISwapChainFactory(IUnknown* pContainer) + : m_container(pContainer) { + + } + + + ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory::AddRef() { + return m_container->AddRef(); + } + + + ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory::Release() { + return m_container->Release(); + } + + + HRESULT STDMETHODCALLTYPE WineDXGISwapChainFactory::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_container->QueryInterface(riid, ppvObject); + } + + + HRESULT STDMETHODCALLTYPE WineDXGISwapChainFactory::CreateSwapChainForHwnd( + IDXGIFactory* pFactory, + HWND hWnd, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, + IDXGIOutput* pRestrictToOutput, + IDXGISwapChain1** ppSwapChain) { + InitReturnPtr(ppSwapChain); + + try { + *ppSwapChain = ref(new DxgiSwapChain( + pFactory, m_container, hWnd, + pDesc, pFullscreenDesc)); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return DXGI_ERROR_INVALID_CALL; + } + } + + + + D3D11DXGIDevice::D3D11DXGIDevice( IDXGIAdapter* pAdapter, DxvkAdapter* pDxvkAdapter, @@ -1679,7 +1727,8 @@ namespace dxvk { m_dxvkDevice (CreateDevice(FeatureLevel)), m_d3d11Device (this, FeatureLevel, FeatureFlags), m_d3d11Presenter(this, &m_d3d11Device), - m_d3d11Interop (this, &m_d3d11Device) { + m_d3d11Interop (this, &m_d3d11Device), + m_wineFactory (this) { for (uint32_t i = 0; i < m_frameEvents.size(); i++) m_frameEvents[i] = new DxvkEvent(); } @@ -1724,6 +1773,11 @@ namespace dxvk { *ppvObject = ref(&m_d3d11Presenter); return S_OK; } + + if (riid == __uuidof(IWineDXGISwapChainFactory)) { + *ppvObject = ref(&m_wineFactory); + return S_OK; + } if (riid == __uuidof(ID3D10Multithread)) { *ppvObject = ref(m_d3d11Device.GetD3D10Multithread()); diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 2d9e3f78..774e0e0e 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -6,6 +6,7 @@ #include "../dxbc/dxbc_options.h" #include "../dxgi/dxgi_object.h" +#include "../dxgi/dxgi_interfaces.h" #include "../dxvk/dxvk_cs.h" @@ -390,6 +391,38 @@ namespace dxvk { }; + + /** + * \brief DXGI swap chain factory + */ + class WineDXGISwapChainFactory : public IWineDXGISwapChainFactory { + + public: + + WineDXGISwapChainFactory(IUnknown* pContainer); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( + IDXGIFactory* pFactory, + HWND hWnd, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, + IDXGIOutput* pRestrictToOutput, + IDXGISwapChain1** ppSwapChain); + + private: + + IUnknown* m_container; + + }; + /** * \brief D3D11 device container @@ -474,6 +507,8 @@ namespace dxvk { D3D11PresentDevice m_d3d11Presenter; D3D11VkInterop m_d3d11Interop; + WineDXGISwapChainFactory m_wineFactory; + uint32_t m_frameLatencyCap = 0; uint32_t m_frameLatency = DefaultFrameLatency; uint32_t m_frameId = 0; diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 3e687038..b924814c 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -1,5 +1,7 @@ dxgi_common_src = [ '../dxgi/dxgi_format.cpp', + '../dxgi/dxgi_monitor.cpp', + '../dxgi/dxgi_swapchain.cpp', ] d3d10_src = [ diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 04bffa4b..d36f84ea 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -237,16 +237,38 @@ IDXGIVkInteropDevice : public IUnknown { }; +/** + * \brief IWineDXGISwapChainFactory device interface + * + * Allows a swap chain to be created from a device. + * See include/wine/winedxgi.idl for definition. + */ +MIDL_INTERFACE("53cb4ff0-c25a-4164-a891-0e83db0a7aac") +IWineDXGISwapChainFactory : public IUnknown { + static const GUID guid; + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( + IDXGIFactory* pFactory, + HWND hWnd, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, + IDXGIOutput* pRestrictToOutput, + IDXGISwapChain1** ppSwapChain) = 0; +}; + + #ifdef _MSC_VER struct __declspec(uuid("907bf281-ea3c-43b4-a8e4-9f231107b4ff")) IDXGIVkAdapter; struct __declspec(uuid("79352328-16f2-4f81-9746-9c2e2ccd43cf")) IDXGIVkPresentDevice; struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDevice; struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSurface; struct __declspec(uuid("104001a6-7f36-4957-b932-86ade9567d91")) IDXGIVkSwapChain; +struct __declspec(uuid("53cb4ff0-c25a-4164-a891-0e83db0a7aac")) IWineDXGISwapChainFactory; #else DXVK_DEFINE_GUID(IDXGIVkAdapter); DXVK_DEFINE_GUID(IDXGIVkPresentDevice); DXVK_DEFINE_GUID(IDXGIVkInteropDevice); DXVK_DEFINE_GUID(IDXGIVkInteropSurface); DXVK_DEFINE_GUID(IDXGIVkSwapChain); +DXVK_DEFINE_GUID(IWineDXGISwapChainFactory); #endif \ No newline at end of file diff --git a/src/util/com/com_guid.cpp b/src/util/com/com_guid.cpp index 539d64a6..cb763cb4 100644 --- a/src/util/com/com_guid.cpp +++ b/src/util/com/com_guid.cpp @@ -9,6 +9,7 @@ const GUID IDXGIVkPresentDevice::guid = {0x79352328,0x16f2,0x4f81,{0x97,0x46,0 const GUID IDXGIVkInteropDevice::guid = {0xe2ef5fa5,0xdc21,0x4af7,{0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x23}}; const GUID IDXGIVkInteropSurface::guid = {0x5546cf8c,0x77e7,0x4341,{0xb0,0x5d,0x8d,0x4d,0x50,0x00,0xe7,0x7d}}; const GUID IDXGIVkSwapChain::guid = {0x104001a6,0x7f36,0x4957,{0xb9,0x32,0x86,0xad,0xe9,0x56,0x7d,0x91}}; +const GUID IWineDXGISwapChainFactory::guid = {0x53cb4ff0,0xc25a,0x4164,{0xa8,0x91,0x0e,0x83,0xdb,0x0a,0x7a,0xac}}; std::ostream& operator << (std::ostream& os, REFIID guid) { os << std::hex << std::setfill('0')