]> git.cworth.org Git - apitrace/blob - retrace/dxgiretrace.py
d3dretrace: Use debugging when available.
[apitrace] / retrace / dxgiretrace.py
1 ##########################################################################
2 #
3 # Copyright 2011 Jose Fonseca
4 # All Rights Reserved.
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
23 #
24 ##########################################################################/
25
26
27 """D3D retracer generator."""
28
29
30 import sys
31 from dllretrace import DllRetracer as Retracer
32 from specs.stdapi import API
33 from specs.dxgi import dxgi
34 from specs.d3d10 import d3d10
35 from specs.d3d10_1 import d3d10_1
36 from specs.d3d11 import d3d11
37
38
39 class D3DRetracer(Retracer):
40
41     def retraceApi(self, api):
42         print '// Swizzling mapping for lock addresses'
43         print 'static std::map<void *, void *> _maps;'
44         print
45         print r'''
46 static void 
47 createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
48     if (pSwapChainDesc->Windowed) {
49         UINT Width  = pSwapChainDesc->BufferDesc.Width;
50         UINT Height = pSwapChainDesc->BufferDesc.Height;
51         if (!Width)  Width = 1024;
52         if (!Height) Height = 768;
53         pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height);
54     }
55 }
56 '''
57
58         self.table_name = 'd3dretrace::dxgi_callbacks'
59
60         Retracer.retraceApi(self, api)
61
62     createDeviceFunctionNames = [
63         "D3D10CreateDevice",
64         "D3D10CreateDeviceAndSwapChain",
65         "D3D10CreateDevice1",
66         "D3D10CreateDeviceAndSwapChain1",
67         "D3D11CreateDevice",
68         "D3D11CreateDeviceAndSwapChain",
69     ]
70
71     def invokeFunction(self, function):
72         if function.name in self.createDeviceFunctionNames:
73             # create windows as neccessary
74             if 'pSwapChainDesc' in function.argNames():
75                 print r'    createWindow(pSwapChainDesc);'
76
77             # Compensate for the fact we don't trace DXGI object creation
78             if function.name.startswith('D3D11CreateDevice'):
79                 print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
80                 print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
81                 print r'    }'
82
83             if function.name.startswith('D3D10CreateDevice'):
84                 # Toggle debugging
85                 print r'    Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
86                 print r'    if (retrace::debug) {'
87                 print r'        if (LoadLibraryA("d3d10sdklayers")) {'
88                 print r'            Flags |= D3D10_CREATE_DEVICE_DEBUG;'
89                 print r'        }'
90                 print r'    }'
91
92                 # Force driver
93                 self.forceDriver('D3D10_DRIVER_TYPE')
94
95             if function.name.startswith('D3D11CreateDevice'):
96                 # Toggle debugging
97                 print r'    Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
98                 print r'    if (retrace::debug) {'
99                 print r'        if (LoadLibraryA("d3d11sdklayers")) {'
100                 print r'            Flags |= D3D11_CREATE_DEVICE_DEBUG;'
101                 print r'        }'
102                 print r'    }'
103
104                 # Force driver
105                 self.forceDriver('D3D_DRIVER_TYPE')
106
107         Retracer.invokeFunction(self, function)
108
109     def forceDriver(self, enum):
110         print r'    switch (retrace::driver) {'
111         print r'    case retrace::DRIVER_HARDWARE:'
112         print r'        DriverType = %s_HARDWARE;' % enum
113         print r'        Software = NULL;'
114         print r'        break;'
115         print r'    case retrace::DRIVER_SOFTWARE:'
116         print r'        pAdapter = NULL;'
117         print r'        DriverType = %s_WARP;' % enum
118         print r'        Software = NULL;'
119         print r'        break;'
120         print r'    case retrace::DRIVER_REFERENCE:'
121         print r'        pAdapter = NULL;'
122         print r'        DriverType = %s_REFERENCE;' % enum
123         print r'        Software = NULL;'
124         print r'        break;'
125         print r'    case retrace::DRIVER_NULL:'
126         print r'        pAdapter = NULL;'
127         print r'        DriverType = %s_NULL;' % enum
128         print r'        Software = NULL;'
129         print r'        break;'
130         print r'    case retrace::DRIVER_MODULE:'
131         print r'        pAdapter = NULL;'
132         print r'        DriverType = %s_SOFTWARE;' % enum
133         print r'        Software = LoadLibraryA(retrace::driverModule);'
134         print r'        if (!Software) {'
135         print r'            retrace::warning(call) << "failed to load " << retrace::driverModule << "\n";'
136         print r'        }'
137         print r'        break;'
138         print r'    default:'
139         print r'        assert(0);'
140         print r'        /* fall-through */'
141         print r'    case retrace::DRIVER_DEFAULT:'
142         print r'        if (DriverType == %s_SOFTWARE) {' % enum
143         print r'            Software = LoadLibraryA("d3d10warp");'
144         print r'            if (!Software) {'
145         print r'                retrace::warning(call) << "failed to load d3d10warp.dll\n";'
146         print r'            }'
147         print r'        }'
148         print r'        break;'
149         print r'    }'
150
151     def invokeInterfaceMethod(self, interface, method):
152         # keep track of the last used device for state dumping
153         if interface.name in ('ID3D10Device', 'ID3D10Device1'):
154             if method.name == 'Release':
155                 print r'    d3d10Dumper.unbindDevice(_this);'
156             else:
157                 print r'    d3d10Dumper.bindDevice(_this);'
158         if interface.name in ('ID3D11DeviceContext',):
159             if method.name == 'Release':
160                 print r'    d3d11Dumper.unbindDevice(_this);'
161             else:
162                 print r'    d3d11Dumper.bindDevice(_this);'
163
164         # create windows as neccessary
165         if method.name == 'CreateSwapChain':
166             print r'    createWindow(pDesc);'
167
168         # notify frame has been completed
169         if method.name == 'Present':
170             print r'    retrace::frameComplete(call);'
171
172         if 'pSharedResource' in method.argNames():
173             print r'    if (pSharedResource) {'
174             print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
175             print r'        pSharedResource = NULL;'
176             print r'    }'
177
178         Retracer.invokeInterfaceMethod(self, interface, method)
179
180         # process events after presents
181         if method.name == 'Present':
182             print r'    d3dretrace::processEvents();'
183
184         if method.name == 'Map':
185             print '    VOID *_pbData = NULL;'
186             print '    size_t _MappedSize = 0;'
187             print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames())
188             print '    if (_MappedSize) {'
189             print '        _maps[_this] = _pbData;'
190             print '    } else {'
191             print '        return;'
192             print '    }'
193         
194         if method.name == 'Unmap':
195             print '    VOID *_pbData = 0;'
196             print '    _pbData = _maps[_this];'
197             print '    if (_pbData) {'
198             print '        retrace::delRegionByPointer(_pbData);'
199             print '        _maps[_this] = 0;'
200             print '    }'
201
202         # Attach shader byte code for lookup
203         if 'pShaderBytecode' in method.argNames():
204             ppShader = method.args[-1]
205             assert ppShader.output
206             print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
207             print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
208             print r'    }'
209
210
211 def main():
212     print r'#include <string.h>'
213     print
214     print r'#include <iostream>'
215     print
216     print r'#include "d3dretrace.hpp"'
217     print
218
219     moduleNames = sys.argv[1:]
220
221     api = API()
222     
223     if moduleNames:
224         api.addModule(dxgi)
225     
226     if 'd3d10' in moduleNames:
227         if 'd3d10_1' in moduleNames:
228             print r'#include "d3d10_1imports.hpp"'
229             api.addModule(d3d10_1)
230         else:
231             print r'#include "d3d10imports.hpp"'
232         print r'#include "d3d10size.hpp"'
233         api.addModule(d3d10)
234         print
235         print '''static d3dretrace::D3DDumper<ID3D10Device> d3d10Dumper;'''
236         print
237
238     if 'd3d11' in moduleNames:
239         print r'#include "d3d11imports.hpp"'
240         if 'd3d11_1' in moduleNames:
241             print '#include <d3d11_1.h>'
242             import specs.d3d11_1
243         print r'#include "d3d11size.hpp"'
244         print r'#include "d3dstate.hpp"'
245         api.addModule(d3d11)
246         
247         print
248         print '''static d3dretrace::D3DDumper<ID3D11DeviceContext> d3d11Dumper;'''
249         print
250
251     retracer = D3DRetracer()
252     retracer.retraceApi(api)
253
254
255 if __name__ == '__main__':
256     main()