mirror of https://github.com/PCSX2/pcsx2.git
gsdx-d3d11: Modernize swapchain and device creation
Updates the d3d device and swapchain creation to more modern methods. - Use CreateDXGIFactory2 to create the factory and store in member - Use CreateSwapChainForHwnd - Add messages for failures to the console - Some general formatting improvements
This commit is contained in:
parent
91e7c5b7f1
commit
210336d8c1
|
@ -145,31 +145,37 @@ bool GSDevice11::Create(const std::shared_ptr<GSWnd> &wnd)
|
|||
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC scd;
|
||||
D3D11_BUFFER_DESC bd;
|
||||
D3D11_SAMPLER_DESC sd;
|
||||
D3D11_DEPTH_STENCIL_DESC dsd;
|
||||
D3D11_RASTERIZER_DESC rd;
|
||||
D3D11_BLEND_DESC bsd;
|
||||
|
||||
// create factory
|
||||
{
|
||||
const HRESULT result = CreateDXGIFactory2(0, IID_PPV_ARGS(&m_factory));
|
||||
if (FAILED(result))
|
||||
{
|
||||
fprintf(stderr, "D3D11: Unable to create DXGIFactory2 (reason: %x)\n", result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// enumerate adapters
|
||||
CComPtr<IDXGIAdapter1> adapter;
|
||||
D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_HARDWARE;
|
||||
|
||||
{
|
||||
std::string adapter_id = theApp.GetConfigS("Adapter");
|
||||
|
||||
if (adapter_id == "ref")
|
||||
{
|
||||
driver_type = D3D_DRIVER_TYPE_REFERENCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
CComPtr<IDXGIFactory1> dxgi_factory;
|
||||
CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgi_factory);
|
||||
if (dxgi_factory)
|
||||
for (int i = 0;; i++)
|
||||
{
|
||||
CComPtr<IDXGIAdapter1> enum_adapter;
|
||||
if (S_OK != dxgi_factory->EnumAdapters1(i, &enum_adapter))
|
||||
if (S_OK != m_factory->EnumAdapters1(i, &enum_adapter))
|
||||
break;
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
hr = enum_adapter->GetDesc1(&desc);
|
||||
|
@ -184,54 +190,68 @@ bool GSDevice11::Create(const std::shared_ptr<GSWnd> &wnd)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(&scd, 0, sizeof(scd));
|
||||
|
||||
scd.BufferCount = 2;
|
||||
scd.BufferDesc.Width = 1;
|
||||
scd.BufferDesc.Height = 1;
|
||||
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
//scd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
//scd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
scd.OutputWindow = (HWND)m_wnd->GetHandle();
|
||||
scd.SampleDesc.Count = 1;
|
||||
scd.SampleDesc.Quality = 0;
|
||||
|
||||
// Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less
|
||||
// required if we want to add support for dual displays later on. The fullscreen/exclusive flip
|
||||
// will be issued after all other initializations are complete.
|
||||
|
||||
scd.Windowed = TRUE;
|
||||
|
||||
// NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED
|
||||
// This flag is safe as long as the DXGI's internal message pump is disabled or is on the
|
||||
// same thread as the GS window (which the emulator makes sure of, if it utilizes a
|
||||
// multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes.
|
||||
D3D_FEATURE_LEVEL level;
|
||||
|
||||
// device creation
|
||||
{
|
||||
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||
|
||||
#ifdef DEBUG
|
||||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
|
||||
D3D_FEATURE_LEVEL level;
|
||||
|
||||
const D3D_FEATURE_LEVEL levels[] =
|
||||
{
|
||||
constexpr std::array<D3D_FEATURE_LEVEL, 3> supported_levels = {
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
};
|
||||
|
||||
hr = D3D11CreateDeviceAndSwapChain(adapter, driver_type, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx);
|
||||
const HRESULT result = D3D11CreateDevice(
|
||||
adapter, driver_type, nullptr, flags,
|
||||
supported_levels.data(), supported_levels.size(),
|
||||
D3D11_SDK_VERSION, &m_dev, &level, &m_ctx
|
||||
);
|
||||
|
||||
if(FAILED(hr)) return false;
|
||||
|
||||
if(!SetFeatureLevel(level, true))
|
||||
if (FAILED(result))
|
||||
{
|
||||
fprintf(stderr, "D3D11: Unable to create D3D11 device (reason %x)\n", result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// swapchain creation
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC1 swapchain_description = {};
|
||||
|
||||
// let the runtime get window size
|
||||
swapchain_description.Width = 0;
|
||||
swapchain_description.Height = 0;
|
||||
|
||||
swapchain_description.BufferCount = 2;
|
||||
swapchain_description.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swapchain_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapchain_description.SampleDesc.Count = 1;
|
||||
swapchain_description.SampleDesc.Quality = 0;
|
||||
|
||||
// TODO: update swap effect
|
||||
swapchain_description.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
const HRESULT result = m_factory->CreateSwapChainForHwnd(
|
||||
m_dev, reinterpret_cast<HWND>(m_wnd->GetHandle()),
|
||||
&swapchain_description, nullptr, nullptr, &m_swapchain
|
||||
);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
fprintf(stderr, "D3D11: Failed to create swapchain (reason: %x)\n", result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!SetFeatureLevel(level, true))
|
||||
return false;
|
||||
|
||||
// Set maximum texture size limit based on supported feature level.
|
||||
if (level >= D3D_FEATURE_LEVEL_11_0)
|
||||
|
|
|
@ -384,9 +384,10 @@ private:
|
|||
|
||||
uint16 ConvertBlendEnum(uint16 generic) final;
|
||||
|
||||
CComPtr<IDXGIFactory2> m_factory;
|
||||
CComPtr<ID3D11Device> m_dev;
|
||||
CComPtr<ID3D11DeviceContext> m_ctx;
|
||||
CComPtr<IDXGISwapChain> m_swapchain;
|
||||
CComPtr<IDXGISwapChain1> m_swapchain;
|
||||
CComPtr<ID3D11Buffer> m_vb;
|
||||
CComPtr<ID3D11Buffer> m_vb_old;
|
||||
CComPtr<ID3D11Buffer> m_ib;
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
#include <commdlg.h>
|
||||
#include <shellapi.h>
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3d11_1.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <comutil.h>
|
||||
#include <atlcomcli.h>
|
||||
|
||||
|
|
Loading…
Reference in New Issue