Skip to content

Commit 2ee449e

Browse files
committed
Add vertex shader dumping/override
This change generalizes the pixel shader dumping and override support to also include vertex shaders.
1 parent dec7fd1 commit 2ee449e

File tree

7 files changed

+87
-45
lines changed

7 files changed

+87
-45
lines changed

DATA/DSfix.ini

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,17 @@ enableTexturePrefetch 0
201201
# Shader Override Options
202202
###############################################################################
203203

204-
# Enable pixel shader dumping
205-
# Disassembled pixel shaders will be dumped to "dsfix\pixelshader_dump\[hash].asm".
206-
enablePixelShaderDumping 0
204+
# Enable shader dumping
205+
# Disassembled pixel shaders will be dumped to
206+
# "dsfix\pixelshader_dump\[hash].asm", vertex shaders to
207+
# "dsfix\vertexshader_dump\[hash].asm".
208+
enableShaderDumping 0
207209

208210
# Enable pixel shader override
209-
# Pixel shaders named "dsfix\pixelshader_override\[hash].asm" will
210-
# replace the corresponding originals.
211-
enablePixelShaderOverride 0
211+
# Shaders from files named "dsfix\pixelshader_override\[hash].asm" or
212+
# "dsfix\vertexshader_override\[hash].asm" will replace the
213+
# corresponding originals.
214+
enableShaderOverride 0
212215

213216
###############################################################################
214217
# Other Options

RenderstateManager.cpp

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515

1616
RSManager RSManager::instance;
1717

18-
#define PIXEL_SHADER_DUMP_DIR "dsfix/pixelshader_dump"
19-
#define PIXEL_SHADER_OVERRIDE_DIR "dsfix/pixelshader_override"
18+
static const char *PIXEL_SHADER_DUMP_DIR = "dsfix/pixelshader_dump";
19+
static const char *PIXEL_SHADER_OVERRIDE_DIR = "dsfix/pixelshader_override";
20+
static const char *VERTEX_SHADER_DUMP_DIR = "dsfix/vertexshader_dump";
21+
static const char *VERTEX_SHADER_OVERRIDE_DIR = "dsfix/vertexshader_override";
2022

