From 210336d8c17925e11ac15e849b0d3336a17a876e Mon Sep 17 00:00:00 2001 From: Kojin Date: Mon, 29 Jun 2020 03:33:48 -0400 Subject: [PATCH] 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 --- plugins/GSdx/Renderers/DX11/GSDevice11.cpp | 122 ++++++++++++--------- plugins/GSdx/Renderers/DX11/GSDevice11.h | 3 +- plugins/GSdx/stdafx.h | 3 +- 3 files changed, 75 insertions(+), 53 deletions(-) diff --git a/plugins/GSdx/Renderers/DX11/GSDevice11.cpp b/plugins/GSdx/Renderers/DX11/GSDevice11.cpp index 91a76704c9..5c4fabd66d 100644 --- a/plugins/GSdx/Renderers/DX11/GSDevice11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSDevice11.cpp @@ -145,31 +145,37 @@ bool GSDevice11::Create(const std::shared_ptr &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 adapter; D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_HARDWARE; - std::string adapter_id = theApp.GetConfigS("Adapter"); + { + std::string adapter_id = theApp.GetConfigS("Adapter"); - if (adapter_id == "ref") - { - driver_type = D3D_DRIVER_TYPE_REFERENCE; - } - else - { - CComPtr dxgi_factory; - CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgi_factory); - if (dxgi_factory) + if (adapter_id == "ref") + driver_type = D3D_DRIVER_TYPE_REFERENCE; + else + { for (int i = 0;; i++) { CComPtr 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); @@ -183,55 +189,69 @@ bool GSDevice11::Create(const std::shared_ptr &wnd) break; } } + } } - 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. - - uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED; - -#ifdef DEBUG - flags |= D3D11_CREATE_DEVICE_DEBUG; -#endif - D3D_FEATURE_LEVEL level; - const D3D_FEATURE_LEVEL levels[] = + // device creation { - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - }; + uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED; - hr = D3D11CreateDeviceAndSwapChain(adapter, driver_type, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); +#ifdef DEBUG + flags |= D3D11_CREATE_DEVICE_DEBUG; +#endif - if(FAILED(hr)) return false; + constexpr std::array supported_levels = { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + }; + + 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(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(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) diff --git a/plugins/GSdx/Renderers/DX11/GSDevice11.h b/plugins/GSdx/Renderers/DX11/GSDevice11.h index 94e7ec4d8f..4c33ce1ef2 100644 --- a/plugins/GSdx/Renderers/DX11/GSDevice11.h +++ b/plugins/GSdx/Renderers/DX11/GSDevice11.h @@ -384,9 +384,10 @@ private: uint16 ConvertBlendEnum(uint16 generic) final; + CComPtr m_factory; CComPtr m_dev; CComPtr m_ctx; - CComPtr m_swapchain; + CComPtr m_swapchain; CComPtr m_vb; CComPtr m_vb_old; CComPtr m_ib; diff --git a/plugins/GSdx/stdafx.h b/plugins/GSdx/stdafx.h index d7d0c480d9..80a17a3cd4 100644 --- a/plugins/GSdx/stdafx.h +++ b/plugins/GSdx/stdafx.h @@ -38,7 +38,8 @@ #include #include #include -#include +#include +#include #include #include