From 3b18682ec801546fc7b2a1b9593161fa99c5adcd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 27 Nov 2012 15:25:21 +0000 Subject: [PATCH] d3dtrace,d3dretrace: Move shader disassembly helpers to common location. --- CMakeLists.txt | 1 + helpers/CMakeLists.txt | 13 +++ helpers/d3dshader.cpp | 184 +++++++++++++++++++++++++++++++++++ helpers/d3dshader.hpp | 51 ++++++++++ retrace/CMakeLists.txt | 1 + retrace/d3d9state.cpp | 64 +----------- retrace/dxgiretrace.py | 2 + wrappers/CMakeLists.txt | 15 ++- wrappers/d3d9shader.cpp | 66 ++----------- wrappers/d3dcommonshader.cpp | 94 ++---------------- 10 files changed, 282 insertions(+), 209 deletions(-) create mode 100644 helpers/CMakeLists.txt create mode 100644 helpers/d3dshader.cpp create mode 100644 helpers/d3dshader.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d97b1e..e39bb45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -346,6 +346,7 @@ endif () # Sub-directories add_subdirectory (dispatch) +add_subdirectory (helpers) add_subdirectory (wrappers) add_subdirectory (retrace) diff --git a/helpers/CMakeLists.txt b/helpers/CMakeLists.txt new file mode 100644 index 0000000..53a639f --- /dev/null +++ b/helpers/CMakeLists.txt @@ -0,0 +1,13 @@ +############################################################################## +# API helpers + + +if (WIN32) + add_library (d3dhelpers STATIC + d3dshader.cpp + ) + set_target_properties (d3dhelpers PROPERTIES + # Ensure it can be statically linked in shared libraries + COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}" + ) +endif () diff --git a/helpers/d3dshader.cpp b/helpers/d3dshader.cpp new file mode 100644 index 0000000..06a7135 --- /dev/null +++ b/helpers/d3dshader.cpp @@ -0,0 +1,184 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * Copyright 2008-2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include + +#include "d3dshader.hpp" +#include "os.hpp" + + +struct ID3DXBuffer : public IUnknown { + virtual LPVOID STDMETHODCALLTYPE GetBufferPointer(void) = 0; + virtual DWORD STDMETHODCALLTYPE GetBufferSize(void) = 0; +}; + +typedef HRESULT +(WINAPI *PD3DXDISASSEMBLESHADER)( + CONST DWORD *pShader, + BOOL EnableColorCode, + LPCSTR pComments, + ID3DXBuffer **ppDisassembly +); + + +HRESULT +DisassembleShader(const DWORD *tokens, IDisassemblyBuffer **ppDisassembly) +{ + static BOOL firsttime = TRUE; + + /* + * TODO: Consider using d3dcompile_xx.dll per + * http://msdn.microsoft.com/en-us/library/windows/desktop/ee663275.aspx + */ + + static HMODULE hD3DXModule = NULL; + static PD3DXDISASSEMBLESHADER pfnD3DXDisassembleShader = NULL; + + if (firsttime) { + if (!hD3DXModule) { + unsigned release; + int version; + for (release = 0; release <= 1; ++release) { + /* Version 41 corresponds to Mar 2009 version of DirectX Runtime / SDK */ + for (version = 41; version >= 0; --version) { + char filename[256]; + _snprintf(filename, sizeof(filename), + "d3dx9%s%s%u.dll", release ? "" : "d", version ? "_" : "", version); + hD3DXModule = LoadLibraryA(filename); + if (hD3DXModule) + goto found; + } + } +found: + ; + } + + if (hD3DXModule) { + if (!pfnD3DXDisassembleShader) { + pfnD3DXDisassembleShader = (PD3DXDISASSEMBLESHADER)GetProcAddress(hD3DXModule, "D3DXDisassembleShader"); + } + } + + firsttime = FALSE; + } + + HRESULT hr = E_FAIL; + if (pfnD3DXDisassembleShader) { + hr = pfnD3DXDisassembleShader(tokens, FALSE, NULL, + reinterpret_cast(ppDisassembly)); + } + return hr; +} + + +struct ID3D10Blob : public IUnknown { + virtual LPVOID STDMETHODCALLTYPE GetBufferPointer(void) = 0; + virtual SIZE_T STDMETHODCALLTYPE GetBufferSize(void) = 0; +}; + +typedef ID3D10Blob ID3DBlob; + +#define D3D_DISASM_ENABLE_COLOR_CODE 0x00000001 +#define D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS 0x00000002 +#define D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING 0x00000004 +#define D3D_DISASM_ENABLE_INSTRUCTION_CYCLE 0x00000008 +#define D3D_DISASM_DISABLE_DEBUG_INFO 0x00000010 +#define D3D_DISASM_ENABLE_INSTRUCTION_OFFSET 0x00000020 +#define D3D_DISASM_INSTRUCTION_ONLY 0x00000040 + +typedef HRESULT +(WINAPI *PFND3DDISASSEMBLE)( + LPCVOID pSrcData, + SIZE_T SrcDataSize, + UINT Flags, + LPCSTR szComments, + ID3DBlob **ppDisassembly +); + +static PFND3DDISASSEMBLE pfnD3DDisassemble = NULL; + +typedef HRESULT +(WINAPI *PFND3D10DISASSEMBLESHADER)( + const void *pShader, + SIZE_T BytecodeLength, + BOOL EnableColorCode, + LPCSTR pComments, + ID3D10Blob **ppDisassembly +); + +static PFND3D10DISASSEMBLESHADER pfnD3D10DisassembleShader = NULL; + + +HRESULT +DisassembleShader(const void *pShaderBytecode, SIZE_T BytecodeLength, IDisassemblyBuffer **ppDisassembly) +{ + static bool firsttime = true; + + if (firsttime) { + char szFilename[MAX_PATH]; + HMODULE hModule = NULL; + int version; + for (version = 44; version >= 33; --version) { + _snprintf(szFilename, sizeof(szFilename), "d3dcompiler_%i.dll", version); + hModule = LoadLibraryA(szFilename); + if (hModule) { + pfnD3DDisassemble = (PFND3DDISASSEMBLE) + GetProcAddress(hModule, "D3DDisassemble"); + if (pfnD3DDisassemble) { + break; + } + } + } + if (!pfnD3DDisassemble) { + /* + * Fallback to D3D10DisassembleShader, which should be always present. + */ + if (GetSystemDirectoryA(szFilename, MAX_PATH)) { + strcat(szFilename, "\\d3d10.dll"); + hModule = LoadLibraryA(szFilename); + if (hModule) { + pfnD3D10DisassembleShader = (PFND3D10DISASSEMBLESHADER) + GetProcAddress(hModule, "D3D10DisassembleShader"); + } + } + } + + firsttime = false; + } + + HRESULT hr = E_FAIL; + + if (pfnD3DDisassemble) { + hr = pfnD3DDisassemble(pShaderBytecode, BytecodeLength, 0, NULL, + reinterpret_cast(ppDisassembly)); + } else if (pfnD3D10DisassembleShader) { + hr = pfnD3D10DisassembleShader(pShaderBytecode, BytecodeLength, 0, NULL, + reinterpret_cast(ppDisassembly)); + } + + return hr; +} diff --git a/helpers/d3dshader.hpp b/helpers/d3dshader.hpp new file mode 100644 index 0000000..169785e --- /dev/null +++ b/helpers/d3dshader.hpp @@ -0,0 +1,51 @@ +/************************************************************************** + * + * Copyright 2012 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _D3DSHADER_HPP_ +#define _D3DSHADER_HPP_ + + +#include + +// Matches ID3DXBuffer, ID3D10Blob, ID3DBlob +struct IDisassemblyBuffer : public IUnknown { + virtual LPVOID STDMETHODCALLTYPE GetBufferPointer(void) = 0; + + // XXX: ID3D10Blob, ID3DBlob actually return SIZE_T but DWORD should give + // the same results + virtual DWORD STDMETHODCALLTYPE GetBufferSize(void) = 0; +}; + + +// D3D9 and earlier +HRESULT +DisassembleShader(const DWORD *tokens, IDisassemblyBuffer **ppDisassembly); + +// D3D10 and higher +HRESULT +DisassembleShader(const void *pShader, SIZE_T BytecodeLength, IDisassemblyBuffer **ppDisassembly); + + +#endif /* _D3DSHADER_HPP_ */ diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt index 41a94d0..57079b5 100644 --- a/retrace/CMakeLists.txt +++ b/retrace/CMakeLists.txt @@ -228,6 +228,7 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR) ) target_link_libraries (d3dretrace retrace_common + d3dhelpers ) install (TARGETS d3dretrace RUNTIME DESTINATION bin) diff --git a/retrace/d3d9state.cpp b/retrace/d3d9state.cpp index 73746e7..3865cb3 100644 --- a/retrace/d3d9state.cpp +++ b/retrace/d3d9state.cpp @@ -29,70 +29,13 @@ #include #include "d3d9imports.hpp" +#include "d3dshader.hpp" #include "json.hpp" namespace d3dstate { -typedef HRESULT -(WINAPI *PD3DXDISASSEMBLESHADER)( - CONST DWORD *pShader, - BOOL EnableColorCode, - LPCSTR pComments, - LPD3DXBUFFER *ppDisassembly -); - - -HRESULT -disassembleShader(const DWORD *tokens, LPD3DXBUFFER *ppDisassembly) -{ - static BOOL firsttime = TRUE; - - /* - * TODO: Consider using d3dcompile_xx.dll per - * http://msdn.microsoft.com/en-us/library/windows/desktop/ee663275.aspx - */ - - static HMODULE hD3DXModule = NULL; - static PD3DXDISASSEMBLESHADER pfnD3DXDisassembleShader = NULL; - - if (firsttime) { - if (!hD3DXModule) { - unsigned release; - int version; - for (release = 0; release <= 1; ++release) { - /* Version 41 corresponds to Mar 2009 version of DirectX Runtime / SDK */ - for (version = 41; version >= 0; --version) { - char filename[256]; - _snprintf(filename, sizeof(filename), - "d3dx9%s%s%u.dll", release ? "" : "d", version ? "_" : "", version); - hD3DXModule = LoadLibraryA(filename); - if (hD3DXModule) - goto found; - } - } -found: - ; - } - - if (hD3DXModule) { - if (!pfnD3DXDisassembleShader) { - pfnD3DXDisassembleShader = (PD3DXDISASSEMBLESHADER)GetProcAddress(hD3DXModule, "D3DXDisassembleShader"); - } - } - - firsttime = FALSE; - } - - if (!pfnD3DXDisassembleShader) { - return E_FAIL; - } - - return pfnD3DXDisassembleShader(tokens, FALSE, NULL, ppDisassembly); -} - - template< class T > inline void dumpShader(JSONWriter &json, const char *name, T *pShader) { @@ -111,9 +54,8 @@ dumpShader(JSONWriter &json, const char *name, T *pShader) { if (pData) { hr = pShader->GetFunction(pData, &SizeOfData); if (SUCCEEDED(hr)) { - LPD3DXBUFFER pDisassembly; - - hr = disassembleShader((const DWORD *)pData, &pDisassembly); + IDisassemblyBuffer *pDisassembly = NULL; + hr = DisassembleShader((const DWORD *)pData, &pDisassembly); if (SUCCEEDED(hr)) { json.beginMember(name); json.writeString((const char *)pDisassembly->GetBufferPointer() /*, pDisassembly->GetBufferSize() */); diff --git a/retrace/dxgiretrace.py b/retrace/dxgiretrace.py index 95face8..72520c0 100644 --- a/retrace/dxgiretrace.py +++ b/retrace/dxgiretrace.py @@ -88,7 +88,9 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) { print r' DriverType = D3D_DRIVER_TYPE_HARDWARE;' print r' }' + # Force software renderer if function.name.startswith('D3D10CreateDevice'): + print r' Flags |= D3D10_CREATE_DEVICE_DEBUG;' self.forceDriver('D3D10_DRIVER_TYPE') if function.name.startswith('D3D11CreateDevice'): self.forceDriver('D3D_DRIVER_TYPE') diff --git a/wrappers/CMakeLists.txt b/wrappers/CMakeLists.txt index 93be8e8..8a0e769 100644 --- a/wrappers/CMakeLists.txt +++ b/wrappers/CMakeLists.txt @@ -76,8 +76,13 @@ if (WIN32) ${CMAKE_SOURCE_DIR}/specs/winapi.py ${CMAKE_SOURCE_DIR}/specs/stdapi.py ) - add_library (d3d8trace MODULE d3d8.def d3d8trace.cpp d3d9shader.cpp) + add_library (d3d8trace MODULE + d3d8.def + d3d8trace.cpp + d3d9shader.cpp + ) target_link_libraries (d3d8trace + d3dhelpers common_trace common ${ZLIB_LIBRARIES} @@ -108,8 +113,13 @@ if (WIN32) ${CMAKE_SOURCE_DIR}/specs/winapi.py ${CMAKE_SOURCE_DIR}/specs/stdapi.py ) - add_library (d3d9trace MODULE d3d9.def d3d9trace.cpp d3d9shader.cpp) + add_library (d3d9trace MODULE + d3d9.def + d3d9trace.cpp + d3d9shader.cpp + ) target_link_libraries (d3d9trace + d3dhelpers common_trace common ${ZLIB_LIBRARIES} @@ -176,6 +186,7 @@ if (WIN32) d3dcommonshader.cpp ) target_link_libraries (dxgitrace + d3dhelpers common_trace common ${ZLIB_LIBRARIES} diff --git a/wrappers/d3d9shader.cpp b/wrappers/d3d9shader.cpp index b2a39f6..6dbe06b 100644 --- a/wrappers/d3d9shader.cpp +++ b/wrappers/d3d9shader.cpp @@ -27,78 +27,28 @@ #include +#include "os.hpp" +#include "d3dshader.hpp" + #include "d3d9shader.hpp" #include "d3d9imports.hpp" #include "d3d9size.hpp" -typedef HRESULT -(WINAPI *PD3DXDISASSEMBLESHADER)( - CONST DWORD *pShader, - BOOL EnableColorCode, - LPCSTR pComments, - LPD3DXBUFFER *ppDisassembly -); - - void DumpShader(trace::Writer &writer, const DWORD *tokens) { - static BOOL firsttime = TRUE; - - /* - * TODO: Consider using d3dcompile_xx.dll per - * http://msdn.microsoft.com/en-us/library/windows/desktop/ee663275.aspx - */ - - static HMODULE hD3DXModule = NULL; - static PD3DXDISASSEMBLESHADER pfnD3DXDisassembleShader = NULL; - - if (firsttime) { - if (!hD3DXModule) { - unsigned release; - int version; - for (release = 0; release <= 1; ++release) { - /* Version 41 corresponds to Mar 2009 version of DirectX Runtime / SDK */ - for (version = 41; version >= 0; --version) { - char filename[256]; - _snprintf(filename, sizeof(filename), - "d3dx9%s%s%u.dll", release ? "" : "d", version ? "_" : "", version); - hD3DXModule = LoadLibraryA(filename); - if (hD3DXModule) - goto found; - } - } -found: - ; - } - - if (hD3DXModule) { - if (!pfnD3DXDisassembleShader) { - pfnD3DXDisassembleShader = (PD3DXDISASSEMBLESHADER)GetProcAddress(hD3DXModule, "D3DXDisassembleShader"); - } - } - - firsttime = FALSE; - } - - LPD3DXBUFFER pDisassembly = NULL; - HRESULT hr = E_FAIL; - - if (pfnD3DXDisassembleShader) { - hr = pfnD3DXDisassembleShader(tokens, FALSE, NULL, &pDisassembly); - } + IDisassemblyBuffer *pDisassembly = NULL; + HRESULT hr = DisassembleShader(tokens, &pDisassembly); if (SUCCEEDED(hr)) { writer.beginRepr(); - writer.writeString((const char *)pDisassembly->GetBufferPointer(), pDisassembly->GetBufferSize()); + writer.writeString((const char *)pDisassembly->GetBufferPointer(), + pDisassembly->GetBufferSize()); + pDisassembly->Release(); } writer.writeBlob(tokens, _shaderSize(tokens)); - if (pDisassembly) { - pDisassembly->Release(); - } - if (SUCCEEDED(hr)) { writer.endRepr(); } diff --git a/wrappers/d3dcommonshader.cpp b/wrappers/d3dcommonshader.cpp index 2ae804b..a66e017 100644 --- a/wrappers/d3dcommonshader.cpp +++ b/wrappers/d3dcommonshader.cpp @@ -27,106 +27,24 @@ #include +#include "d3dshader.hpp" #include "d3dcommonshader.hpp" -struct ID3D10Blob : public IUnknown { -public: - virtual LPVOID STDMETHODCALLTYPE GetBufferPointer( void) = 0; - virtual SIZE_T STDMETHODCALLTYPE GetBufferSize( void) = 0; -}; - -typedef ID3D10Blob ID3DBlob; -typedef ID3DBlob* LPD3DBLOB; - -#define D3D_DISASM_ENABLE_COLOR_CODE 0x00000001 -#define D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS 0x00000002 -#define D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING 0x00000004 -#define D3D_DISASM_ENABLE_INSTRUCTION_CYCLE 0x00000008 -#define D3D_DISASM_DISABLE_DEBUG_INFO 0x00000010 -#define D3D_DISASM_ENABLE_INSTRUCTION_OFFSET 0x00000020 -#define D3D_DISASM_INSTRUCTION_ONLY 0x00000040 - -typedef HRESULT -(WINAPI *PFND3DDISASSEMBLE)( - LPCVOID pSrcData, - SIZE_T SrcDataSize, - UINT Flags, - LPCSTR szComments, - ID3DBlob **ppDisassembly -); - -static PFND3DDISASSEMBLE pfnD3DDisassemble = NULL; - -typedef HRESULT -(WINAPI *PFND3D10DISASSEMBLESHADER)( - const void *pShader, - SIZE_T BytecodeLength, - BOOL EnableColorCode, - LPCSTR pComments, - ID3D10Blob **ppDisassembly -); - -static PFND3D10DISASSEMBLESHADER pfnD3D10DisassembleShader = NULL; - void DumpShader(trace::Writer &writer, const void *pShaderBytecode, SIZE_T BytecodeLength) { - static bool firsttime = true; - - if (firsttime) { - char szFilename[MAX_PATH]; - HMODULE hModule = NULL; - - int version; - for (version = 44; version >= 33; --version) { - _snprintf(szFilename, sizeof(szFilename), "d3dcompiler_%i.dll", version); - hModule = LoadLibraryA(szFilename); - if (hModule) { - pfnD3DDisassemble = (PFND3DDISASSEMBLE) - GetProcAddress(hModule, "D3DDisassemble"); - if (pfnD3DDisassemble) { - break; - } - } - } - - if (!pfnD3DDisassemble) { - /* - * Fallback to D3D10DisassembleShader, which should be always present. - */ - if (GetSystemDirectoryA(szFilename, MAX_PATH)) { - strcat(szFilename, "\\d3d10.dll"); - hModule = LoadLibraryA(szFilename); - if (hModule) { - pfnD3D10DisassembleShader = (PFND3D10DISASSEMBLESHADER) - GetProcAddress(hModule, "D3D10DisassembleShader"); - } - } - } - - firsttime = false; - } - - LPD3DBLOB pDisassembly = NULL; - HRESULT hr = E_FAIL; - - if (pfnD3DDisassemble) { - hr = pfnD3DDisassemble(pShaderBytecode, BytecodeLength, 0, NULL, &pDisassembly); - } else if (pfnD3D10DisassembleShader) { - hr = pfnD3D10DisassembleShader(pShaderBytecode, BytecodeLength, 0, NULL, &pDisassembly); - } + IDisassemblyBuffer *pDisassembly = NULL; + HRESULT hr = DisassembleShader(pShaderBytecode, BytecodeLength, &pDisassembly); if (SUCCEEDED(hr)) { writer.beginRepr(); - writer.writeString((const char *)pDisassembly->GetBufferPointer(), pDisassembly->GetBufferSize()); + writer.writeString((const char *)pDisassembly->GetBufferPointer(), + pDisassembly->GetBufferSize()); + pDisassembly->Release(); } writer.writeBlob(pShaderBytecode, BytecodeLength); - if (pDisassembly) { - pDisassembly->Release(); - } - if (SUCCEEDED(hr)) { writer.endRepr(); } -- 2.43.0