Merge pull request #8096 from stenzek/d3d-old-drivers
D3DCommon: Fallback to base CreateSwapChain on failure
This commit is contained in:
commit
6567409177
|
@ -23,7 +23,7 @@ namespace DX11
|
|||
static Common::DynamicLibrary s_d3d11_library;
|
||||
namespace D3D
|
||||
{
|
||||
ComPtr<IDXGIFactory2> dxgi_factory;
|
||||
ComPtr<IDXGIFactory> dxgi_factory;
|
||||
ComPtr<ID3D11Device> device;
|
||||
ComPtr<ID3D11Device1> device1;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
|
@ -173,7 +173,7 @@ std::vector<u32> GetAAModes(u32 adapter_index)
|
|||
ComPtr<ID3D11Device> temp_device = device;
|
||||
if (!temp_device)
|
||||
{
|
||||
ComPtr<IDXGIFactory2> temp_dxgi_factory = D3DCommon::CreateDXGIFactory(false);
|
||||
ComPtr<IDXGIFactory> temp_dxgi_factory = D3DCommon::CreateDXGIFactory(false);
|
||||
if (!temp_dxgi_factory)
|
||||
return {};
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class SwapChain;
|
|||
|
||||
namespace D3D
|
||||
{
|
||||
extern ComPtr<IDXGIFactory2> dxgi_factory;
|
||||
extern ComPtr<IDXGIFactory> dxgi_factory;
|
||||
extern ComPtr<ID3D11Device> device;
|
||||
extern ComPtr<ID3D11Device1> device1;
|
||||
extern ComPtr<ID3D11DeviceContext> context;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace DX11
|
||||
{
|
||||
SwapChain::SwapChain(const WindowSystemInfo& wsi, IDXGIFactory2* dxgi_factory,
|
||||
SwapChain::SwapChain(const WindowSystemInfo& wsi, IDXGIFactory* dxgi_factory,
|
||||
ID3D11Device* d3d_device)
|
||||
: D3DCommon::SwapChain(wsi, dxgi_factory, d3d_device)
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@ class DXFramebuffer;
|
|||
class SwapChain : public D3DCommon::SwapChain
|
||||
{
|
||||
public:
|
||||
SwapChain(const WindowSystemInfo& wsi, IDXGIFactory2* dxgi_factory, ID3D11Device* d3d_device);
|
||||
SwapChain(const WindowSystemInfo& wsi, IDXGIFactory* dxgi_factory, ID3D11Device* d3d_device);
|
||||
~SwapChain();
|
||||
|
||||
static std::unique_ptr<SwapChain> Create(const WindowSystemInfo& wsi);
|
||||
|
|
|
@ -43,7 +43,7 @@ std::vector<u32> DXContext::GetAAModes(u32 adapter_index)
|
|||
ComPtr<ID3D12Device> temp_device = g_dx_context ? g_dx_context->m_device : nullptr;
|
||||
if (!temp_device)
|
||||
{
|
||||
ComPtr<IDXGIFactory2> temp_dxgi_factory = D3DCommon::CreateDXGIFactory(false);
|
||||
ComPtr<IDXGIFactory> temp_dxgi_factory = D3DCommon::CreateDXGIFactory(false);
|
||||
if (!temp_dxgi_factory)
|
||||
return {};
|
||||
|
||||
|
@ -57,7 +57,8 @@ std::vector<u32> DXContext::GetAAModes(u32 adapter_index)
|
|||
return {};
|
||||
}
|
||||
|
||||
HRESULT hr = d3d12_create_device(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&temp_device));
|
||||
HRESULT hr =
|
||||
d3d12_create_device(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&temp_device));
|
||||
if (!SUCCEEDED(hr))
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "VideoBackends/D3D12/Common.h"
|
||||
|
@ -14,7 +12,7 @@
|
|||
#include "VideoBackends/D3D12/DescriptorHeapManager.h"
|
||||
#include "VideoBackends/D3D12/StreamBuffer.h"
|
||||
|
||||
struct IDXGIFactory2;
|
||||
struct IDXGIFactory;
|
||||
|
||||
namespace DX12
|
||||
{
|
||||
|
@ -54,7 +52,7 @@ public:
|
|||
// Destroys active context.
|
||||
static void Destroy();
|
||||
|
||||
IDXGIFactory2* GetDXGIFactory() const { return m_dxgi_factory.Get(); }
|
||||
IDXGIFactory* GetDXGIFactory() const { return m_dxgi_factory.Get(); }
|
||||
ID3D12Device* GetDevice() const { return m_device.Get(); }
|
||||
ID3D12CommandQueue* GetCommandQueue() const { return m_command_queue.Get(); }
|
||||
|
||||
|
@ -159,7 +157,7 @@ private:
|
|||
void MoveToNextCommandList();
|
||||
void DestroyPendingResources(CommandListResources& cmdlist);
|
||||
|
||||
ComPtr<IDXGIFactory2> m_dxgi_factory;
|
||||
ComPtr<IDXGIFactory> m_dxgi_factory;
|
||||
ComPtr<ID3D12Debug> m_debug_interface;
|
||||
ComPtr<ID3D12Device> m_device;
|
||||
ComPtr<ID3D12CommandQueue> m_command_queue;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace DX12
|
||||
{
|
||||
SwapChain::SwapChain(const WindowSystemInfo& wsi, IDXGIFactory2* dxgi_factory,
|
||||
SwapChain::SwapChain(const WindowSystemInfo& wsi, IDXGIFactory* dxgi_factory,
|
||||
ID3D12CommandQueue* d3d_command_queue)
|
||||
: D3DCommon::SwapChain(wsi, dxgi_factory, d3d_command_queue)
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@ class DXFramebuffer;
|
|||
class SwapChain : public D3DCommon::SwapChain
|
||||
{
|
||||
public:
|
||||
SwapChain(const WindowSystemInfo& wsi, IDXGIFactory2* dxgi_factory,
|
||||
SwapChain(const WindowSystemInfo& wsi, IDXGIFactory* dxgi_factory,
|
||||
ID3D12CommandQueue* d3d_command_queue);
|
||||
~SwapChain();
|
||||
|
||||
|
|
|
@ -72,9 +72,9 @@ void UnloadLibraries()
|
|||
s_libraries_loaded = false;
|
||||
}
|
||||
|
||||
IDXGIFactory2* CreateDXGIFactory(bool debug_device)
|
||||
IDXGIFactory* CreateDXGIFactory(bool debug_device)
|
||||
{
|
||||
IDXGIFactory2* factory;
|
||||
IDXGIFactory* factory;
|
||||
|
||||
// Use Win8.1 version if available.
|
||||
if (create_dxgi_factory2 &&
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "Common/CommonTypes.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
struct IDXGIFactory2;
|
||||
struct IDXGIFactory;
|
||||
|
||||
enum class AbstractTextureFormat : u32;
|
||||
|
||||
|
@ -26,7 +26,7 @@ void UnloadLibraries();
|
|||
std::vector<std::string> GetAdapterNames();
|
||||
|
||||
// Helper function which creates a DXGI factory.
|
||||
IDXGIFactory2* CreateDXGIFactory(bool debug_device);
|
||||
IDXGIFactory* CreateDXGIFactory(bool debug_device);
|
||||
|
||||
// Globally-accessible D3DCompiler function.
|
||||
extern pD3DCompile d3d_compile;
|
||||
|
|
|
@ -25,7 +25,7 @@ static bool IsTearingSupported(IDXGIFactory2* dxgi_factory)
|
|||
allow_tearing != 0;
|
||||
}
|
||||
|
||||
static bool GetFullscreenState(IDXGISwapChain1* swap_chain)
|
||||
static bool GetFullscreenState(IDXGISwapChain* swap_chain)
|
||||
{
|
||||
BOOL fs = FALSE;
|
||||
return SUCCEEDED(swap_chain->GetFullscreenState(&fs, nullptr)) && fs;
|
||||
|
@ -33,9 +33,8 @@ static bool GetFullscreenState(IDXGISwapChain1* swap_chain)
|
|||
|
||||
namespace D3DCommon
|
||||
{
|
||||
SwapChain::SwapChain(const WindowSystemInfo& wsi, IDXGIFactory2* dxgi_factory, IUnknown* d3d_device)
|
||||
: m_wsi(wsi), m_dxgi_factory(dxgi_factory), m_d3d_device(d3d_device),
|
||||
m_allow_tearing_supported(IsTearingSupported(dxgi_factory))
|
||||
SwapChain::SwapChain(const WindowSystemInfo& wsi, IDXGIFactory* dxgi_factory, IUnknown* d3d_device)
|
||||
: m_wsi(wsi), m_dxgi_factory(dxgi_factory), m_d3d_device(d3d_device)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,40 +65,63 @@ bool SwapChain::CreateSwapChain(bool stereo)
|
|||
m_height = client_rc.bottom - client_rc.top;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
|
||||
swap_chain_desc.Width = m_width;
|
||||
swap_chain_desc.Height = m_height;
|
||||
swap_chain_desc.BufferCount = SWAP_CHAIN_BUFFER_COUNT;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.Format = GetDXGIFormatForAbstractFormat(m_texture_format, false);
|
||||
swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swap_chain_desc.Stereo = stereo;
|
||||
swap_chain_desc.Flags = GetSwapChainFlags();
|
||||
|
||||
HRESULT hr = m_dxgi_factory->CreateSwapChainForHwnd(
|
||||
m_d3d_device.Get(), static_cast<HWND>(m_wsi.render_surface), &swap_chain_desc, nullptr,
|
||||
nullptr, &m_swap_chain);
|
||||
if (FAILED(hr))
|
||||
// Try using the Win8 version if available.
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory2> dxgi_factory2;
|
||||
HRESULT hr = m_dxgi_factory.As(&dxgi_factory2);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Flip-model discard swapchains aren't supported on Windows 8, so here we fall back to
|
||||
// a sequential swapchain
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
hr = m_dxgi_factory->CreateSwapChainForHwnd(m_d3d_device.Get(),
|
||||
static_cast<HWND>(m_wsi.render_surface),
|
||||
&swap_chain_desc, nullptr, nullptr, &m_swap_chain);
|
||||
m_allow_tearing_supported = IsTearingSupported(dxgi_factory2.Get());
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
|
||||
swap_chain_desc.Width = m_width;
|
||||
swap_chain_desc.Height = m_height;
|
||||
swap_chain_desc.BufferCount = SWAP_CHAIN_BUFFER_COUNT;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.Format = GetDXGIFormatForAbstractFormat(m_texture_format, false);
|
||||
swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swap_chain_desc.Stereo = stereo;
|
||||
swap_chain_desc.Flags = GetSwapChainFlags();
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain1;
|
||||
hr = dxgi_factory2->CreateSwapChainForHwnd(m_d3d_device.Get(),
|
||||
static_cast<HWND>(m_wsi.render_surface),
|
||||
&swap_chain_desc, nullptr, nullptr, &swap_chain1);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Flip-model discard swapchains aren't supported on Windows 8, so here we fall back to
|
||||
// a sequential swapchain
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
hr = dxgi_factory2->CreateSwapChainForHwnd(m_d3d_device.Get(),
|
||||
static_cast<HWND>(m_wsi.render_surface),
|
||||
&swap_chain_desc, nullptr, nullptr, &swap_chain1);
|
||||
}
|
||||
|
||||
m_swap_chain = swap_chain1;
|
||||
}
|
||||
|
||||
// Flip-model swapchains aren't supported on Windows 7, so here we fall back to a legacy
|
||||
// BitBlt-model swapchain. Note that this won't work for DX12, but systems which don't
|
||||
// support the newer DXGI interface aren't going to support DX12 anyway.
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Flip-model swapchains aren't supported on Windows 7, so here we fall back to a legacy
|
||||
// BitBlt-model swapchain
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
hr = m_dxgi_factory->CreateSwapChainForHwnd(m_d3d_device.Get(),
|
||||
static_cast<HWND>(m_wsi.render_surface),
|
||||
&swap_chain_desc, nullptr, nullptr, &m_swap_chain);
|
||||
DXGI_SWAP_CHAIN_DESC desc = {};
|
||||
desc.BufferDesc.Width = m_width;
|
||||
desc.BufferDesc.Height = m_height;
|
||||
desc.BufferDesc.Format = GetDXGIFormatForAbstractFormat(m_texture_format, false);
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
desc.BufferCount = SWAP_CHAIN_BUFFER_COUNT;
|
||||
desc.OutputWindow = static_cast<HWND>(m_wsi.render_surface);
|
||||
desc.Windowed = TRUE;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
desc.Flags = 0;
|
||||
|
||||
m_allow_tearing_supported = false;
|
||||
hr = m_dxgi_factory->CreateSwapChain(m_d3d_device.Get(), &desc, &m_swap_chain);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
|
@ -147,11 +169,11 @@ bool SwapChain::ResizeSwapChain()
|
|||
if (FAILED(hr))
|
||||
WARN_LOG(VIDEO, "ResizeBuffers() failed with HRESULT %08X", hr);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 desc;
|
||||
if (SUCCEEDED(m_swap_chain->GetDesc1(&desc)))
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
if (SUCCEEDED(m_swap_chain->GetDesc(&desc)))
|
||||
{
|
||||
m_width = desc.Width;
|
||||
m_height = desc.Height;
|
||||
m_width = desc.BufferDesc.Width;
|
||||
m_height = desc.BufferDesc.Height;
|
||||
}
|
||||
|
||||
return CreateSwapChainBuffers();
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace D3DCommon
|
|||
class SwapChain
|
||||
{
|
||||
public:
|
||||
SwapChain(const WindowSystemInfo& wsi, IDXGIFactory2* dxgi_factory, IUnknown* d3d_device);
|
||||
SwapChain(const WindowSystemInfo& wsi, IDXGIFactory* dxgi_factory, IUnknown* d3d_device);
|
||||
virtual ~SwapChain();
|
||||
|
||||
// Sufficient buffers for triple buffering.
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
// Returns true if the stereo mode is quad-buffering.
|
||||
static bool WantsStereo();
|
||||
|
||||
IDXGISwapChain1* GetDXGISwapChain() const { return m_swap_chain.Get(); }
|
||||
IDXGISwapChain* GetDXGISwapChain() const { return m_swap_chain.Get(); }
|
||||
AbstractTextureFormat GetFormat() const { return m_texture_format; }
|
||||
u32 GetWidth() const { return m_width; }
|
||||
u32 GetHeight() const { return m_height; }
|
||||
|
@ -57,8 +57,8 @@ protected:
|
|||
virtual void DestroySwapChainBuffers() = 0;
|
||||
|
||||
WindowSystemInfo m_wsi;
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory2> m_dxgi_factory;
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swap_chain;
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory> m_dxgi_factory;
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain> m_swap_chain;
|
||||
Microsoft::WRL::ComPtr<IUnknown> m_d3d_device;
|
||||
AbstractTextureFormat m_texture_format = AbstractTextureFormat::RGBA8;
|
||||
|
||||
|
|
Loading…
Reference in New Issue