diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index fd867e51f..bfa7c8010 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -132,6 +132,10 @@ EXPORT_C_(int) GSinit() return -1; } + if (!GSDeviceDX::LoadD3DCompiler()) + { + return -1; + } #endif return 0; @@ -156,6 +160,8 @@ EXPORT_C GSshutdown() s_hr = E_FAIL; } + GSDeviceDX::FreeD3DCompiler(); + #endif } diff --git a/plugins/GSdx/GSDeviceDX.cpp b/plugins/GSdx/GSDeviceDX.cpp index 2b23b5b5b..346de8c1a 100644 --- a/plugins/GSdx/GSDeviceDX.cpp +++ b/plugins/GSdx/GSDeviceDX.cpp @@ -22,6 +22,11 @@ #include "stdafx.h" #include "GSdx.h" #include "GSDeviceDX.h" +#include + +HMODULE GSDeviceDX::s_d3d_compiler_dll = nullptr; +decltype(&D3DCompile) GSDeviceDX::s_pD3DCompile = nullptr; +bool GSDeviceDX::s_old_d3d_compiler_dll; GSDeviceDX::GSDeviceDX() { @@ -35,6 +40,48 @@ GSDeviceDX::~GSDeviceDX() { } +bool GSDeviceDX::LoadD3DCompiler() +{ + // Windows 8.1 and later come with the latest d3dcompiler_47.dll, but + // Windows 7 devs might also have the dll available for use (which will + // have to be placed in the application directory) + s_d3d_compiler_dll = LoadLibraryEx(D3DCOMPILER_DLL, nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); + + // Windows Vista and 7 can use the older version. If the previous LoadLibrary + // call fails on Windows 8.1 and later, then the user's system is likely + // broken. + if (s_d3d_compiler_dll) + { + s_old_d3d_compiler_dll = false; + } + else + { + if (!IsWindows8Point1OrGreater()) + s_d3d_compiler_dll = LoadLibraryEx("D3DCompiler_43.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + + if (s_d3d_compiler_dll == nullptr) + return false; + + s_old_d3d_compiler_dll = true; + } + + s_pD3DCompile = reinterpret_cast(GetProcAddress(s_d3d_compiler_dll, "D3DCompile")); + if (s_pD3DCompile) + return true; + + FreeLibrary(s_d3d_compiler_dll); + s_d3d_compiler_dll = nullptr; + return false; +} + +void GSDeviceDX::FreeD3DCompiler() +{ + s_pD3DCompile = nullptr; + if (s_d3d_compiler_dll) + FreeLibrary(s_d3d_compiler_dll); + s_d3d_compiler_dll = nullptr; +} + GSTexture* GSDeviceDX::FetchSurface(int type, int w, int h, bool msaa, int format) { if(m_msaa < 2) diff --git a/plugins/GSdx/GSDeviceDX.h b/plugins/GSdx/GSDeviceDX.h index 680b22744..cdf03312a 100644 --- a/plugins/GSdx/GSDeviceDX.h +++ b/plugins/GSdx/GSDeviceDX.h @@ -278,6 +278,12 @@ protected: uint32 m_msaa; DXGI_SAMPLE_DESC m_msaa_desc; + static HMODULE s_d3d_compiler_dll; + static decltype(&D3DCompile) s_pD3DCompile; + // Older version doesn't support D3D_COMPILE_STANDARD_FILE_INCLUDE, which + // could be useful for external shaders. + static bool s_old_d3d_compiler_dll; + GSTexture* FetchSurface(int type, int w, int h, bool msaa, int format); public: @@ -297,6 +303,9 @@ public: virtual bool HasStencil() = 0; virtual bool HasDepth32() = 0; + static bool LoadD3DCompiler(); + static void FreeD3DCompiler(); + template void PrepareShaderMacro(vector& dst, const T* src) { dst.clear(); diff --git a/plugins/GSdx/stdafx.h b/plugins/GSdx/stdafx.h index 7aac17529..6f2e63e3d 100644 --- a/plugins/GSdx/stdafx.h +++ b/plugins/GSdx/stdafx.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include