2123
void RSManager::initResources() {
2224
SDLOG(0, "RenderstateManager resource initialization started\n");
@@ -40,12 +42,9 @@ void RSManager::initResources() {
4042
if (Settings::get().getEnableTextureOverride() && Settings::get().getEnableTexturePrefetch())
4143
prefetchTextures();
4244

43-
if (Settings::get().getEnablePixelShaderDumping()) {
44-
CreateDirectory(GetDirectoryFile(PIXEL_SHADER_DUMP_DIR), nullptr);
45-
DWORD error = GetLastError();
46-
if (error && error != ERROR_ALREADY_EXISTS) {
47-
SDLOG(0, "Failed to create %s: %s\n", PIXEL_SHADER_DUMP_DIR, formatMessage(error));
48-
}
45+
if (Settings::get().getEnableShaderDumping()) {
46+
createDirectory(PIXEL_SHADER_DUMP_DIR);
47+
createDirectory(VERTEX_SHADER_DUMP_DIR);
4948
}
5049

5150
SDLOG(0, "RenderstateManager resource initialization completed\n");
@@ -869,14 +868,14 @@ HRESULT RSManager::redirectSetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
869868

870869
HRESULT RSManager::redirectCreatePixelShader(CONST DWORD* pFunction, IDirect3DPixelShader9** ppShader)
871870
{
872-
bool shouldDump = Settings::get().getEnablePixelShaderDumping();
873-
bool shouldOverride = Settings::get().getEnablePixelShaderOverride();
871+
bool shouldDump = Settings::get().getEnableShaderDumping();
872+
bool shouldOverride = Settings::get().getEnableShaderOverride();
874873
LPD3DXBUFFER pAssemblerBuffer = nullptr;
875874
LPD3DXBUFFER pFunctionBuffer = nullptr;
876875
UINT32 hash;
877876

878877
if (shouldDump || shouldOverride) {
879-
if (disassemblePixelShader(pFunction, &pAssemblerBuffer)) {
878+
if (disassembleShader(pFunction, &pAssemblerBuffer)) {
880879
hash = SuperFastHash(static_cast<char *>(pAssemblerBuffer->GetBufferPointer()), pAssemblerBuffer->GetBufferSize());
881880
}
882881
else {
@@ -886,11 +885,11 @@ HRESULT RSManager::redirectCreatePixelShader(CONST DWORD* pFunction, IDirect3DPi
886885
}
887886

888887
if (shouldDump) {
889-
dumpPixelShader(hash, pAssemblerBuffer);
888+
dumpShader(hash, PIXEL_SHADER_DUMP_DIR, pAssemblerBuffer);
890889
}
891890

892891
if (shouldOverride) {
893-
if (getOverridePixelShader(hash, &pFunctionBuffer)) {
892+
if (getOverrideShader(hash, PIXEL_SHADER_OVERRIDE_DIR, &pFunctionBuffer)) {
894893
pFunction = static_cast<DWORD *>(pFunctionBuffer->GetBufferPointer());
895894
}
896895
}
@@ -904,33 +903,70 @@ HRESULT RSManager::redirectCreatePixelShader(CONST DWORD* pFunction, IDirect3DPi
904903
return result;
905904
}
906905

907-
bool RSManager::disassemblePixelShader(CONST DWORD *pFunction, LPD3DXBUFFER *ppBuffer) {
906+
HRESULT RSManager::redirectCreateVertexShader(CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader)
907+
{
908+
bool shouldDump = Settings::get().getEnableShaderDumping();
909+
bool shouldOverride = Settings::get().getEnableShaderOverride();
910+
LPD3DXBUFFER pAssemblerBuffer = nullptr;
911+
LPD3DXBUFFER pFunctionBuffer = nullptr;
912+
UINT32 hash;
913+
914+
if (shouldDump || shouldOverride) {
915+
if (disassembleShader(pFunction, &pAssemblerBuffer)) {
916+
hash = SuperFastHash(static_cast<char *>(pAssemblerBuffer->GetBufferPointer()), pAssemblerBuffer->GetBufferSize());
917+
}
918+
else {
919+
shouldDump = false;
920+
shouldOverride = false;
921+
}
922+
}
923+
924+
if (shouldDump) {
925+
dumpShader(hash, VERTEX_SHADER_DUMP_DIR, pAssemblerBuffer);
926+
}
927+
928+
if (shouldOverride) {
929+
if (getOverrideShader(hash, VERTEX_SHADER_OVERRIDE_DIR, &pFunctionBuffer)) {
930+
pFunction = static_cast<DWORD *>(pFunctionBuffer->GetBufferPointer());
931+
}
932+
}
933+
934+
HRESULT result = d3ddev->CreateVertexShader(pFunction, ppShader);
935+
if (shouldDump || shouldOverride) {
936+
SDLOG(1, "Created vertex shader for hash %08x: 0x%p\n", hash, *ppShader);
937+
}
938+
SAFERELEASE(pAssemblerBuffer);
939+
SAFERELEASE(pFunctionBuffer);
940+
return result;
941+
}
942+
943+
bool RSManager::disassembleShader(CONST DWORD *pFunction, LPD3DXBUFFER *ppBuffer) {
908944
LPD3DXBUFFER buffer = nullptr;
909945
HRESULT result = D3DXDisassembleShader(pFunction, false, NULL, ppBuffer);
910946
if (result != D3D_OK) {
911-
SDLOG(0, "Failed to disassemble pixel shader\n");
947+
SDLOG(0, "Failed to disassemble shader\n");
912948
}
913949
return result == D3D_OK;
914950
}
915951

916-
void RSManager::dumpPixelShader(UINT32 hash, LPD3DXBUFFER pBuffer) {
952+
void RSManager::dumpShader(UINT32 hash, const char *directory, LPD3DXBUFFER pBuffer) {
917953
char fileNameBuffer[64];
918-
sprintf_s(fileNameBuffer, PIXEL_SHADER_DUMP_DIR "/%08x.asm", hash);
954+
sprintf_s(fileNameBuffer, "%s/%08x.asm", directory, hash);
919955
const char *fileName = GetDirectoryFile(fileNameBuffer);
920-
if (writeFile(fileName, static_cast<char *>(pBuffer->GetBufferPointer()), pBuffer->GetBufferSize())) {
921-
SDLOG(0, "Wrote disassembled pixel shader to %s\n", fileNameBuffer);
956+
if (writeFile(fileName, static_cast<char *>(pBuffer->GetBufferPointer()), pBuffer->GetBufferSize() - 1)) {
957+
SDLOG(0, "Wrote disassembled shader to %s\n", fileNameBuffer);
922958
}
923959
else {
924-
SDLOG(0, "Failed to write disassembled pixel shader to %s\n", fileNameBuffer);
960+
SDLOG(0, "Failed to write disassembled shader to %s\n", fileNameBuffer);
925961
}
926962
}
927963

928-
bool RSManager::getOverridePixelShader(UINT32 hash, LPD3DXBUFFER *ppBuffer) {
964+
bool RSManager::getOverrideShader(UINT32 hash, const char *directory, LPD3DXBUFFER *ppBuffer) {
929965
char fileNameBuffer[64];
930-
sprintf_s(fileNameBuffer, PIXEL_SHADER_OVERRIDE_DIR "/%08x.asm", hash);
966+
sprintf_s(fileNameBuffer, "%s/%08x.asm", directory, hash);
931967
const char * fileName = GetDirectoryFile(fileNameBuffer);
932968
if (fileExists(fileName)) {
933-
SDLOG(1, "Pixel shader override: %08x\n", hash);
969+
SDLOG(1, "Shader override: %s\n", fileName);
934970
LPD3DXBUFFER errors = nullptr;
935971
HRESULT assembleResult = D3DXAssembleShaderFromFile(fileName, nullptr, nullptr, 0, ppBuffer, &errors);
936972
if (assembleResult != D3D_OK) {

RenderstateManager.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ class RSManager {
113113

114114
std::map<UINT32, MemData> cachedTexFiles;
115115

116-
bool disassemblePixelShader(CONST DWORD *pFunction, LPD3DXBUFFER *ppBuffer);
117-
void dumpPixelShader(UINT32 hash, LPD3DXBUFFER pBuffer);
118-
bool getOverridePixelShader(UINT32 hash, LPD3DXBUFFER *ppBuffer);
116+
bool disassembleShader(CONST DWORD *pFunction, LPD3DXBUFFER *ppBuffer);
117+
void dumpShader(UINT32 hash, const char *directory, LPD3DXBUFFER pBuffer);
118+
bool getOverrideShader(UINT32 hash, const char *directory, LPD3DXBUFFER *ppBuffer);
119119

120120
private:
121121
~RSManager();
@@ -194,4 +194,5 @@ class RSManager {
194194
HRESULT redirectSetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
195195
HRESULT redirectSetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
196196
HRESULT redirectCreatePixelShader(CONST DWORD *pfunction, IDirect3DPixelShader9 **ppShader);
197+
HRESULT redirectCreateVertexShader(CONST DWORD *pfunction, IDirect3DVertexShader9 **ppShader);
197198
};

Settings.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ SETTING(bool, EnableTextureDumping, "enableTextureDumping", false);
5252
SETTING(bool, EnableTextureOverride, "enableTextureOverride", false);
5353
SETTING(bool, EnableTexturePrefetch, "enableTexturePrefetch", false);
5454

55-
// Pixel Shader Override Options
56-
SETTING(bool, EnablePixelShaderDumping, "enablePixelShaderDumping", false);
57-
SETTING(bool, EnablePixelShaderOverride, "enablePixelShaderOverride", false);
55+
// Shader Override Options
56+
SETTING(bool, EnableShaderDumping, "enableShaderDumping", false);
57+
SETTING(bool, EnableShaderOverride, "enableShaderOverride", false);
5858

5959
// HUD options
6060
SETTING(bool, EnableHudMod, "enableHudMod", false)

d3d9dev.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,7 @@ HRESULT APIENTRY hkIDirect3DDevice9::CreateVertexDeclaration(CONST D3DVERTEXELEM
253253
}
254254

255255
HRESULT APIENTRY hkIDirect3DDevice9::CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader) {
256-
HRESULT res = m_pD3Ddev->CreateVertexShader(pFunction, ppShader);
257-
if(Settings::get().getLogLevel() > 12) {
258-
SDLOG(12, "CreateVertexShader data: %p : shader: %p\n", pFunction, *ppShader);
259-
LPD3DXBUFFER buffer;
260-
D3DXDisassembleShader(pFunction, false, NULL, &buffer);
261-
SDLOG(12, "===== disassembly:\n%s\n==============\n", buffer->GetBufferPointer());
262-
}
263-
return res;
256+
return RSManager::get().redirectCreateVertexShader(pFunction, ppShader);
264257
}
265258

266259
HRESULT APIENTRY hkIDirect3DDevice9::CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle) {

main.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ bool WINAPI DllMain(HMODULE hDll, DWORD dwReason, PVOID pvReserved) {
7979
return false;
8080
}
8181

82-
char *GetDirectoryFile(char *filename) {
82+
char *GetDirectoryFile(const char *filename) {
8383
static char path[320];
8484
strcpy_s(path, dlldir);
8585
strcat_s(path, filename);
@@ -136,6 +136,14 @@ bool fileExists(const char *filename) {
136136
return std::ifstream(filename).good();
137137
}
138138

139+
void createDirectory(const char *fileName) {
140+
CreateDirectory(GetDirectoryFile(fileName), nullptr);
141+
DWORD error = GetLastError();
142+
if (error && error != ERROR_ALREADY_EXISTS) {
143+
SDLOG(0, "Failed to create %s: %s\n", fileName, formatMessage(error));
144+
}
145+
}
146+
139147
bool writeFile(const char *filename, const char *data, size_t length) {
140148
std::ofstream file(filename, std::ios::out | std::ios::binary);
141149
if (!file) {

main.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@
3636
#include "dinput.h"
3737
#include <string>
3838

39-
char *GetDirectoryFile(char *filename);
39+
char *GetDirectoryFile(const char *filename);
4040
bool fileExists(const char *filename);
41+
void createDirectory(const char *filename);
4142
bool writeFile(const char *filename, const char *data, size_t length);
4243
std::string formatMessage(DWORD messageId);
4344
std::string strError(int err);

0 commit comments

Comments
 (0)