mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-29 17:52:18 +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:
parent
8d3dcba8d5
commit
ae88f83b86
@ -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<IDXGIAdapter> adapter;
|
||||
|
||||
if (FAILED(m_dxgiDevice->GetAdapter(&adapter))
|
||||
if (FAILED(pDxgiDevice->GetAdapter(&adapter))
|
||||
|| FAILED(adapter->QueryInterface(__uuidof(IDXGIVkAdapter),
|
||||
reinterpret_cast<void**>(&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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<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
|
||||
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<DxvkDevice> GetDXVKDevice() {
|
||||
return m_dxvkDevice;
|
||||
@ -298,9 +337,8 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
const Com<IDXGIVkDevice> m_dxgiDevice;
|
||||
Com<IDXGIVkAdapter> m_dxgiAdapter;
|
||||
const Com<D3D11PresentDevice> m_presentDevice;
|
||||
IDXGIObject* m_container;
|
||||
Com<IDXGIVkAdapter> m_dxgiAdapter;
|
||||
|
||||
const D3D_FEATURE_LEVEL m_featureLevel;
|
||||
const UINT m_featureFlags;
|
||||
|
@ -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<IDXGIVkDevice> dxvkDevice = nullptr;
|
||||
Com<D3D11DeviceContainer> 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> 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");
|
||||
|
@ -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<D3D11Device*>(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<ID3D11DeviceContext> 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);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
|
@ -50,8 +50,9 @@ namespace dxvk {
|
||||
Rc<DxvkAdapter> 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;
|
||||
|
@ -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<DxvkDevice> STDMETHODCALLTYPE DxgiDevice::GetDXVKDevice() {
|
||||
return m_device;
|
||||
}
|
||||
|
@ -9,22 +9,41 @@ namespace dxvk {
|
||||
|
||||
class DxgiFactory;
|
||||
|
||||
class DxgiDevice : public DxgiObject<IDXGIVkDevice> {
|
||||
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<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice() final;
|
||||
|
||||
private:
|
||||
|
||||
Com<IDXGIVkAdapter> m_adapter;
|
||||
Rc<DxvkDevice> m_device;
|
||||
IDXGIObject* m_container;
|
||||
|
||||
IUnknown* m_layer = nullptr;
|
||||
Com<IDXGIVkAdapter> m_adapter;
|
||||
Rc<DxvkDevice> m_device;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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<dxvk::DxvkDevice> 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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user