mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-12 22:08:59 +01:00
271 lines
8.1 KiB
C++
271 lines
8.1 KiB
C++
#include "dxgi_factory.h"
|
|
#include "dxgi_swapchain.h"
|
|
|
|
namespace dxvk {
|
|
|
|
DxgiFactory::DxgiFactory()
|
|
: m_instance(new DxvkInstance()),
|
|
m_options (m_instance->config()) {
|
|
for (uint32_t i = 0; m_instance->enumAdapters(i) != nullptr; i++)
|
|
m_instance->enumAdapters(i)->logAdapterInfo();
|
|
}
|
|
|
|
|
|
DxgiFactory::~DxgiFactory() {
|
|
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::QueryInterface(REFIID riid, void** ppvObject) {
|
|
*ppvObject = nullptr;
|
|
|
|
if (riid == __uuidof(IUnknown)
|
|
|| riid == __uuidof(IDXGIObject)
|
|
|| riid == __uuidof(IDXGIFactory)
|
|
|| riid == __uuidof(IDXGIFactory1)
|
|
|| riid == __uuidof(IDXGIFactory2)) {
|
|
*ppvObject = ref(this);
|
|
return S_OK;
|
|
}
|
|
|
|
Logger::warn("DxgiFactory::QueryInterface: Unknown interface query");
|
|
Logger::warn(str::format(riid));
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::GetParent(REFIID riid, void** ppParent) {
|
|
InitReturnPtr(ppParent);
|
|
|
|
Logger::warn("DxgiFactory::GetParent: Unknown interface query");
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
BOOL STDMETHODCALLTYPE DxgiFactory::IsWindowedStereoEnabled() {
|
|
// We don't support Stereo 3D at the moment
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::CreateSoftwareAdapter(
|
|
HMODULE Module,
|
|
IDXGIAdapter** ppAdapter) {
|
|
InitReturnPtr(ppAdapter);
|
|
|
|
if (ppAdapter == nullptr)
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
Logger::err("DXGI: CreateSoftwareAdapter: Software adapters not supported");
|
|
return DXGI_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::CreateSwapChain(
|
|
IUnknown* pDevice,
|
|
DXGI_SWAP_CHAIN_DESC* pDesc,
|
|
IDXGISwapChain** ppSwapChain) {
|
|
if (ppSwapChain == nullptr || pDesc == nullptr || pDevice == nullptr)
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
DXGI_SWAP_CHAIN_DESC1 desc;
|
|
desc.Width = pDesc->BufferDesc.Width;
|
|
desc.Height = pDesc->BufferDesc.Height;
|
|
desc.Format = pDesc->BufferDesc.Format;
|
|
desc.Stereo = FALSE;
|
|
desc.SampleDesc = pDesc->SampleDesc;
|
|
desc.BufferUsage = pDesc->BufferUsage;
|
|
desc.BufferCount = pDesc->BufferCount;
|
|
desc.Scaling = DXGI_SCALING_STRETCH;
|
|
desc.SwapEffect = pDesc->SwapEffect;
|
|
desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
|
desc.Flags = pDesc->Flags;
|
|
|
|
DXGI_SWAP_CHAIN_FULLSCREEN_DESC descFs;
|
|
descFs.RefreshRate = pDesc->BufferDesc.RefreshRate;
|
|
descFs.ScanlineOrdering = pDesc->BufferDesc.ScanlineOrdering;
|
|
descFs.Scaling = pDesc->BufferDesc.Scaling;
|
|
descFs.Windowed = pDesc->Windowed;
|
|
|
|
IDXGISwapChain1* swapChain = nullptr;
|
|
HRESULT hr = CreateSwapChainForHwnd(
|
|
pDevice, pDesc->OutputWindow,
|
|
&desc, &descFs, nullptr,
|
|
&swapChain);
|
|
|
|
*ppSwapChain = swapChain;
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::CreateSwapChainForHwnd(
|
|
IUnknown* pDevice,
|
|
HWND hWnd,
|
|
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
|
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
|
|
IDXGIOutput* pRestrictToOutput,
|
|
IDXGISwapChain1** ppSwapChain) {
|
|
InitReturnPtr(ppSwapChain);
|
|
|
|
if (ppSwapChain == nullptr || pDesc == nullptr || hWnd == nullptr || pDevice == nullptr)
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
try {
|
|
*ppSwapChain = ref(new DxgiSwapChain(this,
|
|
pDevice, hWnd, pDesc, &fullscreenDesc));
|
|
return S_OK;
|
|
} catch (const DxvkError& e) {
|
|
Logger::err(e.message());
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::CreateSwapChainForCoreWindow(
|
|
IUnknown* pDevice,
|
|
IUnknown* pWindow,
|
|
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
|
IDXGIOutput* pRestrictToOutput,
|
|
IDXGISwapChain1** ppSwapChain) {
|
|
InitReturnPtr(ppSwapChain);
|
|
|
|
Logger::err("DxgiFactory::CreateSwapChainForCoreWindow: Not implemented");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::CreateSwapChainForComposition(
|
|
IUnknown* pDevice,
|
|
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
|
IDXGIOutput* pRestrictToOutput,
|
|
IDXGISwapChain1** ppSwapChain) {
|
|
InitReturnPtr(ppSwapChain);
|
|
|
|
Logger::err("DxgiFactory::CreateSwapChainForComposition: Not implemented");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::EnumAdapters(
|
|
UINT Adapter,
|
|
IDXGIAdapter** ppAdapter) {
|
|
InitReturnPtr(ppAdapter);
|
|
|
|
if (ppAdapter == nullptr)
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
IDXGIAdapter1* handle = nullptr;
|
|
HRESULT hr = this->EnumAdapters1(Adapter, &handle);
|
|
*ppAdapter = handle;
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::EnumAdapters1(
|
|
UINT Adapter,
|
|
IDXGIAdapter1** ppAdapter) {
|
|
InitReturnPtr(ppAdapter);
|
|
|
|
if (ppAdapter == nullptr)
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
Rc<DxvkAdapter> dxvkAdapter
|
|
= m_instance->enumAdapters(Adapter);
|
|
|
|
if (dxvkAdapter == nullptr)
|
|
return DXGI_ERROR_NOT_FOUND;
|
|
|
|
*ppAdapter = ref(new DxgiAdapter(this, dxvkAdapter));
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::GetWindowAssociation(HWND *pWindowHandle) {
|
|
if (pWindowHandle == nullptr)
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
*pWindowHandle = m_associatedWindow;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::GetSharedResourceAdapterLuid(
|
|
HANDLE hResource,
|
|
LUID* pLuid) {
|
|
Logger::err("DxgiFactory::GetSharedResourceAdapterLuid: Not implemented");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::MakeWindowAssociation(HWND WindowHandle, UINT Flags) {
|
|
Logger::warn("DXGI: MakeWindowAssociation: Ignoring flags");
|
|
m_associatedWindow = WindowHandle;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
BOOL STDMETHODCALLTYPE DxgiFactory::IsCurrent() {
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::RegisterOcclusionStatusWindow(
|
|
HWND WindowHandle,
|
|
UINT wMsg,
|
|
DWORD* pdwCookie) {
|
|
Logger::err("DxgiFactory::RegisterOcclusionStatusWindow: Not implemented");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::RegisterStereoStatusEvent(
|
|
HANDLE hEvent,
|
|
DWORD* pdwCookie) {
|
|
Logger::err("DxgiFactory::RegisterStereoStatusEvent: Not implemented");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::RegisterStereoStatusWindow(
|
|
HWND WindowHandle,
|
|
UINT wMsg,
|
|
DWORD* pdwCookie) {
|
|
Logger::err("DxgiFactory::RegisterStereoStatusWindow: Not implemented");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiFactory::RegisterOcclusionStatusEvent(
|
|
HANDLE hEvent,
|
|
DWORD* pdwCookie) {
|
|
Logger::err("DxgiFactory::RegisterOcclusionStatusEvent: Not implemented");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
void STDMETHODCALLTYPE DxgiFactory::UnregisterStereoStatus(
|
|
DWORD dwCookie) {
|
|
Logger::err("DxgiFactory::UnregisterStereoStatus: Not implemented");
|
|
}
|
|
|
|
|
|
void STDMETHODCALLTYPE DxgiFactory::UnregisterOcclusionStatus(
|
|
DWORD dwCookie) {
|
|
Logger::err("DxgiFactory::UnregisterOcclusionStatus: Not implemented");
|
|
}
|
|
|
|
}
|