Skip to content
Permalink
Browse files

Merge pull request #12032 from driver1998/d3dcompiler

POC: D3DCompiler on D3D9
  • Loading branch information...
hrydgard committed May 14, 2019
2 parents bf8255c + eb99044 commit ff7a85cc2fb2805fd54c6240c8726819be251414
@@ -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
@@ -1,3 +1,5 @@
#include "ppsspp_config.h"

#include "Common/CommonWindows.h"
#include <d3d9.h>

@@ -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;
@@ -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();
@@ -419,6 +419,7 @@
<ClInclude Include="json\json_reader.h" />
<ClInclude Include="net\websocket_server.h" />
<ClInclude Include="thin3d\d3d11_loader.h" />
<ClInclude Include="thin3d\d3d9_d3dcompiler_loader.h" />
<ClInclude Include="thin3d\DataFormat.h" />
<ClInclude Include="thin3d\DataFormatGL.h" />
<ClInclude Include="thin3d\GLQueueRunner.h" />
@@ -1129,6 +1130,7 @@
<ClCompile Include="math\dataconv.cpp" />
<ClCompile Include="net\websocket_server.cpp" />
<ClCompile Include="thin3d\d3d11_loader.cpp" />
<ClCompile Include="thin3d\d3d9_d3dcompiler_loader.cpp" />
<ClCompile Include="thin3d\DataFormatGL.cpp" />
<ClCompile Include="thin3d\GLQueueRunner.cpp" />
<ClCompile Include="thin3d\GLRenderManager.cpp" />
@@ -347,6 +347,9 @@
<ClInclude Include="data\base64.h">
<Filter>data</Filter>
</ClInclude>
<ClInclude Include="thin3d\d3d9_d3dcompiler_loader.h">
<Filter>thin3d</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="gfx\gl_debug_log.cpp">
@@ -826,6 +829,9 @@
<ClCompile Include="data\base64.cpp">
<Filter>data</Filter>
</ClCompile>
<ClCompile Include="thin3d\d3d9_d3dcompiler_loader.cpp">
<Filter>thin3d</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="gfx">
@@ -36,10 +36,10 @@ LoadD3D11Error LoadD3D11() {
}

g_D3DCompileModule = LoadLibrary(D3DCOMPILER_DLL);
#if PPSSPP_PLATFORM(32BIT)
#if PPSSPP_ARCH(X86)
// Workaround for distributing both 32-bit and 64-bit versions of the DLL.
if (!g_D3DCompileModule)
g_D3DCompileModule = LoadLibrary("D3dcompiler_47.x86.dll");
g_D3DCompileModule = LoadLibrary(L"D3dcompiler_47.x86.dll");
#endif
if (!g_D3DCompileModule)
g_D3DCompileModule = LoadLibrary(L"D3dcompiler_42.dll");
@@ -74,4 +74,4 @@ bool UnloadD3D11() {
}

return true;
}
}
@@ -0,0 +1,62 @@
#include <assert.h>
#include <Windows.h>
#include <D3Dcompiler.h>

#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);
}
@@ -0,0 +1,15 @@
#pragma once
#include "ppsspp_config.h"

#include <Windows.h>
#include <D3Dcompiler.h>

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();
@@ -2,6 +2,8 @@
#include <cstdio>
#include <cstdint>

#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 <d3dx9.h>
#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 <D3Dcompiler.h>
#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);
}

@@ -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

0 comments on commit ff7a85c

Please sign in to comment.
You can’t perform that action at this time.