import sys
from dllretrace import DllRetracer as Retracer
+import specs.dxgi
from specs.stdapi import API
from specs.dxgi import dxgi
from specs.d3d10 import d3d10
print r'''
static void
createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
- if (pSwapChainDesc->Windowed) {
- UINT Width = pSwapChainDesc->BufferDesc.Width;
- UINT Height = pSwapChainDesc->BufferDesc.Height;
- if (!Width) Width = 1024;
- if (!Height) Height = 768;
- pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height);
- }
+ UINT Width = pSwapChainDesc->BufferDesc.Width;
+ UINT Height = pSwapChainDesc->BufferDesc.Height;
+ if (!Width) Width = 1024;
+ if (!Height) Height = 768;
+ pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height);
}
'''
print r' }'
if function.name.startswith('D3D10CreateDevice'):
+ # Toggle debugging
+ print r' Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
+ print r' if (retrace::debug) {'
+ print r' if (LoadLibraryA("d3d10sdklayers")) {'
+ print r' Flags |= D3D10_CREATE_DEVICE_DEBUG;'
+ print r' }'
+ print r' }'
+
+ # Force driver
self.forceDriver('D3D10_DRIVER_TYPE')
+
if function.name.startswith('D3D11CreateDevice'):
+ # Toggle debugging
+ print r' Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
+ print r' if (retrace::debug) {'
+ print r' OSVERSIONINFO osvi;'
+ print r' BOOL bIsWindows8orLater;'
+ print r' ZeroMemory(&osvi, sizeof osvi);'
+ print r' osvi.dwOSVersionInfoSize = sizeof osvi;'
+ print r' GetVersionEx(&osvi);'
+ print r' bIsWindows8orLater = '
+ print r' (osvi.dwMajorVersion > 6) ||'
+ print r' (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 2);'
+ print r' const char *szD3d11SdkLayers = bIsWindows8orLater ? "d3d11_1sdklayers" : "d3d11sdklayers";'
+ print r' if (LoadLibraryA(szD3d11SdkLayers)) {'
+ print r' Flags |= D3D11_CREATE_DEVICE_DEBUG;'
+ print r' }'
+ print r' }'
+
+ # Force driver
self.forceDriver('D3D_DRIVER_TYPE')
Retracer.invokeFunction(self, function)
+ # Debug layers with Windows 8 or Windows 7 Platform update are a mess.
+ # It's not possible to know before hand whether they are or not
+ # available, so always retry with debug flag off..
+ if function.name in self.createDeviceFunctionNames:
+ print r' if (FAILED(_result)) {'
+
+ if function.name.startswith('D3D10CreateDevice'):
+ print r' if (_result == E_FAIL && (Flags & D3D10_CREATE_DEVICE_DEBUG)) {'
+ print r' retrace::warning(call) << "debug layer (d3d10sdklayers.dll) not installed\n";'
+ print r' Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
+ Retracer.invokeFunction(self, function)
+ print r' }'
+ elif function.name.startswith('D3D11CreateDevice'):
+ print r' if (_result == E_FAIL && (Flags & D3D11_CREATE_DEVICE_DEBUG)) {'
+ print r' retrace::warning(call) << "debug layer (d3d11sdklayers.dll for Windows 7, d3d11_1sdklayers.dll for Windows 8 or Windows 7 with KB 2670838) not properly installed\n";'
+ print r' Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
+ Retracer.invokeFunction(self, function)
+ print r' }'
+ else:
+ assert False
+
+ print r' if (FAILED(_result)) {'
+ print r' exit(1);'
+ print r' }'
+
+ print r' }'
+
def forceDriver(self, enum):
- print r' switch (retrace::driver) {'
- print r' case retrace::DRIVER_HARDWARE:'
- print r' DriverType = %s_HARDWARE;' % enum
- print r' Software = NULL;'
- print r' break;'
- print r' case retrace::DRIVER_SOFTWARE:'
- print r' pAdapter = NULL;'
- print r' DriverType = %s_WARP;' % enum
- print r' Software = NULL;'
- print r' break;'
- print r' case retrace::DRIVER_REFERENCE:'
- print r' pAdapter = NULL;'
- print r' DriverType = %s_REFERENCE;' % enum
- print r' Software = NULL;'
- print r' break;'
- print r' case retrace::DRIVER_NULL:'
- print r' pAdapter = NULL;'
- print r' DriverType = %s_NULL;' % enum
- print r' Software = NULL;'
- print r' break;'
- print r' case retrace::DRIVER_MODULE:'
- print r' pAdapter = NULL;'
- print r' DriverType = %s_SOFTWARE;' % enum
- print r' Software = LoadLibraryA(retrace::driverModule);'
- print r' if (!Software) {'
- print r' retrace::warning(call) << "failed to load " << retrace::driverModule << "\n";'
- print r' }'
- print r' break;'
- print r' default:'
- print r' assert(0);'
- print r' /* fall-through */'
- print r' case retrace::DRIVER_DEFAULT:'
- print r' if (DriverType == %s_SOFTWARE) {' % enum
- print r' Software = LoadLibraryA("d3d10warp");'
+ # This can only work when pAdapter is NULL. For non-NULL pAdapter we
+ # need to override inside the EnumAdapters call below
+ print r' if (pAdapter == NULL) {'
+ print r' switch (retrace::driver) {'
+ print r' case retrace::DRIVER_HARDWARE:'
+ print r' DriverType = %s_HARDWARE;' % enum
+ print r' Software = NULL;'
+ print r' break;'
+ print r' case retrace::DRIVER_SOFTWARE:'
+ print r' DriverType = %s_WARP;' % enum
+ print r' Software = NULL;'
+ print r' break;'
+ print r' case retrace::DRIVER_REFERENCE:'
+ print r' DriverType = %s_REFERENCE;' % enum
+ print r' Software = NULL;'
+ print r' break;'
+ print r' case retrace::DRIVER_NULL:'
+ print r' DriverType = %s_NULL;' % enum
+ print r' Software = NULL;'
+ print r' break;'
+ print r' case retrace::DRIVER_MODULE:'
+ print r' DriverType = %s_SOFTWARE;' % enum
+ print r' Software = LoadLibraryA(retrace::driverModule);'
print r' if (!Software) {'
- print r' retrace::warning(call) << "failed to load d3d10warp.dll\n";'
+ print r' retrace::warning(call) << "failed to load " << retrace::driverModule << "\n";'
+ print r' }'
+ print r' break;'
+ print r' default:'
+ print r' assert(0);'
+ print r' /* fall-through */'
+ print r' case retrace::DRIVER_DEFAULT:'
+ print r' if (DriverType == %s_SOFTWARE) {' % enum
+ print r' Software = LoadLibraryA("d3d10warp");'
+ print r' if (!Software) {'
+ print r' retrace::warning(call) << "failed to load d3d10warp.dll\n";'
+ print r' }'
print r' }'
+ print r' break;'
print r' }'
- print r' break;'
+ print r' } else {'
+ print r' Software = NULL;'
print r' }'
def invokeInterfaceMethod(self, interface, method):
# keep track of the last used device for state dumping
if interface.name in ('ID3D10Device', 'ID3D10Device1'):
if method.name == 'Release':
- print r' d3d10Dumper.unbindDevice(_this);'
+ print r' if (call.ret->toUInt() == 0) {'
+ print r' d3d10Dumper.unbindDevice(_this);'
+ print r' }'
else:
print r' d3d10Dumper.bindDevice(_this);'
- if interface.name in ('ID3D11DeviceContext',):
+ if interface.name in ('ID3D11DeviceContext', 'ID3D11DeviceContext1'):
if method.name == 'Release':
- print r' d3d11Dumper.unbindDevice(_this);'
+ print r' if (call.ret->toUInt() == 0) {'
+ print r' d3d11Dumper.unbindDevice(_this);'
+ print r' }'
else:
- print r' d3d11Dumper.bindDevice(_this);'
+ print r' if (_this->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) {'
+ print r' d3d11Dumper.bindDevice(_this);'
+ print r' }'
+
+ if interface.name == 'IDXGIFactory' and method.name == 'QueryInterface':
+ print r' if (riid == IID_IDXGIFactoryDWM) {'
+ print r' _this->AddRef();'
+ print r' *ppvObj = new d3dretrace::CDXGIFactoryDWM(_this);'
+ print r' _result = S_OK;'
+ print r' } else {'
+ Retracer.invokeInterfaceMethod(self, interface, method)
+ print r' }'
+ return
# create windows as neccessary
if method.name == 'CreateSwapChain':
print r' pSharedResource = NULL;'
print r' }'
+ # Force driver
+ if interface.name.startswith('IDXGIFactory') and method.name == 'EnumAdapters':
+ print r' const char *szSoftware = NULL;'
+ print r' switch (retrace::driver) {'
+ print r' case retrace::DRIVER_REFERENCE:'
+ print r' case retrace::DRIVER_SOFTWARE:'
+ print r' szSoftware = "d3d10warp.dll";'
+ print r' break;'
+ print r' case retrace::DRIVER_MODULE:'
+ print r' szSoftware = retrace::driverModule;'
+ print r' break;'
+ print r' default:'
+ print r' break;'
+ print r' }'
+ print r' HMODULE hSoftware = NULL;'
+ print r' if (szSoftware) {'
+ print r' hSoftware = LoadLibraryA(szSoftware);'
+ print r' if (!hSoftware) {'
+ print r' retrace::warning(call) << "failed to load " << szSoftware << "\n";'
+ print r' }'
+ print r' }'
+ print r' if (hSoftware) {'
+ print r' _result = _this->CreateSoftwareAdapter(hSoftware, ppAdapter);'
+ print r' } else {'
+ Retracer.invokeInterfaceMethod(self, interface, method)
+ print r' }'
+ return
+
+ if interface.name.startswith('ID3D10Device') and method.name == 'OpenSharedResource':
+ print r' retrace::warning(call) << "replacing shared resource with checker pattern\n";'
+ print r' D3D10_TEXTURE2D_DESC Desc;'
+ print r' memset(&Desc, 0, sizeof Desc);'
+ print r' Desc.Width = 8;'
+ print r' Desc.Height = 8;'
+ print r' Desc.MipLevels = 1;'
+ print r' Desc.ArraySize = 1;'
+ print r' Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
+ print r' Desc.SampleDesc.Count = 1;'
+ print r' Desc.SampleDesc.Quality = 0;'
+ print r' Desc.Usage = D3D10_USAGE_DEFAULT;'
+ print r' Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;'
+ print r' Desc.CPUAccessFlags = 0x0;'
+ print r' Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;'
+ print r'''
+ const DWORD Checker[8][8] = {
+ { 0, ~0, 0, ~0, 0, ~0, 0, ~0, },
+ {~0, 0, ~0, 0, ~0, 0, ~0, 0, },
+ { 0, ~0, 0, ~0, 0, ~0, 0, ~0, },
+ {~0, 0, ~0, 0, ~0, 0, ~0, 0, },
+ { 0, ~0, 0, ~0, 0, ~0, 0, ~0, },
+ {~0, 0, ~0, 0, ~0, 0, ~0, 0, },
+ { 0, ~0, 0, ~0, 0, ~0, 0, ~0, },
+ {~0, 0, ~0, 0, ~0, 0, ~0, 0, }
+ };
+ const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
+ '''
+ print r' _result = _this->CreateTexture2D(&Desc, &InitialData, (ID3D10Texture2D**)ppResource);'
+ self.checkResult(method.type)
+ return
+
+ if method.name == 'Map':
+ # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
+ # way to cope with it (other than retry).
+ mapFlagsArg = method.getArgByName('MapFlags')
+ for flag in mapFlagsArg.type.values:
+ if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
+ print r' MapFlags &= ~%s;' % flag
+
Retracer.invokeInterfaceMethod(self, interface, method)
# process events after presents
print r' d3dretrace::processEvents();'
if method.name == 'Map':
- print ' VOID *_pbData = NULL;'
- print ' size_t _MappedSize = 0;'
- print ' _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames())
- print ' if (_MappedSize) {'
- print ' _maps[_this] = _pbData;'
+ print ' _MAP_DESC _MapDesc;'
+ print ' _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames())
+ print ' size_t _MappedSize = _MapDesc.Size;'
+ print ' if (_MapDesc.Size) {'
+ print ' _maps[_this] = _MapDesc.pData;'
print ' } else {'
print ' return;'
print ' }'
def main():
+ print r'#define INITGUID'
+ print
print r'#include <string.h>'
print
print r'#include <iostream>'
api = API()
if moduleNames:
+ print r'#include "d3dretrace_dxgi.hpp"'
api.addModule(dxgi)
if 'd3d10' in moduleNames: