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
This commit is contained in:
gabest11 2011-02-20 16:09:46 +00:00
parent b8f1d1e60e
commit 31a22bb57b
7 changed files with 153 additions and 161 deletions

View File

@ -35,10 +35,11 @@
#include "GSSettingsDlg.h" #include "GSSettingsDlg.h"
static HRESULT s_hr = E_FAIL; static HRESULT s_hr = E_FAIL;
static bool s_isdx11avail = false; // set on GSinit
#else #else
extern bool RunLinuxDialog(); extern bool RunLinuxDialog();
#endif #endif
#define PS2E_LT_GS 0x01 #define PS2E_LT_GS 0x01
@ -122,8 +123,6 @@ EXPORT_C_(int) GSinit()
return -1; return -1;
} }
s_isdx11avail = GSUtil::IsDirect3D11Available();
#endif #endif
return 0; return 0;
@ -280,8 +279,6 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
return -1; return -1;
} }
// if(mt) _mm_setcsr(MXCSR);
return 0; return 0;
} }
@ -292,7 +289,11 @@ EXPORT_C_(int) GSopen2(void** dsp, uint32 flags)
if(flags & 4) if(flags & 4)
{ {
#ifdef _WINDOWS #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 #endif
} }
@ -316,7 +317,11 @@ EXPORT_C_(int) GSopen(void** dsp, char* title, int mt)
// pcsx2 sent a switch renderer request // pcsx2 sent a switch renderer request
#ifdef _WINDOWS #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 #endif
mt = 1; mt = 1;

View File

@ -25,115 +25,6 @@
#include "GSUtil.h" #include "GSUtil.h"
#include "resource.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<ID3D11Device> dev;
CComPtr<ID3D11DeviceContext> 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() GSDevice11::GSDevice11()
{ {
memset(&m_state, 0, sizeof(m_state)); memset(&m_state, 0, sizeof(m_state));
@ -197,6 +88,13 @@ bool GSDevice11::Create(GSWnd* wnd)
D3D_FEATURE_LEVEL level; 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_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); // hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx);

View File

@ -24,24 +24,6 @@
#include "GSDeviceDX.h" #include "GSDeviceDX.h"
#include "GSTexture11.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 struct GSVertexShader11
{ {
CComPtr<ID3D11VertexShader> vs; CComPtr<ID3D11VertexShader> vs;

View File

@ -27,12 +27,12 @@
#include "GSDevice11.h" #include "GSDevice11.h"
#include "resource.h" #include "resource.h"
GSSettingsDlg::GSSettingsDlg( bool isOpen2 ) GSSettingsDlg::GSSettingsDlg(bool isOpen2)
: GSDialog(isOpen2 ? IDD_CONFIG2 : IDD_CONFIG) : GSDialog(isOpen2 ? IDD_CONFIG2 : IDD_CONFIG)
, m_IsOpen2(isOpen2) , m_IsOpen2(isOpen2)
{ {
} }
bool allowHacks = false;
void GSSettingsDlg::OnInit() void GSSettingsDlg::OnInit()
{ {
__super::OnInit(); __super::OnInit();
@ -73,7 +73,9 @@ void GSSettingsDlg::OnInit()
} }
} }
bool isdx11avail_config = GSUtil::IsDirect3D11Available(); D3D_FEATURE_LEVEL level;
GSUtil::CheckDirect3D11Level(level);
vector<GSSetting> renderers; vector<GSSetting> renderers;
@ -83,9 +85,9 @@ void GSSettingsDlg::OnInit()
if(i >= 3 && i <= 5) 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); renderers.push_back(r);
@ -141,6 +143,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code)
//post change //post change
bool dx9 = false; bool dx9 = false;
INT_PTR i; INT_PTR i;
if(ComboBoxGetSelData(IDC_RENDERER, i)) if(ComboBoxGetSelData(IDC_RENDERER, i))
@ -178,7 +181,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code)
if(!supportedAa.length()) if(!supportedAa.length())
{ {
supportedAa="None"; supportedAa = "None";
} }
string s = format("AA=%d is not supported.\nSupported AA values: %s.", (int)requestedMsaa, supportedAa.c_str()); 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(); 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_AlphaHack", (int)IsDlgButtonChecked(m_hWnd, IDC_ALPHAHACK));
theApp.SetConfig("UserHacks_HalfPixelOffset", (int)IsDlgButtonChecked(m_hWnd, IDC_OFFSETHACK)); 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)); 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); return __super::OnCommand(hWnd, id, code);

View File

@ -35,8 +35,8 @@ protected:
void OnInit(); void OnInit();
bool OnCommand(HWND hWnd, UINT id, UINT code); 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: public:
GSSettingsDlg( bool isOpen2 ); GSSettingsDlg(bool isOpen2);
}; };

View File

@ -198,17 +198,11 @@ bool GSUtil::CheckDirectX()
if(GetVersionEx((OSVERSIONINFO*)&version)) if(GetVersionEx((OSVERSIONINFO*)&version))
{ {
printf("Windows %d.%d.%d", printf("Windows %d.%d.%d", version.dwMajorVersion, version.dwMinorVersion, version.dwBuildNumber);
version.dwMajorVersion,
version.dwMinorVersion,
version.dwBuildNumber);
if(version.wServicePackMajor > 0) if(version.wServicePackMajor > 0)
{ {
printf(" (%s %d.%d)", printf(" (%s %d.%d)", version.szCSDVersion, version.wServicePackMajor, version.wServicePackMinor);
version.szCSDVersion,
version.wServicePackMajor,
version.wServicePackMinor);
} }
printf("\n"); printf("\n");
@ -254,4 +248,123 @@ bool GSUtil::CheckDirectX()
return true; 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<IDXGIFactory> 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<ID3D11Device> dev;
CComPtr<ID3D11DeviceContext> 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 #endif

View File

@ -39,15 +39,9 @@ public:
#ifdef _WINDOWS #ifdef _WINDOWS
static bool CheckDirectX(); static bool CheckDirectX();
static bool CheckDirect3D11Level(D3D_FEATURE_LEVEL& level);
static void UnloadDynamicLibraries(); 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 #endif
}; };