From 610942b9efd69d50875d0076a0957be0b8fff174 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 8 Nov 2012 10:46:03 +0000 Subject: [PATCH] d3d10,d3d11: Rudimentary retrace support. Doesn't work often, in practice because dxgi calls are missing from traces. --- retrace/CMakeLists.txt | 101 +++++++++++++++++++++++++++++++++--- retrace/d3d10_1retrace.py | 48 +++++++++++++++++ retrace/d3d10retrace.py | 69 ++---------------------- retrace/d3d11retrace.py | 48 +++++++++++++++++ retrace/d3d9retrace.py | 2 +- retrace/d3dcommonretrace.py | 94 +++++++++++++++++++++++++++++++++ retrace/d3dretrace.hpp | 3 +- retrace/d3dretrace_main.cpp | 3 +- retrace/retrace.py | 1 - 9 files changed, 290 insertions(+), 79 deletions(-) create mode 100644 retrace/d3d10_1retrace.py create mode 100644 retrace/d3d11retrace.py create mode 100644 retrace/d3dcommonretrace.py diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt index 69612f0..1f260e4 100644 --- a/retrace/CMakeLists.txt +++ b/retrace/CMakeLists.txt @@ -128,7 +128,7 @@ if (ENABLE_EGL AND X11_FOUND AND NOT WIN32 AND NOT APPLE) install (TARGETS eglretrace RUNTIME DESTINATION bin) endif () -if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR AND DirectX_D3D10_INCLUDE_DIR) +if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR) add_custom_command ( OUTPUT d3dretrace_d3d9.cpp COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d9retrace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3dretrace_d3d9.cpp @@ -144,11 +144,28 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR AND DirectX_D3D10_INCLUDE_DIR) ${CMAKE_SOURCE_DIR}/specs/stdapi.py ) + include_directories (SYSTEM ${DirectX_D3DX9_INCLUDE_DIR}) + add_executable (d3dretrace + d3dretrace_main.cpp + d3dretrace_d3d9.cpp + d3dretrace_ws.cpp + d3d9state.cpp + d3d9state_images.cpp + ) + target_link_libraries (d3dretrace + retrace_common + ) + + install (TARGETS d3dretrace RUNTIME DESTINATION bin) +endif () + +if (WIN32 AND DirectX_D3D10_INCLUDE_DIR) add_custom_command ( OUTPUT d3dretrace_d3d10.cpp COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10retrace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3dretrace_d3d10.cpp DEPENDS d3d10retrace.py + d3dcommonretrace.py dllretrace.py retrace.py ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py @@ -165,19 +182,89 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR AND DirectX_D3D10_INCLUDE_DIR) ${CMAKE_SOURCE_DIR}/specs/stdapi.py ) - include_directories (SYSTEM ${DirectX_D3DX9_INCLUDE_DIR}) - add_executable (d3dretrace + include_directories (SYSTEM ${DirectX_D3D10_INCLUDE_DIR}) + add_executable (d3d10retrace d3dretrace_main.cpp - d3dretrace_d3d9.cpp d3dretrace_d3d10.cpp d3dretrace_ws.cpp d3d9state.cpp d3d9state_images.cpp ) - target_link_libraries (d3dretrace + target_link_libraries (d3d10retrace retrace_common ) - - install (TARGETS d3dretrace RUNTIME DESTINATION bin) + + install (TARGETS d3d10retrace RUNTIME DESTINATION bin) endif () +if (WIN32 AND DirectX_D3D10_1_INCLUDE_DIR) + add_custom_command ( + OUTPUT d3dretrace_d3d10_1.cpp + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10_1retrace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3dretrace_d3d10_1.cpp + DEPENDS + d3d10retrace.py + d3dcommonretrace.py + dllretrace.py + retrace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py + ${CMAKE_SOURCE_DIR}/specs/d3d10_1.py + ${CMAKE_SOURCE_DIR}/specs/d3d10.py + ${CMAKE_SOURCE_DIR}/specs/d3d10sdklayers.py + ${CMAKE_SOURCE_DIR}/specs/d3dcommon.py + ${CMAKE_SOURCE_DIR}/specs/dxgi.py + ${CMAKE_SOURCE_DIR}/specs/dxgitype.py + ${CMAKE_SOURCE_DIR}/specs/dxgiformat.py + ${CMAKE_SOURCE_DIR}/specs/winapi.py + ${CMAKE_SOURCE_DIR}/specs/stdapi.py + ) + + include_directories (SYSTEM ${DirectX_D3D10_1_INCLUDE_DIR}) + add_executable (d3d10_1retrace + d3dretrace_main.cpp + d3dretrace_d3d10_1.cpp + d3dretrace_ws.cpp + d3d9state.cpp + d3d9state_images.cpp + ) + target_link_libraries (d3d10_1retrace + retrace_common + ) + + install (TARGETS d3d10_1retrace RUNTIME DESTINATION bin) +endif () + +if (WIN32 AND DirectX_D3D11_INCLUDE_DIR) + add_custom_command ( + OUTPUT d3dretrace_d3d11.cpp + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d11retrace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3dretrace_d3d11.cpp + DEPENDS + d3d11retrace.py + d3dcommonretrace.py + dllretrace.py + retrace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py + ${CMAKE_SOURCE_DIR}/specs/d3d11_1.py + ${CMAKE_SOURCE_DIR}/specs/d3d11.py + ${CMAKE_SOURCE_DIR}/specs/d3d11sdklayers.py + ${CMAKE_SOURCE_DIR}/specs/d3dcommon.py + ${CMAKE_SOURCE_DIR}/specs/dxgi.py + ${CMAKE_SOURCE_DIR}/specs/dxgitype.py + ${CMAKE_SOURCE_DIR}/specs/dxgiformat.py + ${CMAKE_SOURCE_DIR}/specs/winapi.py + ${CMAKE_SOURCE_DIR}/specs/stdapi.py + ) + + include_directories (SYSTEM ${DirectX_D3D11_INCLUDE_DIR}) + add_executable (d3d11retrace + d3dretrace_main.cpp + d3dretrace_d3d11.cpp + d3dretrace_ws.cpp + d3d9state.cpp + d3d9state_images.cpp + ) + target_link_libraries (d3d11retrace + retrace_common + ) + + install (TARGETS d3d11retrace RUNTIME DESTINATION bin) +endif () diff --git a/retrace/d3d10_1retrace.py b/retrace/d3d10_1retrace.py new file mode 100644 index 0000000..bb45b82 --- /dev/null +++ b/retrace/d3d10_1retrace.py @@ -0,0 +1,48 @@ +########################################################################## +# +# Copyright 2011 Jose Fonseca +# 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. +# +##########################################################################/ + + +"""D3D10 retracer generator.""" + + +from d3dcommonretrace import D3DRetracer +import specs.stdapi as stdapi +from specs.d3d10_1 import d3d10_1 + + +if __name__ == '__main__': + print r''' +#include + +#include + +#include "d3d10_1imports.hpp" +#include "d3d10size.hpp" +#include "d3dretrace.hpp" + +''' + + retracer = D3DRetracer() + retracer.retraceApi(d3d10_1) diff --git a/retrace/d3d10retrace.py b/retrace/d3d10retrace.py index ee8736b..877b1e4 100644 --- a/retrace/d3d10retrace.py +++ b/retrace/d3d10retrace.py @@ -24,75 +24,12 @@ ##########################################################################/ -"""D3D retracer generator.""" +"""D3D10 retracer generator.""" -from dllretrace import DllRetracer as Retracer +from d3dcommonretrace import D3DRetracer import specs.stdapi as stdapi -from specs.d3d10 import * - - -class D3DRetracer(Retracer): - - def retraceApi(self, api): - print '// Swizzling mapping for lock addresses' - print 'static std::map _maps;' - print - - self.table_name = 'd3dretrace::%s_callbacks' % api.name.lower() - - Retracer.retraceApi(self, api) - - def invokeFunction(self, function): - # create windows as neccessary - if function.name == 'D3D10CreateDeviceAndSwapChain': - print r' pSwapChainDesc->OutputWindow = d3dretrace::createWindow(512, 512);' - - Retracer.invokeFunction(self, function) - - def invokeInterfaceMethod(self, interface, method): - # keep track of the last used device for state dumping - #if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'): - # print r' d3dretrace::pLastDirect3DDevice9 = _this;' - - # create windows as neccessary - if method.name == 'CreateSwapChain': - print r' pDesc->OutputWindow = d3dretrace::createWindow(512, 512);' - - # notify frame has been completed - if method.name == 'Present': - print r' retrace::frameComplete(call);' - - if 'pSharedResource' in method.argNames(): - print r' if (pSharedResource) {' - print r' retrace::warning(call) << "shared surfaces unsupported\n";' - print r' pSharedResource = NULL;' - print r' }' - - Retracer.invokeInterfaceMethod(self, interface, method) - - # process events after presents - if method.name == 'Present': - print r' d3dretrace::processEvents();' - - # check errors - if str(method.type) == 'HRESULT': - print r' if (FAILED(_result)) {' - print r' retrace::warning(call) << "failed\n";' - print r' }' - - if method.name == 'Map': - print ' VOID *_pbData = NULL;' - print ' size_t _MappedSize = 0;' - print ' _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()) - print ' _maps[_this] = _pbData;' - - if method.name == 'Unmap': - print ' VOID *_pbData = 0;' - print ' _pbData = _maps[_this];' - print ' if (_pbData) {' - print ' retrace::delRegionByPointer(_pbData);' - print ' }' +from specs.d3d10 import d3d10 if __name__ == '__main__': diff --git a/retrace/d3d11retrace.py b/retrace/d3d11retrace.py new file mode 100644 index 0000000..8831024 --- /dev/null +++ b/retrace/d3d11retrace.py @@ -0,0 +1,48 @@ +########################################################################## +# +# Copyright 2011 Jose Fonseca +# 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. +# +##########################################################################/ + + +"""D3D10 retracer generator.""" + + +from d3dcommonretrace import D3DRetracer +import specs.stdapi as stdapi +from specs.d3d11 import d3d11 + + +if __name__ == '__main__': + print r''' +#include + +#include + +#include "d3d11imports.hpp" +#include "d3d11size.hpp" +#include "d3dretrace.hpp" + +''' + + retracer = D3DRetracer() + retracer.retraceApi(d3d11) diff --git a/retrace/d3d9retrace.py b/retrace/d3d9retrace.py index 14b92ab..44104ce 100644 --- a/retrace/d3d9retrace.py +++ b/retrace/d3d9retrace.py @@ -39,7 +39,7 @@ class D3DRetracer(Retracer): print 'static std::map _locks;' print - self.table_name = 'd3dretrace::%s_callbacks' % api.name.lower() + self.table_name = 'd3dretrace::d3d_callbacks' Retracer.retraceApi(self, api) diff --git a/retrace/d3dcommonretrace.py b/retrace/d3dcommonretrace.py new file mode 100644 index 0000000..ea09eb0 --- /dev/null +++ b/retrace/d3dcommonretrace.py @@ -0,0 +1,94 @@ +########################################################################## +# +# Copyright 2011 Jose Fonseca +# 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. +# +##########################################################################/ + + +"""D3D retracer generator.""" + + +from dllretrace import DllRetracer as Retracer +import specs.stdapi as stdapi + + +class D3DRetracer(Retracer): + + def retraceApi(self, api): + print '// Swizzling mapping for lock addresses' + print 'static std::map _maps;' + print + + self.table_name = 'd3dretrace::d3d_callbacks' + + Retracer.retraceApi(self, api) + + def invokeFunction(self, function): + # create windows as neccessary + if function.name in ('D3D10CreateDeviceAndSwapChain', 'D3D10CreateDeviceAndSwapChain1', 'D3D11CreateDeviceAndSwapChain'): + print r' pSwapChainDesc->OutputWindow = d3dretrace::createWindow(512, 512);' + + Retracer.invokeFunction(self, function) + + def invokeInterfaceMethod(self, interface, method): + # keep track of the last used device for state dumping + #if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'): + # print r' d3dretrace::pLastDirect3DDevice9 = _this;' + + # create windows as neccessary + if method.name == 'CreateSwapChain': + print r' pDesc->OutputWindow = d3dretrace::createWindow(512, 512);' + + # notify frame has been completed + if method.name == 'Present': + print r' retrace::frameComplete(call);' + + if 'pSharedResource' in method.argNames(): + print r' if (pSharedResource) {' + print r' retrace::warning(call) << "shared surfaces unsupported\n";' + print r' pSharedResource = NULL;' + print r' }' + + Retracer.invokeInterfaceMethod(self, interface, method) + + # process events after presents + if method.name == 'Present': + print r' d3dretrace::processEvents();' + + # check errors + if str(method.type) == 'HRESULT': + print r' if (FAILED(_result)) {' + print r' retrace::warning(call) << "failed\n";' + print r' }' + + if method.name == 'Map': + print ' VOID *_pbData = NULL;' + print ' size_t _MappedSize = 0;' + print ' _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()) + print ' _maps[_this] = _pbData;' + + if method.name == 'Unmap': + print ' VOID *_pbData = 0;' + print ' _pbData = _maps[_this];' + print ' if (_pbData) {' + print ' retrace::delRegionByPointer(_pbData);' + print ' }' diff --git a/retrace/d3dretrace.hpp b/retrace/d3dretrace.hpp index c4e5bb4..b479237 100644 --- a/retrace/d3dretrace.hpp +++ b/retrace/d3dretrace.hpp @@ -44,8 +44,7 @@ namespace d3dretrace { extern IDirect3DDevice9 *pLastDirect3DDevice9; -extern const retrace::Entry d3d9_callbacks[]; -extern const retrace::Entry d3d10_callbacks[]; +extern const retrace::Entry d3d_callbacks[]; HWND diff --git a/retrace/d3dretrace_main.cpp b/retrace/d3dretrace_main.cpp index 5806546..4bd4b80 100644 --- a/retrace/d3dretrace_main.cpp +++ b/retrace/d3dretrace_main.cpp @@ -54,8 +54,7 @@ retrace::setUp(void) { void retrace::addCallbacks(retrace::Retracer &retracer) { - retracer.addCallbacks(d3dretrace::d3d9_callbacks); - retracer.addCallbacks(d3dretrace::d3d10_callbacks); + retracer.addCallbacks(d3dretrace::d3d_callbacks); } diff --git a/retrace/retrace.py b/retrace/retrace.py index f9b800c..544796d 100644 --- a/retrace/retrace.py +++ b/retrace/retrace.py @@ -34,7 +34,6 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) import specs.stdapi as stdapi -import specs.glapi as glapi class UnsupportedType(Exception): -- 2.43.0