mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 16:29:16 +01:00
[dxgi] Refactor swap chain creation
Cleans up constructor and moves a bunch of common code to the new CreateDxvkSwapChainForHwnd function, which can be called from both d3d11 and dxgi. Also fixes potential issues with the current implementation of the IWineDXGISwapChainFactory interface.
This commit is contained in:
parent
15078357dc
commit
4e22e4bc3a
@ -1671,26 +1671,27 @@ namespace dxvk {
|
||||
|
||||
|
||||
|
||||
WineDXGISwapChainFactory::WineDXGISwapChainFactory(IUnknown* pContainer)
|
||||
: m_container(pContainer) {
|
||||
WineDXGISwapChainFactory::WineDXGISwapChainFactory(
|
||||
IDXGIVkPresentDevice* pDevice)
|
||||
: m_device(pDevice) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory::AddRef() {
|
||||
return m_container->AddRef();
|
||||
return m_device->AddRef();
|
||||
}
|
||||
|
||||
|
||||
ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory::Release() {
|
||||
return m_container->Release();
|
||||
return m_device->Release();
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WineDXGISwapChainFactory::QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) {
|
||||
return m_container->QueryInterface(riid, ppvObject);
|
||||
return m_device->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
|
||||
@ -1703,15 +1704,13 @@ namespace dxvk {
|
||||
IDXGISwapChain1** ppSwapChain) {
|
||||
InitReturnPtr(ppSwapChain);
|
||||
|
||||
try {
|
||||
*ppSwapChain = ref(new DxgiSwapChain(
|
||||
pFactory, m_container, hWnd,
|
||||
pDesc, pFullscreenDesc));
|
||||
return S_OK;
|
||||
} catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
if (!ppSwapChain || !pDesc || !hWnd)
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
}
|
||||
|
||||
return CreateDxvkSwapChainForHwnd(
|
||||
pFactory, m_device, hWnd, pDesc,
|
||||
pFullscreenDesc, pRestrictToOutput,
|
||||
ppSwapChain);
|
||||
}
|
||||
|
||||
|
||||
@ -1728,7 +1727,7 @@ namespace dxvk {
|
||||
m_d3d11Device (this, FeatureLevel, FeatureFlags),
|
||||
m_d3d11Presenter(this, &m_d3d11Device),
|
||||
m_d3d11Interop (this, &m_d3d11Device),
|
||||
m_wineFactory (this) {
|
||||
m_wineFactory (&m_d3d11Presenter) {
|
||||
for (uint32_t i = 0; i < m_frameEvents.size(); i++)
|
||||
m_frameEvents[i] = new DxvkEvent();
|
||||
}
|
||||
|
@ -399,7 +399,8 @@ namespace dxvk {
|
||||
|
||||
public:
|
||||
|
||||
WineDXGISwapChainFactory(IUnknown* pContainer);
|
||||
WineDXGISwapChainFactory(
|
||||
IDXGIVkPresentDevice* pDevice);
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
|
||||
@ -419,7 +420,7 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
IUnknown* m_container;
|
||||
IDXGIVkPresentDevice* m_device;
|
||||
|
||||
};
|
||||
|
||||
|
@ -110,30 +110,22 @@ namespace dxvk {
|
||||
IDXGISwapChain1** ppSwapChain) {
|
||||
InitReturnPtr(ppSwapChain);
|
||||
|
||||
if (ppSwapChain == nullptr || pDesc == nullptr || hWnd == nullptr || pDevice == nullptr)
|
||||
if (!ppSwapChain || !pDesc || !hWnd || !pDevice)
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
|
||||
// If necessary, set up a default set of
|
||||
// fullscreen parameters for the swap chain
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDesc;
|
||||
Com<IDXGIVkPresentDevice> dxvkDevice;
|
||||
|
||||
if (pFullscreenDesc != nullptr) {
|
||||
fullscreenDesc = *pFullscreenDesc;
|
||||
} else {
|
||||
fullscreenDesc.RefreshRate = { 0, 0 };
|
||||
fullscreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
fullscreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
fullscreenDesc.Windowed = TRUE;
|
||||
if (SUCCEEDED(pDevice->QueryInterface(
|
||||
__uuidof(IDXGIVkPresentDevice),
|
||||
reinterpret_cast<void**>(&dxvkDevice)))) {
|
||||
return CreateDxvkSwapChainForHwnd(
|
||||
this, dxvkDevice.ptr(), hWnd, pDesc,
|
||||
pFullscreenDesc, pRestrictToOutput,
|
||||
ppSwapChain);
|
||||
}
|
||||
|
||||
try {
|
||||
*ppSwapChain = ref(new DxgiSwapChain(this,
|
||||
pDevice, hWnd, pDesc, &fullscreenDesc));
|
||||
return S_OK;
|
||||
} catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
return E_FAIL;
|
||||
}
|
||||
Logger::err("DXGI: CreateSwapChainForHwnd: Unsupported device type");
|
||||
return DXGI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ namespace dxvk {
|
||||
|
||||
DxgiSwapChain::DxgiSwapChain(
|
||||
IDXGIFactory* pFactory,
|
||||
IUnknown* pDevice,
|
||||
IDXGIVkSwapChain* pPresenter,
|
||||
HWND hWnd,
|
||||
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc)
|
||||
@ -14,6 +14,7 @@ namespace dxvk {
|
||||
m_window (hWnd),
|
||||
m_desc (*pDesc),
|
||||
m_descFs (*pFullscreenDesc),
|
||||
m_presenter (pPresenter),
|
||||
m_monitor (nullptr) {
|
||||
// Initialize frame statistics
|
||||
m_stats.PresentCount = 0;
|
||||
@ -22,20 +23,10 @@ namespace dxvk {
|
||||
m_stats.SyncQPCTime.QuadPart = 0;
|
||||
m_stats.SyncGPUTime.QuadPart = 0;
|
||||
|
||||
// Adjust initial back buffer size. If zero, these
|
||||
// shall be set to the current window size.
|
||||
GetWindowClientSize(m_window,
|
||||
m_desc.Width ? nullptr : &m_desc.Width,
|
||||
m_desc.Height ? nullptr : &m_desc.Height);
|
||||
|
||||
// Create presenter, which also serves as an interface to the device
|
||||
if (FAILED(CreatePresenter(pDevice, &m_presenter)))
|
||||
throw DxvkError("DXGI: Failed to create presenter");
|
||||
|
||||
if (FAILED(m_presenter->GetAdapter(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_adapter))))
|
||||
throw DxvkError("DXGI: Failed to get adapter for present device");
|
||||
|
||||
// Set initial window mode and fullscreen state
|
||||
// Apply initial window mode and fullscreen state
|
||||
if (!m_descFs.Windowed && FAILED(EnterFullscreenMode(nullptr)))
|
||||
throw DxvkError("DXGI: Failed to set initial fullscreen state");
|
||||
}
|
||||
@ -674,21 +665,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
HRESULT DxgiSwapChain::CreatePresenter(
|
||||
IUnknown* pDevice,
|
||||
IDXGIVkSwapChain** ppSwapChain) {
|
||||
Com<IDXGIVkPresentDevice> presentDevice;
|
||||
|
||||
// Retrieve a device pointer that allows us to
|
||||
// communicate with the underlying D3D device
|
||||
if (SUCCEEDED(pDevice->QueryInterface(__uuidof(IDXGIVkPresentDevice),
|
||||
reinterpret_cast<void**>(&presentDevice))))
|
||||
return presentDevice->CreateSwapChainForHwnd(m_window, &m_desc, ppSwapChain);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
||||
HRESULT DxgiSwapChain::GetOutputFromMonitor(
|
||||
HMONITOR Monitor,
|
||||
IDXGIOutput** ppOutput) {
|
||||
@ -709,4 +685,53 @@ namespace dxvk {
|
||||
return DXGI_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CreateDxvkSwapChainForHwnd(
|
||||
IDXGIFactory* pFactory,
|
||||
IDXGIVkPresentDevice* pDevice,
|
||||
HWND hWnd,
|
||||
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
|
||||
IDXGIOutput* pRestrictToOutput,
|
||||
IDXGISwapChain1** ppSwapChain) {
|
||||
// Make sure the back buffer size is not zero
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = *pDesc;
|
||||
|
||||
GetWindowClientSize(hWnd,
|
||||
desc.Width ? nullptr : &desc.Width,
|
||||
desc.Height ? nullptr : &desc.Height);
|
||||
|
||||
// If necessary, set up a default set of
|
||||
// fullscreen parameters for the swap chain
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc;
|
||||
|
||||
if (pFullscreenDesc) {
|
||||
fsDesc = *pFullscreenDesc;
|
||||
} else {
|
||||
fsDesc.RefreshRate = { 0, 0 };
|
||||
fsDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
fsDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
fsDesc.Windowed = TRUE;
|
||||
}
|
||||
|
||||
// Create presenter for the device
|
||||
Com<IDXGIVkSwapChain> presenter;
|
||||
|
||||
HRESULT hr = pDevice->CreateSwapChainForHwnd(
|
||||
hWnd, &desc, &presenter);
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
try {
|
||||
// Create actual swap chain object
|
||||
*ppSwapChain = ref(new DxgiSwapChain(
|
||||
pFactory, presenter.ptr(), hWnd, &desc, &fsDesc));
|
||||
return S_OK;
|
||||
} catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
return DXGI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace dxvk {
|
||||
|
||||
DxgiSwapChain(
|
||||
IDXGIFactory* pFactory,
|
||||
IUnknown* pDevice,
|
||||
IDXGIVkSwapChain* pPresenter,
|
||||
HWND hWnd,
|
||||
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc);
|
||||
@ -199,14 +199,20 @@ namespace dxvk {
|
||||
UINT Count,
|
||||
VkSampleCountFlagBits* pCount) const;
|
||||
|
||||
HRESULT CreatePresenter(
|
||||
IUnknown* pDevice,
|
||||
IDXGIVkSwapChain** ppSwapChain);
|
||||
|
||||
HRESULT GetOutputFromMonitor(
|
||||
HMONITOR Monitor,
|
||||
IDXGIOutput** ppOutput);
|
||||
|
||||
};
|
||||
|
||||
|
||||
HRESULT CreateDxvkSwapChainForHwnd(
|
||||
IDXGIFactory* pFactory,
|
||||
IDXGIVkPresentDevice* pDevice,
|
||||
HWND hWnd,
|
||||
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
|
||||
IDXGIOutput* pRestrictToOutput,
|
||||
IDXGISwapChain1** ppSwapChain);
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user