diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 0815100336..451421b179 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -47,7 +47,11 @@ #ifdef _WIN32 #include "Common/CommonWindows.h" // Want to avoid including the full header here as it includes d3dx.h +#if PPSSPP_API(D3DX9) int GetD3DXVersion(); +#elif PPSSPP_API(D3D9_D3DCOMPILER) +int GetD3DCompilerVersion(); +#endif #endif static const char *logLevelList[] = { @@ -464,7 +468,11 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new InfoItem(si->T("Driver Version"), System_GetProperty(SYSPROP_GPUDRIVER_VERSION))); #if !PPSSPP_PLATFORM(UWP) if (GetGPUBackend() == GPUBackend::DIRECT3D9) { +#if PPSSPP_API(D3DX9) deviceSpecs->Add(new InfoItem(si->T("D3DX Version"), StringFromFormat("%d", GetD3DXVersion()))); +#elif PPSSPP_API(D3D9_D3DCOMPILER) + deviceSpecs->Add(new InfoItem(si->T("D3DCompiler Version"), StringFromFormat("%d", GetD3DCompilerVersion()))); +#endif } #endif #endif diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index 80933615b2..c21a6d7c5d 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -1,3 +1,5 @@ +#include "ppsspp_config.h" + #include "Common/CommonWindows.h" #include @@ -16,7 +18,12 @@ #include "Windows/W32Util/Misc.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" + +#if PPSSPP_API(D3DX9) #include "thin3d/d3dx9_loader.h" +#elif PPSSPP_API(D3D9_D3DCOMPILER) +#include "thin3d/d3d9_d3dcompiler_loader.h" +#endif void D3D9Context::SwapBuffers() { if (has9Ex_) { @@ -64,11 +71,19 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { return false; } +#if PPSSPP_API(D3DX9) int d3dx_version = LoadD3DX9Dynamic(); if (!d3dx_version) { *error_message = "D3DX DLL not found! Try reinstalling DirectX."; return false; } +#elif PPSSPP_API(D3D9_D3DCOMPILER) + bool result = LoadD3DCompilerDynamic(); + if (!result) { + *error_message = "D3DCompiler not found! Try reinstalling DirectX."; + return false; + } +#endif g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9_, "Direct3DCreate9Ex"); has9Ex_ = (g_pfnCreate9ex != NULL) && IsVistaOrHigher(); @@ -208,7 +223,11 @@ void D3D9Context::Shutdown() { device_->EndScene(); device_->Release(); d3d_->Release(); +#if PPSSPP_API(D3DX9) UnloadD3DXDynamic(); +#elif PPSSPP_API(D3D9_D3DCOMPILER) + UnloadD3DCompiler(); +#endif DX9::pD3Ddevice = nullptr; DX9::pD3DdeviceEx = nullptr; device_ = nullptr; diff --git a/ext/native/gfx/d3d9_shader.cpp b/ext/native/gfx/d3d9_shader.cpp index 51b918c21d..2fdec6c41f 100644 --- a/ext/native/gfx/d3d9_shader.cpp +++ b/ext/native/gfx/d3d9_shader.cpp @@ -1,16 +1,30 @@ #ifdef _WIN32 +#include "ppsspp_config.h" #include "d3d9_shader.h" -#include "thin3d/d3dx9_loader.h" #include "Common/CommonFuncs.h" +#if PPSSPP_API(D3DX9) +#include "thin3d/d3dx9_loader.h" + +// They are the same types, just different names. +#define LPD3D_SHADER_MACRO LPD3DXMACRO +#define LPD3DINCLUDE LPD3DXINCLUDE +#define LPD3DBLOB LPD3DXBUFFER +#elif PPSSPP_API(D3D9_D3DCOMPILER) +#include "thin3d/d3d9_d3dcompiler_loader.h" +#endif + +struct ID3DXConstantTable; + namespace DX9 { -bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, LPD3DXCONSTANTTABLE *pShaderTable, std::string &errorMessage) { - ID3DXBuffer *pShaderCode = nullptr; - ID3DXBuffer *pErrorMsg = nullptr; +bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage) { + LPD3DBLOB pShaderCode = nullptr; + LPD3DBLOB pErrorMsg = nullptr; // Compile pixel shader. +#if PPSSPP_API(D3DX9) HRESULT hr = dyn_D3DXCompileShader(code, (UINT)strlen(code), nullptr, @@ -21,6 +35,19 @@ bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPI &pShaderCode, &pErrorMsg, pShaderTable); +#elif PPSSPP_API(D3D9_D3DCOMPILER) + HRESULT hr = dyn_D3DCompile(code, + (UINT)strlen(code), + nullptr, + nullptr, + nullptr, + "main", + "ps_2_0", + 0, + 0, + &pShaderCode, + &pErrorMsg); +#endif if (pErrorMsg) { errorMessage = (CHAR *)pErrorMsg->GetBufferPointer(); @@ -46,11 +73,12 @@ bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPI return true; } -bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, LPD3DXCONSTANTTABLE *pShaderTable, std::string &errorMessage) { - ID3DXBuffer *pShaderCode = nullptr; - ID3DXBuffer *pErrorMsg = nullptr; +bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage) { + LPD3DBLOB pShaderCode = nullptr; + LPD3DBLOB pErrorMsg = nullptr; // Compile pixel shader. +#if PPSSPP_API(D3DX9) HRESULT hr = dyn_D3DXCompileShader(code, (UINT)strlen(code), nullptr, @@ -61,6 +89,19 @@ bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DV &pShaderCode, &pErrorMsg, pShaderTable); +#elif PPSSPP_API(D3D9_D3DCOMPILER) + HRESULT hr = dyn_D3DCompile(code, + (UINT)strlen(code), + nullptr, + nullptr, + nullptr, + "main", + "vs_2_0", + 0, + 0, + &pShaderCode, + &pErrorMsg); +#endif if (pErrorMsg) { errorMessage = (CHAR *)pErrorMsg->GetBufferPointer(); diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index dcbf26d267..85526c64b4 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -419,6 +419,7 @@ + @@ -1129,6 +1130,7 @@ + diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 08305fee7c..83c81d1a4a 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -347,6 +347,9 @@ data + + thin3d + @@ -826,6 +829,9 @@ data + + thin3d + diff --git a/ext/native/thin3d/d3d9_d3dcompiler_loader.cpp b/ext/native/thin3d/d3d9_d3dcompiler_loader.cpp new file mode 100644 index 0000000000..8cc76529fc --- /dev/null +++ b/ext/native/thin3d/d3d9_d3dcompiler_loader.cpp @@ -0,0 +1,62 @@ +#include +#include +#include + +#include "thin3d/d3d9_d3dcompiler_loader.h" + +static HMODULE g_D3DCompileModule; +extern pD3DCompile ptr_D3DCompile; + +int d3dcompiler_version = 47; + +#define GB_MAKE_STR(s) # s +#define GB_MAKE_STR2(x) GB_MAKE_STR(x) +#define GB_D3D9_D3DCOMPILER_LOADER_CHECK_ENTRY_NULL_PTR(funcname) assert(false && GB_MAKE_STR2(funcname) ); + +bool LoadD3DCompilerDynamic() { + g_D3DCompileModule = LoadLibrary(D3DCOMPILER_DLL); +#if PPSSPP_ARCH(X86) + // Workaround for distributing both 32-bit and 64-bit versions of the DLL. + if (!g_D3DCompileModule) + g_D3DCompileModule = LoadLibrary(L"D3dcompiler_47.x86.dll"); +#endif + if (!g_D3DCompileModule) { + g_D3DCompileModule = LoadLibrary(L"D3dcompiler_42.dll"); + d3dcompiler_version = 42; + } + + if (!g_D3DCompileModule) { + return false; + } else { + ptr_D3DCompile = (pD3DCompile)GetProcAddress(g_D3DCompileModule, "D3DCompile"); + return true; + } + +} + +int GetD3DCompilerVersion() { + return d3dcompiler_version; +} + +bool UnloadD3DCompiler() { + if (!g_D3DCompileModule) + return false; + + if (g_D3DCompileModule) { + FreeLibrary(g_D3DCompileModule); + g_D3DCompileModule = nullptr; + } + + return true; +} + + +HRESULT dyn_D3DCompile(LPCSTR pSrcData, UINT SrcDataSize, LPCSTR pFileName, CONST D3D_SHADER_MACRO* pDefines, + LPD3DINCLUDE pInclude, LPCSTR pEntrypoint, LPCSTR pTarget, + UINT Flags1, UINT Flags2, LPD3DBLOB* ppShader, LPD3DBLOB* ppErrorMsgs) +{ + if (!g_D3DCompileModule) { + GB_D3D9_D3DCOMPILER_LOADER_CHECK_ENTRY_NULL_PTR(D3DCompile) + } + return ptr_D3DCompile(pSrcData, SrcDataSize, pFileName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppShader, ppErrorMsgs); +} diff --git a/ext/native/thin3d/d3d9_d3dcompiler_loader.h b/ext/native/thin3d/d3d9_d3dcompiler_loader.h new file mode 100644 index 0000000000..3f8f51112f --- /dev/null +++ b/ext/native/thin3d/d3d9_d3dcompiler_loader.h @@ -0,0 +1,15 @@ +#pragma once +#include "ppsspp_config.h" + +#include +#include + +bool LoadD3DCompilerDynamic(); + +HRESULT dyn_D3DCompile(LPCSTR pSrcData, UINT SrcDataSize, LPCSTR pFileName, CONST D3D_SHADER_MACRO* pDefines, + LPD3DINCLUDE pInclude, LPCSTR pEntrypoint, LPCSTR pTarget, + UINT Flags1, UINT Flags2, LPD3DBLOB* ppShader, LPD3DBLOB* ppErrorMsgs); + +bool UnloadD3DCompiler(); + +int GetD3DCompilerVersion(); diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index d5d4c45bcd..cdd784b5f1 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -2,6 +2,8 @@ #include #include +#include "ppsspp_config.h" + #ifdef _DEBUG #define D3D_DEBUG_INFO #endif @@ -10,15 +12,26 @@ #ifdef USE_CRT_DBG #undef new #endif + +#if PPSSPP_API(D3DX9) #include #ifdef USE_CRT_DBG #define new DBG_NEW #endif +#include "thin3d/d3dx9_loader.h" + +// They are the same types, just different names. +#define LPD3D_SHADER_MACRO LPD3DXMACRO +#define LPD3DINCLUDE LPD3DXINCLUDE +#define LPD3DBLOB LPD3DXBUFFER +#elif PPSSPP_API(D3D9_D3DCOMPILER) +#include +#include "thin3d/d3d9_d3dcompiler_loader.h" +#endif #include "base/logging.h" #include "math/lin/matrix4x4.h" #include "thin3d/thin3d.h" -#include "thin3d/d3dx9_loader.h" #include "gfx/d3d9_state.h" namespace Draw { @@ -969,14 +982,18 @@ void D3D9Context::SetStencilRef(uint8_t ref) { } bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size) { - LPD3DXMACRO defines = nullptr; - LPD3DXINCLUDE includes = nullptr; + LPD3D_SHADER_MACRO defines = nullptr; + LPD3DINCLUDE includes = nullptr; DWORD flags = 0; - LPD3DXBUFFER codeBuffer = nullptr; - LPD3DXBUFFER errorBuffer = nullptr; + LPD3DBLOB codeBuffer = nullptr; + LPD3DBLOB errorBuffer = nullptr; const char *source = (const char *)data; const char *profile = stage_ == ShaderStage::FRAGMENT ? "ps_2_0" : "vs_2_0"; +#if PPSSPP_API(D3DX9) HRESULT hr = dyn_D3DXCompileShader(source, (UINT)strlen(source), defines, includes, "main", profile, flags, &codeBuffer, &errorBuffer, nullptr); +#elif PPSSPP_API(D3D9_D3DCOMPILER) + HRESULT hr = dyn_D3DCompile(source, (UINT)strlen(source), nullptr, defines, includes, "main", profile, 0, 0, &codeBuffer, &errorBuffer); +#endif if (FAILED(hr)) { const char *error = errorBuffer ? (const char *)errorBuffer->GetBufferPointer() : "(no errorbuffer returned)"; if (hr == ERROR_MOD_NOT_FOUND) { @@ -1186,11 +1203,19 @@ void D3D9Context::HandleEvent(Event ev, int width, int height, void *param1, voi } DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) { +#if PPSSPP_API(D3DX9) int d3dx_ver = LoadD3DX9Dynamic(); if (!d3dx_ver) { ELOG("Failed to load D3DX9!"); return NULL; } +#elif PPSSPP_API(D3D9_D3DCOMPILER) + bool result = LoadD3DCompilerDynamic(); + if (!result) { + ELOG("Failed to load D3DCompiler!"); + return NULL; + } +#endif return new D3D9Context(d3d, d3dEx, adapterId, device, deviceEx); } diff --git a/ppsspp_config.h b/ppsspp_config.h index 43e90da724..d2072fbb56 100644 --- a/ppsspp_config.h +++ b/ppsspp_config.h @@ -125,6 +125,10 @@ #if PPSSPP_PLATFORM(WINDOWS) #if !PPSSPP_PLATFORM(UWP) #define PPSSPP_API_D3D9 1 + +// Comment this and uncomment PPSSPP_API_D3DX9 if D3DX9 is prefered. +#define PPSSPP_API_D3D9_D3DCOMPILER 1 +// #define PPSSPP_API_D3DX9 1 #endif #define PPSSPP_API_D3D11 1 #endif