Merge pull request #8096 from stenzek/d3d-old-drivers

D3DCommon: Fallback to base CreateSwapChain on failure
This commit is contained in:
Connor McLaughlin 2019-06-08 20:41:04 +10:00 committed by GitHub
commit 6567409177
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 80 additions and 59 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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