1
0
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:
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 {
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);
}

View File

@ -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;

View File

@ -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");

View File

@ -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);
}

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:
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;
};

View File

@ -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());

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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);