From ae88f83b8691fad6432409c09e017606b747b547 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 28 Mar 2018 21:24:52 +0200 Subject: [PATCH] [d3d11] Introduce D3D11DeviceContainer Refactored DxgiVkDevice, D3D11Device and D3D11Presenter to behave more like aggregable objects, where the new D3D11DeviceContainer class is the COM aggregate object. Fixes the reference counting issue outlined in #210. --- src/d3d11/d3d11_device.cpp | 121 +++++++++++++++++++---------- src/d3d11/d3d11_device.h | 150 ++++++++++++++++++++++-------------- src/d3d11/d3d11_main.cpp | 15 ++-- src/d3d11/d3d11_present.cpp | 45 +++++++---- src/d3d11/d3d11_present.h | 35 +++++---- src/dxgi/dxgi_adapter.cpp | 17 ++-- src/dxgi/dxgi_adapter.h | 3 +- src/dxgi/dxgi_device.cpp | 53 ++++++++----- src/dxgi/dxgi_device.h | 40 +++++++--- src/dxgi/dxgi_interfaces.h | 10 ++- src/dxgi/dxgi_swapchain.cpp | 3 - 11 files changed, 312 insertions(+), 180 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 5d8ef3d03..fc259772f 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -15,28 +15,83 @@ namespace dxvk { + D3D11DeviceContainer::D3D11DeviceContainer() { + + } + + + D3D11DeviceContainer::~D3D11DeviceContainer() { + delete m_d3d11Presenter; + delete m_d3d11Device; + delete m_dxgiDevice; + } + + + HRESULT STDMETHODCALLTYPE D3D11DeviceContainer::QueryInterface(REFIID riid, void** ppvObject) { + if (riid == __uuidof(IUnknown) + || riid == __uuidof(IDXGIObject)) { + *ppvObject = ref(this); + return S_OK; + } + + if (riid == __uuidof(IDXGIDevice) + || riid == __uuidof(IDXGIDevice1) + || riid == __uuidof(IDXGIDevice2) + || riid == __uuidof(IDXGIVkDevice)) { + *ppvObject = ref(m_dxgiDevice); + return S_OK; + } + + if (riid == __uuidof(ID3D11Device) + || riid == __uuidof(ID3D11Device1)) { + *ppvObject = ref(m_d3d11Device); + return S_OK; + } + + if (riid == __uuidof(IDXGIVkPresenter)) { + *ppvObject = ref(m_d3d11Presenter); + return S_OK; + } + + if (riid == __uuidof(ID3D11Debug)) + return E_NOINTERFACE; + + // Undocumented interfaces that are queried by some games + if (riid == GUID{0xd56e2a4c,0x5127,0x8437,{0x65,0x8a,0x98,0xc5,0xbb,0x78,0x94,0x98}}) + return E_NOINTERFACE; + + Logger::warn("D3D11DeviceContainer::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + return E_NOINTERFACE; + } + + + HRESULT STDMETHODCALLTYPE D3D11DeviceContainer::GetParent( + REFIID riid, + void** ppParent) { + return m_dxgiDevice->GetParent(riid, ppParent); + } + + D3D11Device::D3D11Device( - IDXGIVkDevice* dxgiDevice, - D3D_FEATURE_LEVEL featureLevel, - UINT featureFlags) - : m_dxgiDevice (dxgiDevice), - m_presentDevice (new D3D11PresentDevice()), - m_featureLevel (featureLevel), - m_featureFlags (featureFlags), - m_dxvkDevice (m_dxgiDevice->GetDXVKDevice()), + IDXGIObject* pContainer, + IDXGIVkDevice* pDxgiDevice, + D3D_FEATURE_LEVEL FeatureLevel, + UINT FeatureFlags) + : m_container (pContainer), + m_featureLevel (FeatureLevel), + m_featureFlags (FeatureFlags), + m_dxvkDevice (pDxgiDevice->GetDXVKDevice()), m_dxvkAdapter (m_dxvkDevice->adapter()), m_d3d11Options (D3D11GetAppOptions(env::getExeName())), m_dxbcOptions (m_dxvkDevice) { Com adapter; - if (FAILED(m_dxgiDevice->GetAdapter(&adapter)) + if (FAILED(pDxgiDevice->GetAdapter(&adapter)) || FAILED(adapter->QueryInterface(__uuidof(IDXGIVkAdapter), reinterpret_cast(&m_dxgiAdapter)))) throw DxvkError("D3D11Device: Failed to query adapter"); - m_dxgiDevice->SetDeviceLayer(this); - m_presentDevice->SetDeviceLayer(this); - m_context = new D3D11ImmediateContext(this, m_dxvkDevice); m_resourceInitContext = m_dxvkDevice->createContext(); @@ -48,36 +103,22 @@ namespace dxvk { D3D11Device::~D3D11Device() { - m_presentDevice->SetDeviceLayer(nullptr); - m_dxgiDevice->SetDeviceLayer(nullptr); delete m_context; } + ULONG STDMETHODCALLTYPE D3D11Device::AddRef() { + return m_container->AddRef(); + } + + + ULONG STDMETHODCALLTYPE D3D11Device::Release() { + return m_container->Release(); + } + + HRESULT STDMETHODCALLTYPE D3D11Device::QueryInterface(REFIID riid, void** ppvObject) { - COM_QUERY_IFACE(riid, ppvObject, IUnknown); - COM_QUERY_IFACE(riid, ppvObject, ID3D11Device); - COM_QUERY_IFACE(riid, ppvObject, ID3D11Device1); - - if (riid == __uuidof(IDXGIDevice) - || riid == __uuidof(IDXGIDevice1) - || riid == __uuidof(IDXGIDevice2) - || riid == __uuidof(IDXGIVkDevice)) - return m_dxgiDevice->QueryInterface(riid, ppvObject); - - if (riid == __uuidof(IDXGIVkPresenter)) - return m_presentDevice->QueryInterface(riid, ppvObject); - - if (riid == __uuidof(ID3D11Debug)) - return E_NOINTERFACE; - - //d56e2a4c-5127-8437-658a-98c5bb789498, from GTA V, no occurrences in Google - if (riid == GUID{0xd56e2a4c,0x5127,0x8437,{0x65,0x8a,0x98,0xc5,0xbb,0x78,0x94,0x98}}) - return E_NOINTERFACE; - - Logger::warn("D3D11Device::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); - return E_NOINTERFACE; + return m_container->QueryInterface(riid, ppvObject); } @@ -1468,19 +1509,19 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::GetPrivateData( REFGUID guid, UINT* pDataSize, void* pData) { - return m_dxgiDevice->GetPrivateData(guid, pDataSize, pData); + return m_container->GetPrivateData(guid, pDataSize, pData); } HRESULT STDMETHODCALLTYPE D3D11Device::SetPrivateData( REFGUID guid, UINT DataSize, const void* pData) { - return m_dxgiDevice->SetPrivateData(guid, DataSize, pData); + return m_container->SetPrivateData(guid, DataSize, pData); } HRESULT STDMETHODCALLTYPE D3D11Device::SetPrivateDataInterface( REFGUID guid, const IUnknown* pData) { - return m_dxgiDevice->SetPrivateDataInterface(guid, pData); + return m_container->SetPrivateDataInterface(guid, pData); } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index c48c19ae7..f8525510b 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -22,86 +22,125 @@ namespace dxvk { class D3D11DeviceContext; class D3D11ImmediateContext; class D3D11Predicate; - class D3D11PresentDevice; + class D3D11Presenter; class D3D11Query; class D3D11ShaderModule; class D3D11Texture1D; class D3D11Texture2D; class D3D11Texture3D; - class D3D11Device : public ComObject { + /** + * \brief D3D11 device container + * + * Stores all the objects that contribute to the D3D11 + * device implementation, including the DXGI device. + */ + class D3D11DeviceContainer : public DxgiObject { + + public: + + D3D11DeviceContainer(); + ~D3D11DeviceContainer(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetParent( + REFIID riid, + void** ppParent); + + IDXGIVkDevice* m_dxgiDevice = nullptr; + D3D11Device* m_d3d11Device = nullptr; + D3D11Presenter* m_d3d11Presenter = nullptr; + + }; + + + /** + * \brief D3D11 device implementation + * + * Implements the ID3D11Device interfaces + * as part of a \ref D3D11DeviceContainer. + */ + class D3D11Device final : public ID3D11Device1 { /// Maximum number of resource init commands per command buffer constexpr static uint64_t InitCommandThreshold = 50; public: D3D11Device( - IDXGIVkDevice* dxgiDevice, - D3D_FEATURE_LEVEL featureLevel, - UINT featureFlags); + IDXGIObject* pContainer, + IDXGIVkDevice* pDxgiDevice, + D3D_FEATURE_LEVEL FeatureLevel, + UINT FeatureFlags); ~D3D11Device(); + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, - void** ppvObject) final; + void** ppvObject); HRESULT STDMETHODCALLTYPE CreateBuffer( const D3D11_BUFFER_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, - ID3D11Buffer** ppBuffer) final; + ID3D11Buffer** ppBuffer); HRESULT STDMETHODCALLTYPE CreateTexture1D( const D3D11_TEXTURE1D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, - ID3D11Texture1D** ppTexture1D) final; + ID3D11Texture1D** ppTexture1D); HRESULT STDMETHODCALLTYPE CreateTexture2D( const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, - ID3D11Texture2D** ppTexture2D) final; + ID3D11Texture2D** ppTexture2D); HRESULT STDMETHODCALLTYPE CreateTexture3D( const D3D11_TEXTURE3D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, - ID3D11Texture3D** ppTexture3D) final; + ID3D11Texture3D** ppTexture3D); HRESULT STDMETHODCALLTYPE CreateShaderResourceView( ID3D11Resource* pResource, const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, - ID3D11ShaderResourceView** ppSRView) final; + ID3D11ShaderResourceView** ppSRView); HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView( ID3D11Resource* pResource, const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, - ID3D11UnorderedAccessView** ppUAView) final; + ID3D11UnorderedAccessView** ppUAView); HRESULT STDMETHODCALLTYPE CreateRenderTargetView( ID3D11Resource* pResource, const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, - ID3D11RenderTargetView** ppRTView) final; + ID3D11RenderTargetView** ppRTView); HRESULT STDMETHODCALLTYPE CreateDepthStencilView( ID3D11Resource* pResource, const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, - ID3D11DepthStencilView** ppDepthStencilView) final; + ID3D11DepthStencilView** ppDepthStencilView); HRESULT STDMETHODCALLTYPE CreateInputLayout( const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs, UINT NumElements, const void* pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength, - ID3D11InputLayout** ppInputLayout) final; + ID3D11InputLayout** ppInputLayout); HRESULT STDMETHODCALLTYPE CreateVertexShader( const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, - ID3D11VertexShader** ppVertexShader) final; + ID3D11VertexShader** ppVertexShader); HRESULT STDMETHODCALLTYPE CreateGeometryShader( const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, - ID3D11GeometryShader** ppGeometryShader) final; + ID3D11GeometryShader** ppGeometryShader); HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput( const void* pShaderBytecode, @@ -112,78 +151,78 @@ namespace dxvk { UINT NumStrides, UINT RasterizedStream, ID3D11ClassLinkage* pClassLinkage, - ID3D11GeometryShader** ppGeometryShader) final; + ID3D11GeometryShader** ppGeometryShader); HRESULT STDMETHODCALLTYPE CreatePixelShader( const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, - ID3D11PixelShader** ppPixelShader) final; + ID3D11PixelShader** ppPixelShader); HRESULT STDMETHODCALLTYPE CreateHullShader( const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, - ID3D11HullShader** ppHullShader) final; + ID3D11HullShader** ppHullShader); HRESULT STDMETHODCALLTYPE CreateDomainShader( const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, - ID3D11DomainShader** ppDomainShader) final; + ID3D11DomainShader** ppDomainShader); HRESULT STDMETHODCALLTYPE CreateComputeShader( const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, - ID3D11ComputeShader** ppComputeShader) final; + ID3D11ComputeShader** ppComputeShader); HRESULT STDMETHODCALLTYPE CreateClassLinkage( - ID3D11ClassLinkage** ppLinkage) final; + ID3D11ClassLinkage** ppLinkage); HRESULT STDMETHODCALLTYPE CreateBlendState( const D3D11_BLEND_DESC* pBlendStateDesc, - ID3D11BlendState** ppBlendState) final; + ID3D11BlendState** ppBlendState); HRESULT STDMETHODCALLTYPE CreateBlendState1( const D3D11_BLEND_DESC1* pBlendStateDesc, - ID3D11BlendState1** ppBlendState) final; + ID3D11BlendState1** ppBlendState); HRESULT STDMETHODCALLTYPE CreateDepthStencilState( const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, - ID3D11DepthStencilState** ppDepthStencilState) final; + ID3D11DepthStencilState** ppDepthStencilState); HRESULT STDMETHODCALLTYPE CreateRasterizerState( const D3D11_RASTERIZER_DESC* pRasterizerDesc, - ID3D11RasterizerState** ppRasterizerState) final; + ID3D11RasterizerState** ppRasterizerState); HRESULT STDMETHODCALLTYPE CreateRasterizerState1( const D3D11_RASTERIZER_DESC1* pRasterizerDesc, - ID3D11RasterizerState1** ppRasterizerState) final; + ID3D11RasterizerState1** ppRasterizerState); HRESULT STDMETHODCALLTYPE CreateSamplerState( const D3D11_SAMPLER_DESC* pSamplerDesc, - ID3D11SamplerState** ppSamplerState) final; + ID3D11SamplerState** ppSamplerState); HRESULT STDMETHODCALLTYPE CreateQuery( const D3D11_QUERY_DESC* pQueryDesc, - ID3D11Query** ppQuery) final; + ID3D11Query** ppQuery); HRESULT STDMETHODCALLTYPE CreatePredicate( const D3D11_QUERY_DESC* pPredicateDesc, - ID3D11Predicate** ppPredicate) final; + ID3D11Predicate** ppPredicate); HRESULT STDMETHODCALLTYPE CreateCounter( const D3D11_COUNTER_DESC* pCounterDesc, - ID3D11Counter** ppCounter) final; + ID3D11Counter** ppCounter); HRESULT STDMETHODCALLTYPE CreateDeferredContext( UINT ContextFlags, - ID3D11DeviceContext** ppDeferredContext) final; + ID3D11DeviceContext** ppDeferredContext); HRESULT STDMETHODCALLTYPE CreateDeferredContext1( UINT ContextFlags, - ID3D11DeviceContext1** ppDeferredContext) final; + ID3D11DeviceContext1** ppDeferredContext); HRESULT STDMETHODCALLTYPE CreateDeviceContextState( UINT Flags, @@ -192,35 +231,35 @@ namespace dxvk { UINT SDKVersion, REFIID EmulatedInterface, D3D_FEATURE_LEVEL* pChosenFeatureLevel, - ID3DDeviceContextState** ppContextState) final; + ID3DDeviceContextState** ppContextState); HRESULT STDMETHODCALLTYPE OpenSharedResource( HANDLE hResource, REFIID ReturnedInterface, - void** ppResource) final; + void** ppResource); HRESULT STDMETHODCALLTYPE OpenSharedResource1( HANDLE hResource, REFIID returnedInterface, - void** ppResource) final; + void** ppResource); HRESULT STDMETHODCALLTYPE OpenSharedResourceByName( LPCWSTR lpName, DWORD dwDesiredAccess, REFIID returnedInterface, - void** ppResource) final; + void** ppResource); HRESULT STDMETHODCALLTYPE CheckFormatSupport( DXGI_FORMAT Format, - UINT* pFormatSupport) final; + UINT* pFormatSupport); HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels( DXGI_FORMAT Format, UINT SampleCount, - UINT* pNumQualityLevels) final; + UINT* pNumQualityLevels); void STDMETHODCALLTYPE CheckCounterInfo( - D3D11_COUNTER_INFO* pCounterInfo) final; + D3D11_COUNTER_INFO* pCounterInfo); HRESULT STDMETHODCALLTYPE CheckCounter( const D3D11_COUNTER_DESC* pDesc, @@ -231,42 +270,42 @@ namespace dxvk { LPSTR szUnits, UINT* pUnitsLength, LPSTR szDescription, - UINT* pDescriptionLength) final; + UINT* pDescriptionLength); HRESULT STDMETHODCALLTYPE CheckFeatureSupport( D3D11_FEATURE Feature, void* pFeatureSupportData, - UINT FeatureSupportDataSize) final; + UINT FeatureSupportDataSize); HRESULT STDMETHODCALLTYPE GetPrivateData( REFGUID Name, UINT *pDataSize, - void *pData) final; + void *pData); HRESULT STDMETHODCALLTYPE SetPrivateData( REFGUID Name, UINT DataSize, - const void *pData) final; + const void *pData); HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( REFGUID Name, - const IUnknown *pUnknown) final; + const IUnknown *pUnknown); - D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel() final; + D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel(); - UINT STDMETHODCALLTYPE GetCreationFlags() final; + UINT STDMETHODCALLTYPE GetCreationFlags(); - HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason() final; + HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason(); void STDMETHODCALLTYPE GetImmediateContext( - ID3D11DeviceContext** ppImmediateContext) final; + ID3D11DeviceContext** ppImmediateContext); void STDMETHODCALLTYPE GetImmediateContext1( - ID3D11DeviceContext1** ppImmediateContext) final; + ID3D11DeviceContext1** ppImmediateContext); - HRESULT STDMETHODCALLTYPE SetExceptionMode(UINT RaiseFlags) final; + HRESULT STDMETHODCALLTYPE SetExceptionMode(UINT RaiseFlags); - UINT STDMETHODCALLTYPE GetExceptionMode() final; + UINT STDMETHODCALLTYPE GetExceptionMode(); Rc GetDXVKDevice() { return m_dxvkDevice; @@ -298,9 +337,8 @@ namespace dxvk { private: - const Com m_dxgiDevice; - Com m_dxgiAdapter; - const Com m_presentDevice; + IDXGIObject* m_container; + Com m_dxgiAdapter; const D3D_FEATURE_LEVEL m_featureLevel; const UINT m_featureFlags; diff --git a/src/d3d11/d3d11_main.cpp b/src/d3d11/d3d11_main.cpp index 7819cbee4..4d08403e9 100644 --- a/src/d3d11/d3d11_main.cpp +++ b/src/d3d11/d3d11_main.cpp @@ -5,6 +5,7 @@ #include "d3d11_device.h" #include "d3d11_enums.h" +#include "d3d11_present.h" namespace dxvk { Logger Logger::s_instance("d3d11.log"); @@ -110,23 +111,27 @@ extern "C" { if (ppDevice == nullptr && ppImmediateContext == nullptr) return S_FALSE; - Com dxvkDevice = nullptr; + Com container = new D3D11DeviceContainer(); const VkPhysicalDeviceFeatures deviceFeatures = D3D11Device::GetDeviceFeatures(adapter, fl); - if (FAILED(dxvkAdapter->CreateDevice(&deviceFeatures, &dxvkDevice))) { + if (FAILED(dxvkAdapter->CreateDevice(container.ptr(), &deviceFeatures, &container->m_dxgiDevice))) { Logger::err("D3D11CreateDevice: Failed to create DXGI device"); return E_FAIL; } - Com d3d11Device = new D3D11Device(dxvkDevice.ptr(), fl, Flags); + container->m_d3d11Device = new D3D11Device( + container.ptr(), container->m_dxgiDevice, fl, Flags); + + container->m_d3d11Presenter = new D3D11Presenter( + container.ptr(), container->m_d3d11Device); if (ppDevice != nullptr) - *ppDevice = d3d11Device.ref(); + *ppDevice = ref(container->m_d3d11Device); if (ppImmediateContext != nullptr) - d3d11Device->GetImmediateContext(ppImmediateContext); + container->m_d3d11Device->GetImmediateContext(ppImmediateContext); return S_OK; } catch (const DxvkError& e) { Logger::err("D3D11CreateDevice: Failed to create D3D11 device"); diff --git a/src/d3d11/d3d11_present.cpp b/src/d3d11/d3d11_present.cpp index 78b6ea040..dc7135da4 100644 --- a/src/d3d11/d3d11_present.cpp +++ b/src/d3d11/d3d11_present.cpp @@ -14,22 +14,37 @@ namespace dxvk { } - D3D11PresentDevice:: D3D11PresentDevice() { } - D3D11PresentDevice::~D3D11PresentDevice() { } - - - HRESULT STDMETHODCALLTYPE D3D11PresentDevice::QueryInterface( - REFIID riid, - void** ppvObject) { - COM_QUERY_IFACE(riid, ppvObject, IUnknown); - COM_QUERY_IFACE(riid, ppvObject, IDXGIVkPresenter); - return m_device->QueryInterface(riid, ppvObject); + D3D11Presenter:: D3D11Presenter( + IDXGIObject* pContainer, + ID3D11Device* pDevice) + : m_container(pContainer), m_device(pDevice) { + } - HRESULT STDMETHODCALLTYPE D3D11PresentDevice::CreateSwapChainBackBuffer( + D3D11Presenter::~D3D11Presenter() { + + } + + + ULONG STDMETHODCALLTYPE D3D11Presenter::AddRef() { + return m_container->AddRef(); + } + + + ULONG STDMETHODCALLTYPE D3D11Presenter::Release() { + return m_container->Release(); + } + + + HRESULT STDMETHODCALLTYPE D3D11Presenter::QueryInterface(REFIID riid, void** ppvObject) { + return m_container->QueryInterface(riid, ppvObject); + } + + + HRESULT STDMETHODCALLTYPE D3D11Presenter::CreateSwapChainBackBuffer( const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IDXGIVkBackBuffer** ppInterface) { + IDXGIVkBackBuffer** ppInterface) { D3D11_COMMON_TEXTURE_DESC desc; desc.Width = pSwapChainDesc->BufferDesc.Width; desc.Height = pSwapChainDesc->BufferDesc.Height; @@ -49,7 +64,7 @@ namespace dxvk { try { *ppInterface = ref(new D3D11VkBackBuffer( - new D3D11Texture2D(m_device, &desc))); + new D3D11Texture2D(static_cast(m_device), &desc))); return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); @@ -58,7 +73,7 @@ namespace dxvk { } - HRESULT STDMETHODCALLTYPE D3D11PresentDevice::FlushRenderingCommands() { + HRESULT STDMETHODCALLTYPE D3D11Presenter::FlushRenderingCommands() { Com deviceContext = nullptr; m_device->GetImmediateContext(&deviceContext); @@ -71,7 +86,7 @@ namespace dxvk { } - HRESULT STDMETHODCALLTYPE D3D11PresentDevice::GetDevice(REFGUID riid, void** ppvDevice) { + HRESULT STDMETHODCALLTYPE D3D11Presenter::GetDevice(REFGUID riid, void** ppvDevice) { return m_device->QueryInterface(riid, ppvDevice); } diff --git a/src/d3d11/d3d11_present.h b/src/d3d11/d3d11_present.h index d80301fe7..1fe147d6a 100644 --- a/src/d3d11/d3d11_present.h +++ b/src/d3d11/d3d11_present.h @@ -30,34 +30,43 @@ namespace dxvk { }; - class D3D11PresentDevice : public ComObject { + /** + * \brief Present device + * + * Wires up some swap chain related + * functions to the D3D11 device. + */ + class D3D11Presenter final : public IDXGIVkPresenter { public: - D3D11PresentDevice(); - ~D3D11PresentDevice(); + D3D11Presenter( + IDXGIObject* pContainer, + ID3D11Device* pDevice); + ~D3D11Presenter(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, - void** ppvObject) final; + void** ppvObject); HRESULT STDMETHODCALLTYPE CreateSwapChainBackBuffer( - const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IDXGIVkBackBuffer** ppInterface) final; + const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + IDXGIVkBackBuffer** ppInterface); - HRESULT STDMETHODCALLTYPE FlushRenderingCommands() final; + HRESULT STDMETHODCALLTYPE FlushRenderingCommands(); HRESULT STDMETHODCALLTYPE GetDevice( REFGUID riid, - void** ppvDevice) final; - - void SetDeviceLayer(D3D11Device* pDevice) { - m_device = pDevice; - } + void** ppvDevice); private: - D3D11Device* m_device = nullptr; + IDXGIObject* m_container; + ID3D11Device* m_device; }; diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 94a1fcce6..593e6b707 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -25,9 +25,7 @@ namespace dxvk { } - HRESULT STDMETHODCALLTYPE DxgiAdapter::QueryInterface( - REFIID riid, - void **ppvObject) { + HRESULT STDMETHODCALLTYPE DxgiAdapter::QueryInterface(REFIID riid, void** ppvObject) { COM_QUERY_IFACE(riid, ppvObject, IUnknown); COM_QUERY_IFACE(riid, ppvObject, IDXGIObject); COM_QUERY_IFACE(riid, ppvObject, IDXGIAdapter); @@ -40,9 +38,7 @@ namespace dxvk { } - HRESULT STDMETHODCALLTYPE DxgiAdapter::GetParent( - REFIID riid, - void **ppParent) { + HRESULT STDMETHODCALLTYPE DxgiAdapter::GetParent(REFIID riid, void** ppParent) { return m_factory->QueryInterface(riid, ppParent); } @@ -107,19 +103,17 @@ namespace dxvk { auto deviceProp = m_adapter->deviceProperties(); auto memoryProp = m_adapter->memoryProperties(); - //Custom Vendor ID + // Custom Vendor ID const std::string customVendorID = env::getEnvVar(L"DXVK_CUSTOM_VENDOR_ID"); const std::string customDeviceID = env::getEnvVar(L"DXVK_CUSTOM_DEVICE_ID"); if (!customVendorID.empty()) { Logger::info("Using Custom PCI Vendor ID " + customVendorID + " instead of " + str::format(std::hex, deviceProp.vendorID)); - deviceProp.vendorID = std::stoul(customVendorID, nullptr, 16); } if (!customDeviceID.empty()) { Logger::info("Using Custom PCI Device ID " + customDeviceID + " instead of " + str::format(std::hex, deviceProp.deviceID)); - deviceProp.deviceID = std::stoul(customDeviceID, nullptr, 16); } @@ -157,10 +151,11 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiAdapter::CreateDevice( + IDXGIObject* pContainer, const VkPhysicalDeviceFeatures* pFeatures, - IDXGIVkDevice** ppDevice) { + IDXGIVkDevice** ppDevice) { try { - *ppDevice = ref(new dxvk::DxgiDevice(this, pFeatures)); + *ppDevice = new dxvk::DxgiDevice(pContainer, this, pFeatures); return S_OK; } catch (const dxvk::DxvkError& e) { dxvk::Logger::err(e.message()); diff --git a/src/dxgi/dxgi_adapter.h b/src/dxgi/dxgi_adapter.h index 64f743745..76f4ecaaa 100644 --- a/src/dxgi/dxgi_adapter.h +++ b/src/dxgi/dxgi_adapter.h @@ -50,8 +50,9 @@ namespace dxvk { Rc STDMETHODCALLTYPE GetDXVKAdapter() final; HRESULT STDMETHODCALLTYPE CreateDevice( + IDXGIObject* pContainer, const VkPhysicalDeviceFeatures* pFeatures, - IDXGIVkDevice** ppDevice) final; + IDXGIVkDevice** ppDevice) final; DxgiFormatInfo STDMETHODCALLTYPE LookupFormat( DXGI_FORMAT format, DxgiFormatMode mode) final; diff --git a/src/dxgi/dxgi_device.cpp b/src/dxgi/dxgi_device.cpp index 861e6e797..1d3e05a39 100644 --- a/src/dxgi/dxgi_device.cpp +++ b/src/dxgi/dxgi_device.cpp @@ -4,9 +4,11 @@ namespace dxvk { DxgiDevice::DxgiDevice( - IDXGIVkAdapter* pAdapter, + IDXGIObject* pContainer, + IDXGIVkAdapter* pAdapter, const VkPhysicalDeviceFeatures* pFeatures) - : m_adapter(pAdapter) { + : m_container (pContainer), + m_adapter (pAdapter) { m_device = m_adapter->GetDXVKAdapter()->createDevice(*pFeatures); } @@ -16,20 +18,18 @@ namespace dxvk { } + ULONG STDMETHODCALLTYPE DxgiDevice::AddRef() { + return m_container->AddRef(); + } + + + ULONG STDMETHODCALLTYPE DxgiDevice::Release() { + return m_container->Release(); + } + + HRESULT STDMETHODCALLTYPE DxgiDevice::QueryInterface(REFIID riid, void** ppvObject) { - COM_QUERY_IFACE(riid, ppvObject, IUnknown); - COM_QUERY_IFACE(riid, ppvObject, IDXGIObject); - COM_QUERY_IFACE(riid, ppvObject, IDXGIDevice); - COM_QUERY_IFACE(riid, ppvObject, IDXGIDevice1); - COM_QUERY_IFACE(riid, ppvObject, IDXGIDevice2); - COM_QUERY_IFACE(riid, ppvObject, IDXGIVkDevice); - - if (m_layer != nullptr) - return m_layer->QueryInterface(riid, ppvObject); - - Logger::warn("DxgiDevice::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); - return E_NOINTERFACE; + return m_container->QueryInterface(riid, ppvObject); } @@ -38,6 +38,24 @@ namespace dxvk { } + HRESULT STDMETHODCALLTYPE DxgiDevice::GetPrivateData( + REFGUID Name, UINT* pDataSize, void* pData) { + return m_container->GetPrivateData(Name, pDataSize, pData); + } + + + HRESULT STDMETHODCALLTYPE DxgiDevice::SetPrivateData( + REFGUID Name, UINT DataSize, const void* pData) { + return m_container->SetPrivateData(Name, DataSize,pData); + } + + + HRESULT STDMETHODCALLTYPE DxgiDevice::SetPrivateDataInterface( + REFGUID Name, const IUnknown* pUnknown) { + return m_container->SetPrivateDataInterface(Name, pUnknown); + } + + HRESULT STDMETHODCALLTYPE DxgiDevice::CreateSurface( const DXGI_SURFACE_DESC* pDesc, UINT NumSurfaces, @@ -125,11 +143,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE DxgiDevice::SetDeviceLayer(IUnknown* layer) { - m_layer = layer; - } - - Rc STDMETHODCALLTYPE DxgiDevice::GetDXVKDevice() { return m_device; } diff --git a/src/dxgi/dxgi_device.h b/src/dxgi/dxgi_device.h index 93260774e..d1dcf61c9 100644 --- a/src/dxgi/dxgi_device.h +++ b/src/dxgi/dxgi_device.h @@ -9,22 +9,41 @@ namespace dxvk { class DxgiFactory; - class DxgiDevice : public DxgiObject { + class DxgiDevice : public IDXGIVkDevice { public: DxgiDevice( - IDXGIVkAdapter* pAdapter, + IDXGIObject* pContainer, + IDXGIVkAdapter* pAdapter, const VkPhysicalDeviceFeatures* pFeatures); ~DxgiDevice(); + ULONG STDMETHODCALLTYPE AddRef() final; + + ULONG STDMETHODCALLTYPE Release() final; + HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void **ppvObject) final; + REFIID riid, + void** ppvObject) final; HRESULT STDMETHODCALLTYPE GetParent( - REFIID riid, - void **ppParent) final; + REFIID riid, + void** ppParent) final; + + HRESULT STDMETHODCALLTYPE GetPrivateData( + REFGUID Name, + UINT* pDataSize, + void* pData) final; + + HRESULT STDMETHODCALLTYPE SetPrivateData( + REFGUID Name, + UINT DataSize, + const void* pData) final; + + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + REFGUID Name, + const IUnknown* pUnknown) final; HRESULT STDMETHODCALLTYPE CreateSurface( const DXGI_SURFACE_DESC* pDesc, @@ -66,17 +85,14 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE EnqueueSetEvent( HANDLE hEvent) final; - void STDMETHODCALLTYPE SetDeviceLayer( - IUnknown* layer) final; - Rc STDMETHODCALLTYPE GetDXVKDevice() final; private: - Com m_adapter; - Rc m_device; + IDXGIObject* m_container; - IUnknown* m_layer = nullptr; + Com m_adapter; + Rc m_device; }; diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index f0b3c9fbc..3dff8c2aa 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -62,8 +62,7 @@ MIDL_INTERFACE("7a622cf6-627a-46b2-b52f-360ef3da831c") IDXGIVkDevice : public IDXGIDevice2 { static const GUID guid; - virtual void STDMETHODCALLTYPE SetDeviceLayer( - IUnknown* layer) = 0; + virtual ~IDXGIVkDevice() { } virtual dxvk::Rc STDMETHODCALLTYPE GetDXVKDevice() = 0; }; @@ -91,8 +90,9 @@ IDXGIVkAdapter : public IDXGIAdapter1 { * \returns \c S_OK on success, or an error code */ virtual HRESULT STDMETHODCALLTYPE CreateDevice( + IDXGIObject* pContainer, const VkPhysicalDeviceFeatures* pFeatures, - IDXGIVkDevice** ppDevice) = 0; + IDXGIVkDevice** ppDevice) = 0; /** * \brief Maps a DXGI format to a compatible Vulkan format @@ -140,11 +140,13 @@ IDXGIVkPresenter : public IUnknown { /** * \brief Creates a swap chain back buffer * + * \param [in] pSwapChainDesc Swap chain description + * \param [out] ppBackBuffer The swap chain back buffer * \returns \c S_OK on success */ virtual HRESULT STDMETHODCALLTYPE CreateSwapChainBackBuffer( const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IDXGIVkBackBuffer** ppBackBuffer) = 0; + IDXGIVkBackBuffer** ppBackBuffer) = 0; /** * \brief Flushes the immediate context diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index d662d3943..2a7d0ac50 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -94,9 +94,6 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetContainingOutput(IDXGIOutput** ppOutput) { - if (ppOutput == nullptr) - return DXGI_ERROR_INVALID_CALL; - RECT windowRect = { 0, 0, 0, 0 }; ::GetWindowRect(m_desc.OutputWindow, &windowRect);