From 31a22bb57b270710c115fd5a1245be40f3d88048 Mon Sep 17 00:00:00 2001 From: gabest11 Date: Sun, 20 Feb 2011 16:09:46 +0000 Subject: [PATCH] GSdx: made dx11 detection code a bit nicer, but not sure what happens on vista without the dx11 runtime, it probably won't detect dx10 either. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4325 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GS.cpp | 19 +++-- plugins/GSdx/GSDevice11.cpp | 116 ++--------------------------- plugins/GSdx/GSDevice11.h | 18 ----- plugins/GSdx/GSSettingsDlg.cpp | 20 ++--- plugins/GSdx/GSSettingsDlg.h | 4 +- plugins/GSdx/GSUtil.cpp | 129 +++++++++++++++++++++++++++++++-- plugins/GSdx/GSUtil.h | 8 +- 7 files changed, 153 insertions(+), 161 deletions(-) diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 9fd8c1ad06..41f9c69847 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -35,10 +35,11 @@ #include "GSSettingsDlg.h" static HRESULT s_hr = E_FAIL; -static bool s_isdx11avail = false; // set on GSinit #else + extern bool RunLinuxDialog(); + #endif #define PS2E_LT_GS 0x01 @@ -122,8 +123,6 @@ EXPORT_C_(int) GSinit() return -1; } - s_isdx11avail = GSUtil::IsDirect3D11Available(); - #endif return 0; @@ -280,8 +279,6 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1) return -1; } - // if(mt) _mm_setcsr(MXCSR); - return 0; } @@ -292,7 +289,11 @@ EXPORT_C_(int) GSopen2(void** dsp, uint32 flags) if(flags & 4) { #ifdef _WINDOWS - renderer = s_isdx11avail ? 4 : 1; // dx11 / dx9 sw + + D3D_FEATURE_LEVEL level; + + renderer = GSUtil::CheckDirect3D11Level(level) && level >= D3D_FEATURE_LEVEL_10_0 ? 4 : 1; // dx11 / dx9 sw + #endif } @@ -316,7 +317,11 @@ EXPORT_C_(int) GSopen(void** dsp, char* title, int mt) // pcsx2 sent a switch renderer request #ifdef _WINDOWS - renderer = s_isdx11avail ? 4 : 1; // dx11 / dx9 sw + + D3D_FEATURE_LEVEL level; + + renderer = GSUtil::CheckDirect3D11Level(level) && level >= D3D_FEATURE_LEVEL_10_0 ? 4 : 1; // dx11 / dx9 sw + #endif mt = 1; diff --git a/plugins/GSdx/GSDevice11.cpp b/plugins/GSdx/GSDevice11.cpp index 5bed415cbf..bd4ba55fe2 100644 --- a/plugins/GSdx/GSDevice11.cpp +++ b/plugins/GSdx/GSDevice11.cpp @@ -25,115 +25,6 @@ #include "GSUtil.h" #include "resource.h" -static const D3D_FEATURE_LEVEL levels[] = -{ - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, -}; - -// --------------------------------------------------------------------------------- -// DX11 Detection (includes DXGI detection and dynamic library method bindings) -// --------------------------------------------------------------------------------- -// Code 'Borrowed' from Microsoft's DXGI sources -- Modified to suit our needs. --air - -static IDXGIFactory* m_DXGIFactory = NULL; -static bool m_D3D11Available = false; -static bool m_HasD3D11Features = false; - -static HMODULE s_hModD3D11 = NULL; -static PFN_D3D11_CREATE_DEVICE s_DynamicD3D11CreateDevice = NULL; - -static HMODULE s_hModDXGI = NULL; -static FnPtr_CreateDXGIFactory s_DynamicCreateDXGIFactory = NULL; - - -static bool DXUT_EnsureD3D11APIs() -{ - // If any function pointer is non-NULL, this function has already been called. - if( s_DynamicD3D11CreateDevice ) - return true; - - s_hModDXGI = LoadLibrary( _T("dxgi.dll") ); - if( s_hModDXGI ) - { - s_DynamicCreateDXGIFactory = (FnPtr_CreateDXGIFactory)GetProcAddress( s_hModDXGI, "CreateDXGIFactory" ); - } - - // If DXGI isn't installed then this system isn't even capable of DX11 support; so no point - // in checking for DX11 DLLs. - if( s_DynamicCreateDXGIFactory == NULL ) return false; - - // Check for DX11 DLLs. - - s_hModD3D11 = LoadLibrary( _T("d3d11.dll") ); - if( s_hModD3D11 == NULL ) LoadLibrary( _T("d3d11_beta.dll") ); - - if( s_hModD3D11 != NULL ) - { - s_DynamicD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress( s_hModD3D11, "D3D11CreateDevice" ); - } - - return ( s_DynamicD3D11CreateDevice != NULL ); -} - -static bool DXUTDelayLoadDXGI() -{ - if( !DXUT_EnsureD3D11APIs() ) return false; - - if( m_DXGIFactory == NULL ) - { - if( s_DynamicCreateDXGIFactory( __uuidof( IDXGIFactory ), (LPVOID*)&m_DXGIFactory ) != S_OK ) return false; - } - - return ( m_DXGIFactory != NULL ); -} - -bool GSUtil::IsDirect3D11Available() -{ - static bool m_CheckRun = false; - - if (m_CheckRun) return m_D3D11Available; - m_CheckRun = true; - - if( !DXUTDelayLoadDXGI() ) - { - m_D3D11Available = false; - } - else - { - CComPtr dev; - CComPtr ctx; - D3D_FEATURE_LEVEL level; - - HRESULT hr = s_DynamicD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, levels, countof(levels), - D3D11_SDK_VERSION, &dev, &level, &ctx); - - m_D3D11Available = !FAILED(hr); - m_HasD3D11Features = (level >= D3D_FEATURE_LEVEL_11_0); - } - - if( !m_D3D11Available ) UnloadDynamicLibraries(); - return m_D3D11Available; -} - -bool GSUtil::HasD3D11Features() -{ - return IsDirect3D11Available() && m_HasD3D11Features; -} - -void GSUtil::UnloadDynamicLibraries() -{ - if( s_hModD3D11 ) FreeLibrary(s_hModD3D11); - if( s_hModDXGI ) FreeLibrary(s_hModDXGI); - - s_DynamicD3D11CreateDevice = NULL; - s_DynamicCreateDXGIFactory = NULL; - s_hModD3D11 = NULL; - s_hModDXGI = NULL; -} - - GSDevice11::GSDevice11() { memset(&m_state, 0, sizeof(m_state)); @@ -197,6 +88,13 @@ bool GSDevice11::Create(GSWnd* wnd) D3D_FEATURE_LEVEL level; + const D3D_FEATURE_LEVEL levels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + }; + hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); // hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); diff --git a/plugins/GSdx/GSDevice11.h b/plugins/GSdx/GSDevice11.h index 9bc3325b73..949087543c 100644 --- a/plugins/GSdx/GSDevice11.h +++ b/plugins/GSdx/GSDevice11.h @@ -24,24 +24,6 @@ #include "GSDeviceDX.h" #include "GSTexture11.h" -typedef HRESULT (WINAPI * FnPtr_CreateDXGIFactory)(REFIID, void ** ); - -typedef HRESULT (WINAPI * FnPtr_D3D11CreateDeviceAndSwapChain) ( - __in IDXGIAdapter *pAdapter, - __in D3D_DRIVER_TYPE DriverType, - __in HMODULE Software, - __in UINT Flags, - __in const D3D_FEATURE_LEVEL *pFeatureLevels, - __in UINT FeatureLevels, - __in UINT SDKVersion, - __in const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, - __out IDXGISwapChain **ppSwapChain, - __out ID3D11Device **ppDevice, - __out D3D_FEATURE_LEVEL *pFeatureLevel, - __out ID3D11DeviceContext **ppImmediateContext -); - - struct GSVertexShader11 { CComPtr vs; diff --git a/plugins/GSdx/GSSettingsDlg.cpp b/plugins/GSdx/GSSettingsDlg.cpp index 853a18269a..2ada9bbd30 100644 --- a/plugins/GSdx/GSSettingsDlg.cpp +++ b/plugins/GSdx/GSSettingsDlg.cpp @@ -27,12 +27,12 @@ #include "GSDevice11.h" #include "resource.h" -GSSettingsDlg::GSSettingsDlg( bool isOpen2 ) +GSSettingsDlg::GSSettingsDlg(bool isOpen2) : GSDialog(isOpen2 ? IDD_CONFIG2 : IDD_CONFIG) , m_IsOpen2(isOpen2) { } -bool allowHacks = false; + void GSSettingsDlg::OnInit() { __super::OnInit(); @@ -73,7 +73,9 @@ void GSSettingsDlg::OnInit() } } - bool isdx11avail_config = GSUtil::IsDirect3D11Available(); + D3D_FEATURE_LEVEL level; + + GSUtil::CheckDirect3D11Level(level); vector renderers; @@ -83,9 +85,9 @@ void GSSettingsDlg::OnInit() if(i >= 3 && i <= 5) { - if(!isdx11avail_config) continue; + if(level < D3D_FEATURE_LEVEL_10_0) continue; - r.name = std::string("Direct3D") + (GSUtil::HasD3D11Features() ? "11" : "10"); + r.name = std::string("Direct3D") + (level >= D3D_FEATURE_LEVEL_11_0 ? "11" : "10"); } renderers.push_back(r); @@ -141,6 +143,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) //post change bool dx9 = false; + INT_PTR i; if(ComboBoxGetSelData(IDC_RENDERER, i)) @@ -178,7 +181,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) if(!supportedAa.length()) { - supportedAa="None"; + supportedAa = "None"; } string s = format("AA=%d is not supported.\nSupported AA values: %s.", (int)requestedMsaa, supportedAa.c_str()); @@ -199,7 +202,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) } } - m_lastValidMsaa=requestedMsaa; + m_lastValidMsaa = requestedMsaa; UpdateControls(); } @@ -269,9 +272,6 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) theApp.SetConfig("UserHacks_AlphaHack", (int)IsDlgButtonChecked(m_hWnd, IDC_ALPHAHACK)); theApp.SetConfig("UserHacks_HalfPixelOffset", (int)IsDlgButtonChecked(m_hWnd, IDC_OFFSETHACK)); theApp.SetConfig("UserHacks_SkipDraw", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), UDM_GETPOS, 0, 0)); - - bool allowHacks = !!theApp.GetConfig("allowHacks", 0); - theApp.SetConfig("allowHacks", allowHacks); } return __super::OnCommand(hWnd, id, code); diff --git a/plugins/GSdx/GSSettingsDlg.h b/plugins/GSdx/GSSettingsDlg.h index f48bb94e29..9cb7c60d51 100644 --- a/plugins/GSdx/GSSettingsDlg.h +++ b/plugins/GSdx/GSSettingsDlg.h @@ -35,8 +35,8 @@ protected: void OnInit(); bool OnCommand(HWND hWnd, UINT id, UINT code); - uint32 m_lastValidMsaa; //used to revert to previous dialog value if the user changed to invalid one, or lesser one and canceled + uint32 m_lastValidMsaa; // used to revert to previous dialog value if the user changed to invalid one, or lesser one and canceled public: - GSSettingsDlg( bool isOpen2 ); + GSSettingsDlg(bool isOpen2); }; diff --git a/plugins/GSdx/GSUtil.cpp b/plugins/GSdx/GSUtil.cpp index 9fe3cc9456..9df3ed9663 100644 --- a/plugins/GSdx/GSUtil.cpp +++ b/plugins/GSdx/GSUtil.cpp @@ -198,17 +198,11 @@ bool GSUtil::CheckDirectX() if(GetVersionEx((OSVERSIONINFO*)&version)) { - printf("Windows %d.%d.%d", - version.dwMajorVersion, - version.dwMinorVersion, - version.dwBuildNumber); + printf("Windows %d.%d.%d", version.dwMajorVersion, version.dwMinorVersion, version.dwBuildNumber); if(version.wServicePackMajor > 0) { - printf(" (%s %d.%d)", - version.szCSDVersion, - version.wServicePackMajor, - version.wServicePackMinor); + printf(" (%s %d.%d)", version.szCSDVersion, version.wServicePackMajor, version.wServicePackMinor); } printf("\n"); @@ -254,4 +248,123 @@ bool GSUtil::CheckDirectX() return true; } +// --------------------------------------------------------------------------------- +// DX11 Detection (includes DXGI detection and dynamic library method bindings) +// --------------------------------------------------------------------------------- +// Code 'Borrowed' from Microsoft's DXGI sources -- Modified to suit our needs. --air + +typedef HRESULT (WINAPI * FNPTR_CREATEDXGIFACTORY)(REFIID, void**); + +typedef HRESULT (WINAPI * FNPTR_D3D11CREATEDEVICEANDSWAPCHAIN) ( + __in IDXGIAdapter *pAdapter, + __in D3D_DRIVER_TYPE DriverType, + __in HMODULE Software, + __in UINT Flags, + __in const D3D_FEATURE_LEVEL *pFeatureLevels, + __in UINT FeatureLevels, + __in UINT SDKVersion, + __in const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + __out IDXGISwapChain **ppSwapChain, + __out ID3D11Device **ppDevice, + __out D3D_FEATURE_LEVEL *pFeatureLevel, + __out ID3D11DeviceContext **ppImmediateContext +); + +static HMODULE s_hModD3D11 = NULL; +static PFN_D3D11_CREATE_DEVICE s_DynamicD3D11CreateDevice = NULL; +static HMODULE s_hModDXGI = NULL; +static FNPTR_CREATEDXGIFACTORY s_DynamicCreateDXGIFactory = NULL; +static long s_D3D11Checked = 0; +static D3D_FEATURE_LEVEL s_D3D11Level = (D3D_FEATURE_LEVEL)0; + +static bool DXUTDelayLoadDXGI() +{ + if(s_DynamicD3D11CreateDevice == NULL) + { + s_hModDXGI = LoadLibrary("dxgi.dll"); + + if(s_hModDXGI) + { + s_DynamicCreateDXGIFactory = (FNPTR_CREATEDXGIFACTORY)GetProcAddress(s_hModDXGI, "CreateDXGIFactory"); + } + + // If DXGI isn't installed then this system isn't even capable of DX11 support; so no point + // in checking for DX11 DLLs. + + if(s_DynamicCreateDXGIFactory == NULL) + { + return false; + } + + s_hModD3D11 = LoadLibrary("d3d11.dll"); + + if(s_hModD3D11 == NULL) + { + s_hModD3D11 = LoadLibrary("d3d11_beta.dll"); + } + + if(s_hModD3D11 != NULL) + { + s_DynamicD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(s_hModD3D11, "D3D11CreateDevice"); + } + + if(s_DynamicD3D11CreateDevice == NULL) + { + return false; + } + } + + CComPtr f; + + return s_DynamicCreateDXGIFactory(__uuidof(IDXGIFactory), (LPVOID*)&f) == S_OK && f != NULL; +} + +bool GSUtil::CheckDirect3D11Level(D3D_FEATURE_LEVEL& level) +{ + level = (D3D_FEATURE_LEVEL)0; + + if(!_bittestandset(&s_D3D11Checked, 0)) // thread safety... + { + if(!DXUTDelayLoadDXGI()) + { + UnloadDynamicLibraries(); + + return false; + } + + const D3D_FEATURE_LEVEL levels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1, + }; + + CComPtr dev; + CComPtr ctx; + + HRESULT hr = s_DynamicD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, levels, countof(levels), D3D11_SDK_VERSION, &dev, &level, &ctx); + + s_D3D11Level = level; + } + + level = s_D3D11Level; + + return level >= D3D_FEATURE_LEVEL_11_0; +} + +void GSUtil::UnloadDynamicLibraries() +{ + s_DynamicD3D11CreateDevice = NULL; + s_DynamicCreateDXGIFactory = NULL; + + if(s_hModD3D11) FreeLibrary(s_hModD3D11); + if(s_hModDXGI) FreeLibrary(s_hModDXGI); + + s_hModD3D11 = NULL; + s_hModDXGI = NULL; +} + #endif diff --git a/plugins/GSdx/GSUtil.h b/plugins/GSdx/GSUtil.h index d009df6374..153493c9be 100644 --- a/plugins/GSdx/GSUtil.h +++ b/plugins/GSdx/GSUtil.h @@ -39,15 +39,9 @@ public: #ifdef _WINDOWS static bool CheckDirectX(); + static bool CheckDirect3D11Level(D3D_FEATURE_LEVEL& level); static void UnloadDynamicLibraries(); - // These should probably be located more closely to their respective DX9/DX11 driver files, - // and not here in GSUtil (which should be DirectX independent, generally speaking) --air - - static void* GetDX9Proc( const char* methodname ); - static bool IsDirect3D11Available(); - static bool HasD3D11Features(); - #endif };