#include "dxgi_factory.h" #include "dxgi_swapchain.h" namespace dxvk { DxgiFactory::DxgiFactory() : m_instance(new DxvkInstance()), m_adapters(m_instance->enumAdapters()) { for (const auto& adapter : m_adapters) adapter->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; if (Adapter >= m_adapters.size()) return DXGI_ERROR_NOT_FOUND; *ppAdapter = ref(new DxgiAdapter( this, m_adapters.at(Adapter))); 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() { Logger::warn("DxgiFactory::IsCurrent: Stub"); 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"); } }