1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-06 13:54:14 +01:00

[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.
This commit is contained in:
Philip Rebohle 2018-03-28 21:24:52 +02:00
parent 8d3dcba8d5
commit ae88f83b86
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
11 changed files with 312 additions and 180 deletions

View File

@ -15,28 +15,83 @@
namespace dxvk { 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( D3D11Device::D3D11Device(
IDXGIVkDevice* dxgiDevice, IDXGIObject* pContainer,
D3D_FEATURE_LEVEL featureLevel, IDXGIVkDevice* pDxgiDevice,
UINT featureFlags) D3D_FEATURE_LEVEL FeatureLevel,
: m_dxgiDevice (dxgiDevice), UINT FeatureFlags)
m_presentDevice (new D3D11PresentDevice()), : m_container (pContainer),
m_featureLevel (featureLevel), m_featureLevel (FeatureLevel),
m_featureFlags (featureFlags), m_featureFlags (FeatureFlags),
m_dxvkDevice (m_dxgiDevice->GetDXVKDevice()), m_dxvkDevice (pDxgiDevice->GetDXVKDevice()),
m_dxvkAdapter (m_dxvkDevice->adapter()), m_dxvkAdapter (m_dxvkDevice->adapter()),
m_d3d11Options (D3D11GetAppOptions(env::getExeName())), m_d3d11Options (D3D11GetAppOptions(env::getExeName())),
m_dxbcOptions (m_dxvkDevice) { m_dxbcOptions (m_dxvkDevice) {
Com<IDXGIAdapter> adapter; Com<IDXGIAdapter> adapter;
if (FAILED(m_dxgiDevice->GetAdapter(&adapter)) if (FAILED(pDxgiDevice->GetAdapter(&adapter))
|| FAILED(adapter->QueryInterface(__uuidof(IDXGIVkAdapter), || FAILED(adapter->QueryInterface(__uuidof(IDXGIVkAdapter),
reinterpret_cast<void**>(&m_dxgiAdapter)))) reinterpret_cast<void**>(&m_dxgiAdapter))))
throw DxvkError("D3D11Device: Failed to query adapter"); throw DxvkError("D3D11Device: Failed to query adapter");
m_dxgiDevice->SetDeviceLayer(this);
m_presentDevice->SetDeviceLayer(this);
m_context = new D3D11ImmediateContext(this, m_dxvkDevice); m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
m_resourceInitContext = m_dxvkDevice->createContext(); m_resourceInitContext = m_dxvkDevice->createContext();
@ -48,36 +103,22 @@ namespace dxvk {
D3D11Device::~D3D11Device() { D3D11Device::~D3D11Device() {
m_presentDevice->SetDeviceLayer(nullptr);
m_dxgiDevice->SetDeviceLayer(nullptr);
delete m_context; 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) { HRESULT STDMETHODCALLTYPE D3D11Device::QueryInterface(REFIID riid, void** ppvObject) {
COM_QUERY_IFACE(riid, ppvObject, IUnknown); return m_container->QueryInterface(riid, ppvObject);
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;
} }
@ -1468,19 +1509,19 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D11Device::GetPrivateData( HRESULT STDMETHODCALLTYPE D3D11Device::GetPrivateData(
REFGUID guid, UINT* pDataSize, void* pData) { REFGUID guid, UINT* pDataSize, void* pData) {
return m_dxgiDevice->GetPrivateData(guid, pDataSize, pData); return m_container->GetPrivateData(guid, pDataSize, pData);
} }
HRESULT STDMETHODCALLTYPE D3D11Device::SetPrivateData( HRESULT STDMETHODCALLTYPE D3D11Device::SetPrivateData(
REFGUID guid, UINT DataSize, const void* pData) { 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( HRESULT STDMETHODCALLTYPE D3D11Device::SetPrivateDataInterface(
REFGUID guid, const IUnknown* pData) { REFGUID guid, const IUnknown* pData) {
return m_dxgiDevice->SetPrivateDataInterface(guid, pData); return m_container->SetPrivateDataInterface(guid, pData);
} }

View File

@ -22,86 +22,125 @@ namespace dxvk {
class D3D11DeviceContext; class D3D11DeviceContext;
class D3D11ImmediateContext; class D3D11ImmediateContext;
class D3D11Predicate; class D3D11Predicate;
class D3D11PresentDevice; class D3D11Presenter;
class D3D11Query; class D3D11Query;
class D3D11ShaderModule; class D3D11ShaderModule;
class D3D11Texture1D; class D3D11Texture1D;
class D3D11Texture2D; class D3D11Texture2D;
class D3D11Texture3D; class D3D11Texture3D;
class D3D11Device : public ComObject<ID3D11Device1> { /**
* \brief D3D11 device container
*
* Stores all the objects that contribute to the D3D11
* device implementation, including the DXGI device.
*/
class D3D11DeviceContainer : public DxgiObject<IDXGIObject> {
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 /// Maximum number of resource init commands per command buffer
constexpr static uint64_t InitCommandThreshold = 50; constexpr static uint64_t InitCommandThreshold = 50;
public: public:
D3D11Device( D3D11Device(
IDXGIVkDevice* dxgiDevice, IDXGIObject* pContainer,
D3D_FEATURE_LEVEL featureLevel, IDXGIVkDevice* pDxgiDevice,
UINT featureFlags); D3D_FEATURE_LEVEL FeatureLevel,
UINT FeatureFlags);
~D3D11Device(); ~D3D11Device();
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface( HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid, REFIID riid,
void** ppvObject) final; void** ppvObject);
HRESULT STDMETHODCALLTYPE CreateBuffer( HRESULT STDMETHODCALLTYPE CreateBuffer(
const D3D11_BUFFER_DESC* pDesc, const D3D11_BUFFER_DESC* pDesc,
const D3D11_SUBRESOURCE_DATA* pInitialData, const D3D11_SUBRESOURCE_DATA* pInitialData,
ID3D11Buffer** ppBuffer) final; ID3D11Buffer** ppBuffer);
HRESULT STDMETHODCALLTYPE CreateTexture1D( HRESULT STDMETHODCALLTYPE CreateTexture1D(
const D3D11_TEXTURE1D_DESC* pDesc, const D3D11_TEXTURE1D_DESC* pDesc,
const D3D11_SUBRESOURCE_DATA* pInitialData, const D3D11_SUBRESOURCE_DATA* pInitialData,
ID3D11Texture1D** ppTexture1D) final; ID3D11Texture1D** ppTexture1D);
HRESULT STDMETHODCALLTYPE CreateTexture2D( HRESULT STDMETHODCALLTYPE CreateTexture2D(
const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_TEXTURE2D_DESC* pDesc,
const D3D11_SUBRESOURCE_DATA* pInitialData, const D3D11_SUBRESOURCE_DATA* pInitialData,
ID3D11Texture2D** ppTexture2D) final; ID3D11Texture2D** ppTexture2D);
HRESULT STDMETHODCALLTYPE CreateTexture3D( HRESULT STDMETHODCALLTYPE CreateTexture3D(
const D3D11_TEXTURE3D_DESC* pDesc, const D3D11_TEXTURE3D_DESC* pDesc,
const D3D11_SUBRESOURCE_DATA* pInitialData, const D3D11_SUBRESOURCE_DATA* pInitialData,
ID3D11Texture3D** ppTexture3D) final; ID3D11Texture3D** ppTexture3D);
HRESULT STDMETHODCALLTYPE CreateShaderResourceView( HRESULT STDMETHODCALLTYPE CreateShaderResourceView(
ID3D11Resource* pResource, ID3D11Resource* pResource,
const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc,
ID3D11ShaderResourceView** ppSRView) final; ID3D11ShaderResourceView** ppSRView);
HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView( HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView(
ID3D11Resource* pResource, ID3D11Resource* pResource,
const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc,
ID3D11UnorderedAccessView** ppUAView) final; ID3D11UnorderedAccessView** ppUAView);
HRESULT STDMETHODCALLTYPE CreateRenderTargetView( HRESULT STDMETHODCALLTYPE CreateRenderTargetView(
ID3D11Resource* pResource, ID3D11Resource* pResource,
const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, const D3D11_RENDER_TARGET_VIEW_DESC* pDesc,
ID3D11RenderTargetView** ppRTView) final; ID3D11RenderTargetView** ppRTView);
HRESULT STDMETHODCALLTYPE CreateDepthStencilView( HRESULT STDMETHODCALLTYPE CreateDepthStencilView(
ID3D11Resource* pResource, ID3D11Resource* pResource,
const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc,
ID3D11DepthStencilView** ppDepthStencilView) final; ID3D11DepthStencilView** ppDepthStencilView);
HRESULT STDMETHODCALLTYPE CreateInputLayout( HRESULT STDMETHODCALLTYPE CreateInputLayout(
const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs, const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs,
UINT NumElements, UINT NumElements,
const void* pShaderBytecodeWithInputSignature, const void* pShaderBytecodeWithInputSignature,
SIZE_T BytecodeLength, SIZE_T BytecodeLength,
ID3D11InputLayout** ppInputLayout) final; ID3D11InputLayout** ppInputLayout);
HRESULT STDMETHODCALLTYPE CreateVertexShader( HRESULT STDMETHODCALLTYPE CreateVertexShader(
const void* pShaderBytecode, const void* pShaderBytecode,
SIZE_T BytecodeLength, SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage, ID3D11ClassLinkage* pClassLinkage,
ID3D11VertexShader** ppVertexShader) final; ID3D11VertexShader** ppVertexShader);
HRESULT STDMETHODCALLTYPE CreateGeometryShader( HRESULT STDMETHODCALLTYPE CreateGeometryShader(
const void* pShaderBytecode, const void* pShaderBytecode,
SIZE_T BytecodeLength, SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage, ID3D11ClassLinkage* pClassLinkage,
ID3D11GeometryShader** ppGeometryShader) final; ID3D11GeometryShader** ppGeometryShader);
HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput( HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput(
const void* pShaderBytecode, const void* pShaderBytecode,
@ -112,78 +151,78 @@ namespace dxvk {
UINT NumStrides, UINT NumStrides,
UINT RasterizedStream, UINT RasterizedStream,
ID3D11ClassLinkage* pClassLinkage, ID3D11ClassLinkage* pClassLinkage,
ID3D11GeometryShader** ppGeometryShader) final; ID3D11GeometryShader** ppGeometryShader);
HRESULT STDMETHODCALLTYPE CreatePixelShader( HRESULT STDMETHODCALLTYPE CreatePixelShader(
const void* pShaderBytecode, const void* pShaderBytecode,
SIZE_T BytecodeLength, SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage, ID3D11ClassLinkage* pClassLinkage,
ID3D11PixelShader** ppPixelShader) final; ID3D11PixelShader** ppPixelShader);
HRESULT STDMETHODCALLTYPE CreateHullShader( HRESULT STDMETHODCALLTYPE CreateHullShader(
const void* pShaderBytecode, const void* pShaderBytecode,
SIZE_T BytecodeLength, SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage, ID3D11ClassLinkage* pClassLinkage,
ID3D11HullShader** ppHullShader) final; ID3D11HullShader** ppHullShader);
HRESULT STDMETHODCALLTYPE CreateDomainShader( HRESULT STDMETHODCALLTYPE CreateDomainShader(
const void* pShaderBytecode, const void* pShaderBytecode,
SIZE_T BytecodeLength, SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage, ID3D11ClassLinkage* pClassLinkage,
ID3D11DomainShader** ppDomainShader) final; ID3D11DomainShader** ppDomainShader);
HRESULT STDMETHODCALLTYPE CreateComputeShader( HRESULT STDMETHODCALLTYPE CreateComputeShader(
const void* pShaderBytecode, const void* pShaderBytecode,
SIZE_T BytecodeLength, SIZE_T BytecodeLength,
ID3D11ClassLinkage* pClassLinkage, ID3D11ClassLinkage* pClassLinkage,
ID3D11ComputeShader** ppComputeShader) final; ID3D11ComputeShader** ppComputeShader);
HRESULT STDMETHODCALLTYPE CreateClassLinkage( HRESULT STDMETHODCALLTYPE CreateClassLinkage(
ID3D11ClassLinkage** ppLinkage) final; ID3D11ClassLinkage** ppLinkage);
HRESULT STDMETHODCALLTYPE CreateBlendState( HRESULT STDMETHODCALLTYPE CreateBlendState(
const D3D11_BLEND_DESC* pBlendStateDesc, const D3D11_BLEND_DESC* pBlendStateDesc,
ID3D11BlendState** ppBlendState) final; ID3D11BlendState** ppBlendState);
HRESULT STDMETHODCALLTYPE CreateBlendState1( HRESULT STDMETHODCALLTYPE CreateBlendState1(
const D3D11_BLEND_DESC1* pBlendStateDesc, const D3D11_BLEND_DESC1* pBlendStateDesc,
ID3D11BlendState1** ppBlendState) final; ID3D11BlendState1** ppBlendState);
HRESULT STDMETHODCALLTYPE CreateDepthStencilState( HRESULT STDMETHODCALLTYPE CreateDepthStencilState(
const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc,
ID3D11DepthStencilState** ppDepthStencilState) final; ID3D11DepthStencilState** ppDepthStencilState);
HRESULT STDMETHODCALLTYPE CreateRasterizerState( HRESULT STDMETHODCALLTYPE CreateRasterizerState(
const D3D11_RASTERIZER_DESC* pRasterizerDesc, const D3D11_RASTERIZER_DESC* pRasterizerDesc,
ID3D11RasterizerState** ppRasterizerState) final; ID3D11RasterizerState** ppRasterizerState);
HRESULT STDMETHODCALLTYPE CreateRasterizerState1( HRESULT STDMETHODCALLTYPE CreateRasterizerState1(
const D3D11_RASTERIZER_DESC1* pRasterizerDesc, const D3D11_RASTERIZER_DESC1* pRasterizerDesc,
ID3D11RasterizerState1** ppRasterizerState) final; ID3D11RasterizerState1** ppRasterizerState);
HRESULT STDMETHODCALLTYPE CreateSamplerState( HRESULT STDMETHODCALLTYPE CreateSamplerState(
const D3D11_SAMPLER_DESC* pSamplerDesc, const D3D11_SAMPLER_DESC* pSamplerDesc,
ID3D11SamplerState** ppSamplerState) final; ID3D11SamplerState** ppSamplerState);
HRESULT STDMETHODCALLTYPE CreateQuery( HRESULT STDMETHODCALLTYPE CreateQuery(
const D3D11_QUERY_DESC* pQueryDesc, const D3D11_QUERY_DESC* pQueryDesc,
ID3D11Query** ppQuery) final; ID3D11Query** ppQuery);
HRESULT STDMETHODCALLTYPE CreatePredicate( HRESULT STDMETHODCALLTYPE CreatePredicate(
const D3D11_QUERY_DESC* pPredicateDesc, const D3D11_QUERY_DESC* pPredicateDesc,
ID3D11Predicate** ppPredicate) final; ID3D11Predicate** ppPredicate);
HRESULT STDMETHODCALLTYPE CreateCounter( HRESULT STDMETHODCALLTYPE CreateCounter(
const D3D11_COUNTER_DESC* pCounterDesc, const D3D11_COUNTER_DESC* pCounterDesc,
ID3D11Counter** ppCounter) final; ID3D11Counter** ppCounter);
HRESULT STDMETHODCALLTYPE CreateDeferredContext( HRESULT STDMETHODCALLTYPE CreateDeferredContext(
UINT ContextFlags, UINT ContextFlags,
ID3D11DeviceContext** ppDeferredContext) final; ID3D11DeviceContext** ppDeferredContext);
HRESULT STDMETHODCALLTYPE CreateDeferredContext1( HRESULT STDMETHODCALLTYPE CreateDeferredContext1(
UINT ContextFlags, UINT ContextFlags,
ID3D11DeviceContext1** ppDeferredContext) final; ID3D11DeviceContext1** ppDeferredContext);
HRESULT STDMETHODCALLTYPE CreateDeviceContextState( HRESULT STDMETHODCALLTYPE CreateDeviceContextState(
UINT Flags, UINT Flags,
@ -192,35 +231,35 @@ namespace dxvk {
UINT SDKVersion, UINT SDKVersion,
REFIID EmulatedInterface, REFIID EmulatedInterface,
D3D_FEATURE_LEVEL* pChosenFeatureLevel, D3D_FEATURE_LEVEL* pChosenFeatureLevel,
ID3DDeviceContextState** ppContextState) final; ID3DDeviceContextState** ppContextState);
HRESULT STDMETHODCALLTYPE OpenSharedResource( HRESULT STDMETHODCALLTYPE OpenSharedResource(
HANDLE hResource, HANDLE hResource,
REFIID ReturnedInterface, REFIID ReturnedInterface,
void** ppResource) final; void** ppResource);
HRESULT STDMETHODCALLTYPE OpenSharedResource1( HRESULT STDMETHODCALLTYPE OpenSharedResource1(
HANDLE hResource, HANDLE hResource,
REFIID returnedInterface, REFIID returnedInterface,
void** ppResource) final; void** ppResource);
HRESULT STDMETHODCALLTYPE OpenSharedResourceByName( HRESULT STDMETHODCALLTYPE OpenSharedResourceByName(
LPCWSTR lpName, LPCWSTR lpName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
REFIID returnedInterface, REFIID returnedInterface,
void** ppResource) final; void** ppResource);
HRESULT STDMETHODCALLTYPE CheckFormatSupport( HRESULT STDMETHODCALLTYPE CheckFormatSupport(
DXGI_FORMAT Format, DXGI_FORMAT Format,
UINT* pFormatSupport) final; UINT* pFormatSupport);
HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels( HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels(
DXGI_FORMAT Format, DXGI_FORMAT Format,
UINT SampleCount, UINT SampleCount,
UINT* pNumQualityLevels) final; UINT* pNumQualityLevels);
void STDMETHODCALLTYPE CheckCounterInfo( void STDMETHODCALLTYPE CheckCounterInfo(
D3D11_COUNTER_INFO* pCounterInfo) final; D3D11_COUNTER_INFO* pCounterInfo);
HRESULT STDMETHODCALLTYPE CheckCounter( HRESULT STDMETHODCALLTYPE CheckCounter(
const D3D11_COUNTER_DESC* pDesc, const D3D11_COUNTER_DESC* pDesc,
@ -231,42 +270,42 @@ namespace dxvk {
LPSTR szUnits, LPSTR szUnits,
UINT* pUnitsLength, UINT* pUnitsLength,
LPSTR szDescription, LPSTR szDescription,
UINT* pDescriptionLength) final; UINT* pDescriptionLength);
HRESULT STDMETHODCALLTYPE CheckFeatureSupport( HRESULT STDMETHODCALLTYPE CheckFeatureSupport(
D3D11_FEATURE Feature, D3D11_FEATURE Feature,
void* pFeatureSupportData, void* pFeatureSupportData,
UINT FeatureSupportDataSize) final; UINT FeatureSupportDataSize);
HRESULT STDMETHODCALLTYPE GetPrivateData( HRESULT STDMETHODCALLTYPE GetPrivateData(
REFGUID Name, REFGUID Name,
UINT *pDataSize, UINT *pDataSize,
void *pData) final; void *pData);
HRESULT STDMETHODCALLTYPE SetPrivateData( HRESULT STDMETHODCALLTYPE SetPrivateData(
REFGUID Name, REFGUID Name,
UINT DataSize, UINT DataSize,
const void *pData) final; const void *pData);
HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
REFGUID Name, 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( void STDMETHODCALLTYPE GetImmediateContext(
ID3D11DeviceContext** ppImmediateContext) final; ID3D11DeviceContext** ppImmediateContext);
void STDMETHODCALLTYPE GetImmediateContext1( 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<DxvkDevice> GetDXVKDevice() { Rc<DxvkDevice> GetDXVKDevice() {
return m_dxvkDevice; return m_dxvkDevice;
@ -298,9 +337,8 @@ namespace dxvk {
private: private:
const Com<IDXGIVkDevice> m_dxgiDevice; IDXGIObject* m_container;
Com<IDXGIVkAdapter> m_dxgiAdapter; Com<IDXGIVkAdapter> m_dxgiAdapter;
const Com<D3D11PresentDevice> m_presentDevice;
const D3D_FEATURE_LEVEL m_featureLevel; const D3D_FEATURE_LEVEL m_featureLevel;
const UINT m_featureFlags; const UINT m_featureFlags;

View File

@ -5,6 +5,7 @@
#include "d3d11_device.h" #include "d3d11_device.h"
#include "d3d11_enums.h" #include "d3d11_enums.h"
#include "d3d11_present.h"
namespace dxvk { namespace dxvk {
Logger Logger::s_instance("d3d11.log"); Logger Logger::s_instance("d3d11.log");
@ -110,23 +111,27 @@ extern "C" {
if (ppDevice == nullptr && ppImmediateContext == nullptr) if (ppDevice == nullptr && ppImmediateContext == nullptr)
return S_FALSE; return S_FALSE;
Com<IDXGIVkDevice> dxvkDevice = nullptr; Com<D3D11DeviceContainer> container = new D3D11DeviceContainer();
const VkPhysicalDeviceFeatures deviceFeatures const VkPhysicalDeviceFeatures deviceFeatures
= D3D11Device::GetDeviceFeatures(adapter, fl); = 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"); Logger::err("D3D11CreateDevice: Failed to create DXGI device");
return E_FAIL; return E_FAIL;
} }
Com<D3D11Device> 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) if (ppDevice != nullptr)
*ppDevice = d3d11Device.ref(); *ppDevice = ref(container->m_d3d11Device);
if (ppImmediateContext != nullptr) if (ppImmediateContext != nullptr)
d3d11Device->GetImmediateContext(ppImmediateContext); container->m_d3d11Device->GetImmediateContext(ppImmediateContext);
return S_OK; return S_OK;
} catch (const DxvkError& e) { } catch (const DxvkError& e) {
Logger::err("D3D11CreateDevice: Failed to create D3D11 device"); Logger::err("D3D11CreateDevice: Failed to create D3D11 device");

View File

@ -14,22 +14,37 @@ namespace dxvk {
} }
D3D11PresentDevice:: D3D11PresentDevice() { } D3D11Presenter:: D3D11Presenter(
D3D11PresentDevice::~D3D11PresentDevice() { } IDXGIObject* pContainer,
ID3D11Device* pDevice)
: m_container(pContainer), m_device(pDevice) {
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);
} }
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, const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
IDXGIVkBackBuffer** ppInterface) { IDXGIVkBackBuffer** ppInterface) {
D3D11_COMMON_TEXTURE_DESC desc; D3D11_COMMON_TEXTURE_DESC desc;
desc.Width = pSwapChainDesc->BufferDesc.Width; desc.Width = pSwapChainDesc->BufferDesc.Width;
desc.Height = pSwapChainDesc->BufferDesc.Height; desc.Height = pSwapChainDesc->BufferDesc.Height;
@ -49,7 +64,7 @@ namespace dxvk {
try { try {
*ppInterface = ref(new D3D11VkBackBuffer( *ppInterface = ref(new D3D11VkBackBuffer(
new D3D11Texture2D(m_device, &desc))); new D3D11Texture2D(static_cast<D3D11Device*>(m_device), &desc)));
return S_OK; return S_OK;
} catch (const DxvkError& e) { } catch (const DxvkError& e) {
Logger::err(e.message()); Logger::err(e.message());
@ -58,7 +73,7 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE D3D11PresentDevice::FlushRenderingCommands() { HRESULT STDMETHODCALLTYPE D3D11Presenter::FlushRenderingCommands() {
Com<ID3D11DeviceContext> deviceContext = nullptr; Com<ID3D11DeviceContext> deviceContext = nullptr;
m_device->GetImmediateContext(&deviceContext); 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); return m_device->QueryInterface(riid, ppvDevice);
} }

View File

@ -30,34 +30,43 @@ namespace dxvk {
}; };
class D3D11PresentDevice : public ComObject<IDXGIVkPresenter> { /**
* \brief Present device
*
* Wires up some swap chain related
* functions to the D3D11 device.
*/
class D3D11Presenter final : public IDXGIVkPresenter {
public: public:
D3D11PresentDevice(); D3D11Presenter(
~D3D11PresentDevice(); IDXGIObject* pContainer,
ID3D11Device* pDevice);
~D3D11Presenter();
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface( HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid, REFIID riid,
void** ppvObject) final; void** ppvObject);
HRESULT STDMETHODCALLTYPE CreateSwapChainBackBuffer( HRESULT STDMETHODCALLTYPE CreateSwapChainBackBuffer(
const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
IDXGIVkBackBuffer** ppInterface) final; IDXGIVkBackBuffer** ppInterface);
HRESULT STDMETHODCALLTYPE FlushRenderingCommands() final; HRESULT STDMETHODCALLTYPE FlushRenderingCommands();
HRESULT STDMETHODCALLTYPE GetDevice( HRESULT STDMETHODCALLTYPE GetDevice(
REFGUID riid, REFGUID riid,
void** ppvDevice) final; void** ppvDevice);
void SetDeviceLayer(D3D11Device* pDevice) {
m_device = pDevice;
}
private: private:
D3D11Device* m_device = nullptr; IDXGIObject* m_container;
ID3D11Device* m_device;
}; };

View File

@ -25,9 +25,7 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE DxgiAdapter::QueryInterface( HRESULT STDMETHODCALLTYPE DxgiAdapter::QueryInterface(REFIID riid, void** ppvObject) {
REFIID riid,
void **ppvObject) {
COM_QUERY_IFACE(riid, ppvObject, IUnknown); COM_QUERY_IFACE(riid, ppvObject, IUnknown);
COM_QUERY_IFACE(riid, ppvObject, IDXGIObject); COM_QUERY_IFACE(riid, ppvObject, IDXGIObject);
COM_QUERY_IFACE(riid, ppvObject, IDXGIAdapter); COM_QUERY_IFACE(riid, ppvObject, IDXGIAdapter);
@ -40,9 +38,7 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE DxgiAdapter::GetParent( HRESULT STDMETHODCALLTYPE DxgiAdapter::GetParent(REFIID riid, void** ppParent) {
REFIID riid,
void **ppParent) {
return m_factory->QueryInterface(riid, ppParent); return m_factory->QueryInterface(riid, ppParent);
} }
@ -107,19 +103,17 @@ namespace dxvk {
auto deviceProp = m_adapter->deviceProperties(); auto deviceProp = m_adapter->deviceProperties();
auto memoryProp = m_adapter->memoryProperties(); 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 customVendorID = env::getEnvVar(L"DXVK_CUSTOM_VENDOR_ID");
const std::string customDeviceID = env::getEnvVar(L"DXVK_CUSTOM_DEVICE_ID"); const std::string customDeviceID = env::getEnvVar(L"DXVK_CUSTOM_DEVICE_ID");
if (!customVendorID.empty()) { if (!customVendorID.empty()) {
Logger::info("Using Custom PCI Vendor ID " + customVendorID + " instead of " + str::format(std::hex, deviceProp.vendorID)); Logger::info("Using Custom PCI Vendor ID " + customVendorID + " instead of " + str::format(std::hex, deviceProp.vendorID));
deviceProp.vendorID = std::stoul(customVendorID, nullptr, 16); deviceProp.vendorID = std::stoul(customVendorID, nullptr, 16);
} }
if (!customDeviceID.empty()) { if (!customDeviceID.empty()) {
Logger::info("Using Custom PCI Device ID " + customDeviceID + " instead of " + str::format(std::hex, deviceProp.deviceID)); Logger::info("Using Custom PCI Device ID " + customDeviceID + " instead of " + str::format(std::hex, deviceProp.deviceID));
deviceProp.deviceID = std::stoul(customDeviceID, nullptr, 16); deviceProp.deviceID = std::stoul(customDeviceID, nullptr, 16);
} }
@ -157,10 +151,11 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE DxgiAdapter::CreateDevice( HRESULT STDMETHODCALLTYPE DxgiAdapter::CreateDevice(
IDXGIObject* pContainer,
const VkPhysicalDeviceFeatures* pFeatures, const VkPhysicalDeviceFeatures* pFeatures,
IDXGIVkDevice** ppDevice) { IDXGIVkDevice** ppDevice) {
try { try {
*ppDevice = ref(new dxvk::DxgiDevice(this, pFeatures)); *ppDevice = new dxvk::DxgiDevice(pContainer, this, pFeatures);
return S_OK; return S_OK;
} catch (const dxvk::DxvkError& e) { } catch (const dxvk::DxvkError& e) {
dxvk::Logger::err(e.message()); dxvk::Logger::err(e.message());

View File

@ -50,8 +50,9 @@ namespace dxvk {
Rc<DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() final; Rc<DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() final;
HRESULT STDMETHODCALLTYPE CreateDevice( HRESULT STDMETHODCALLTYPE CreateDevice(
IDXGIObject* pContainer,
const VkPhysicalDeviceFeatures* pFeatures, const VkPhysicalDeviceFeatures* pFeatures,
IDXGIVkDevice** ppDevice) final; IDXGIVkDevice** ppDevice) final;
DxgiFormatInfo STDMETHODCALLTYPE LookupFormat( DxgiFormatInfo STDMETHODCALLTYPE LookupFormat(
DXGI_FORMAT format, DxgiFormatMode mode) final; DXGI_FORMAT format, DxgiFormatMode mode) final;

View File

@ -4,9 +4,11 @@
namespace dxvk { namespace dxvk {
DxgiDevice::DxgiDevice( DxgiDevice::DxgiDevice(
IDXGIVkAdapter* pAdapter, IDXGIObject* pContainer,
IDXGIVkAdapter* pAdapter,
const VkPhysicalDeviceFeatures* pFeatures) const VkPhysicalDeviceFeatures* pFeatures)
: m_adapter(pAdapter) { : m_container (pContainer),
m_adapter (pAdapter) {
m_device = m_adapter->GetDXVKAdapter()->createDevice(*pFeatures); 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) { HRESULT STDMETHODCALLTYPE DxgiDevice::QueryInterface(REFIID riid, void** ppvObject) {
COM_QUERY_IFACE(riid, ppvObject, IUnknown); return m_container->QueryInterface(riid, ppvObject);
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;
} }
@ -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( HRESULT STDMETHODCALLTYPE DxgiDevice::CreateSurface(
const DXGI_SURFACE_DESC* pDesc, const DXGI_SURFACE_DESC* pDesc,
UINT NumSurfaces, UINT NumSurfaces,
@ -125,11 +143,6 @@ namespace dxvk {
} }
void STDMETHODCALLTYPE DxgiDevice::SetDeviceLayer(IUnknown* layer) {
m_layer = layer;
}
Rc<DxvkDevice> STDMETHODCALLTYPE DxgiDevice::GetDXVKDevice() { Rc<DxvkDevice> STDMETHODCALLTYPE DxgiDevice::GetDXVKDevice() {
return m_device; return m_device;
} }

View File

@ -9,22 +9,41 @@ namespace dxvk {
class DxgiFactory; class DxgiFactory;
class DxgiDevice : public DxgiObject<IDXGIVkDevice> { class DxgiDevice : public IDXGIVkDevice {
public: public:
DxgiDevice( DxgiDevice(
IDXGIVkAdapter* pAdapter, IDXGIObject* pContainer,
IDXGIVkAdapter* pAdapter,
const VkPhysicalDeviceFeatures* pFeatures); const VkPhysicalDeviceFeatures* pFeatures);
~DxgiDevice(); ~DxgiDevice();
ULONG STDMETHODCALLTYPE AddRef() final;
ULONG STDMETHODCALLTYPE Release() final;
HRESULT STDMETHODCALLTYPE QueryInterface( HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid, REFIID riid,
void **ppvObject) final; void** ppvObject) final;
HRESULT STDMETHODCALLTYPE GetParent( HRESULT STDMETHODCALLTYPE GetParent(
REFIID riid, REFIID riid,
void **ppParent) final; 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( HRESULT STDMETHODCALLTYPE CreateSurface(
const DXGI_SURFACE_DESC* pDesc, const DXGI_SURFACE_DESC* pDesc,
@ -66,17 +85,14 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE EnqueueSetEvent( HRESULT STDMETHODCALLTYPE EnqueueSetEvent(
HANDLE hEvent) final; HANDLE hEvent) final;
void STDMETHODCALLTYPE SetDeviceLayer(
IUnknown* layer) final;
Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice() final; Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice() final;
private: private:
Com<IDXGIVkAdapter> m_adapter; IDXGIObject* m_container;
Rc<DxvkDevice> m_device;
IUnknown* m_layer = nullptr; Com<IDXGIVkAdapter> m_adapter;
Rc<DxvkDevice> m_device;
}; };

View File

@ -62,8 +62,7 @@ MIDL_INTERFACE("7a622cf6-627a-46b2-b52f-360ef3da831c")
IDXGIVkDevice : public IDXGIDevice2 { IDXGIVkDevice : public IDXGIDevice2 {
static const GUID guid; static const GUID guid;
virtual void STDMETHODCALLTYPE SetDeviceLayer( virtual ~IDXGIVkDevice() { }
IUnknown* layer) = 0;
virtual dxvk::Rc<dxvk::DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice() = 0; virtual dxvk::Rc<dxvk::DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice() = 0;
}; };
@ -91,8 +90,9 @@ IDXGIVkAdapter : public IDXGIAdapter1 {
* \returns \c S_OK on success, or an error code * \returns \c S_OK on success, or an error code
*/ */
virtual HRESULT STDMETHODCALLTYPE CreateDevice( virtual HRESULT STDMETHODCALLTYPE CreateDevice(
IDXGIObject* pContainer,
const VkPhysicalDeviceFeatures* pFeatures, const VkPhysicalDeviceFeatures* pFeatures,
IDXGIVkDevice** ppDevice) = 0; IDXGIVkDevice** ppDevice) = 0;
/** /**
* \brief Maps a DXGI format to a compatible Vulkan format * \brief Maps a DXGI format to a compatible Vulkan format
@ -140,11 +140,13 @@ IDXGIVkPresenter : public IUnknown {
/** /**
* \brief Creates a swap chain back buffer * \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 * \returns \c S_OK on success
*/ */
virtual HRESULT STDMETHODCALLTYPE CreateSwapChainBackBuffer( virtual HRESULT STDMETHODCALLTYPE CreateSwapChainBackBuffer(
const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
IDXGIVkBackBuffer** ppBackBuffer) = 0; IDXGIVkBackBuffer** ppBackBuffer) = 0;
/** /**
* \brief Flushes the immediate context * \brief Flushes the immediate context

View File

@ -94,9 +94,6 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetContainingOutput(IDXGIOutput** ppOutput) { HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetContainingOutput(IDXGIOutput** ppOutput) {
if (ppOutput == nullptr)
return DXGI_ERROR_INVALID_CALL;
RECT windowRect = { 0, 0, 0, 0 }; RECT windowRect = { 0, 0, 0, 0 };
::GetWindowRect(m_desc.OutputWindow, &windowRect); ::GetWindowRect(m_desc.OutputWindow, &windowRect);