]> git.cworth.org Git - apitrace/blob - retrace/d3dcommonretrace.py
retrace: Dump call number on exceptions.
[apitrace] / retrace / d3dcommonretrace.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
46         self.table_name = 'd3dretrace::d3d10_callbacks'
47
48         Retracer.retraceApi(self, api)
49
50     createDeviceFunctionNames = [
51         "D3D10CreateDevice",
52         "D3D10CreateDeviceAndSwapChain",
53         "D3D10CreateDevice1",
54         "D3D10CreateDeviceAndSwapChain1",
55         "D3D11CreateDevice",
56         "D3D11CreateDeviceAndSwapChain",
57     ]
58
59     def invokeFunction(self, function):
60         if function.name in self.createDeviceFunctionNames:
61             # create windows as neccessary
62             if 'pSwapChainDesc' in function.argNames():
63                 print r'    pSwapChainDesc->OutputWindow = d3dretrace::createWindow(512, 512);'
64
65             # Compensate for the fact we don't trace the software renderer
66             # module LoadLibrary call
67             if 'Software' in function.argNames():
68                 print r'    if (Software) {'
69                 print r'        retrace::warning(call) << "using WARP for software device\n";'
70                 print r'        Software = LoadLibraryA("d3d10warp");'
71                 print r'    }'
72
73             # Compensate for the fact we don't trace DXGI object creation
74             if function.name.startswith('D3D11CreateDevice'):
75                 print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
76                 print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
77                 print r'    }'
78
79         Retracer.invokeFunction(self, function)
80
81
82     def invokeInterfaceMethod(self, interface, method):
83         # keep track of the last used device for state dumping
84         if interface.name in ('ID3D10Device', 'ID3D10Device1'):
85             if method.name == 'Release':
86                 print r'    d3d10Dumper.unbindDevice(_this);'
87             else:
88                 print r'    d3d10Dumper.bindDevice(_this);'
89         if interface.name in ('ID3D11DeviceContext',):
90             if method.name == 'Release':
91                 print r'    d3d11Dumper.unbindDevice(_this);'
92             else:
93                 print r'    d3d11Dumper.bindDevice(_this);'
94
95         # create windows as neccessary
96         if method.name == 'CreateSwapChain':
97             print r'    pDesc->OutputWindow = d3dretrace::createWindow(512, 512);'
98
99         # notify frame has been completed
100         if method.name == 'Present':
101             print r'    retrace::frameComplete(call);'
102
103         if 'pSharedResource' in method.argNames():
104             print r'    if (pSharedResource) {'
105             print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
106             print r'        pSharedResource = NULL;'
107             print r'    }'
108
109         Retracer.invokeInterfaceMethod(self, interface, method)
110
111         # process events after presents
112         if method.name == 'Present':
113             print r'    d3dretrace::processEvents();'
114
115         if method.name == 'Map':
116             print '    VOID *_pbData = NULL;'
117             print '    size_t _MappedSize = 0;'
118             print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames())
119             print '    if (_MappedSize) {'
120             print '        _maps[_this] = _pbData;'
121             print '    } else {'
122             print '        return;'
123             print '    }'
124         
125         if method.name == 'Unmap':
126             print '    VOID *_pbData = 0;'
127             print '    _pbData = _maps[_this];'
128             print '    if (_pbData) {'
129             print '        retrace::delRegionByPointer(_pbData);'
130             print '        _maps[_this] = 0;'
131             print '    }'
132
133
134 def main():
135     print r'''#include <string.h>'''
136     print
137     print r'#include <iostream>'
138     print
139     print r'#include "d3dretrace.hpp"'
140     print
141
142     moduleNames = sys.argv[1:]
143
144     api = API()
145     
146     if moduleNames:
147         api.addModule(dxgi)
148     
149     if 'd3d10' in moduleNames:
150         if 'd3d10_1' in moduleNames:
151             print r'#include "d3d10_1imports.hpp"'
152             # D3D10CreateBlob is duplicated in d3d10 and d3d10_1
153             d3d10_1.functions = [function for function in d3d10_1.functions if function.name != 'D3D10CreateBlob']
154             api.addModule(d3d10_1)
155         else:
156             print r'#include "d3d10imports.hpp"'
157         print r'#include "d3d10size.hpp"'
158         api.addModule(d3d10)
159         print
160         print '''static d3dretrace::D3DDumper<ID3D10Device> d3d10Dumper;'''
161         print
162
163     if 'd3d11' in moduleNames:
164         print r'#include "d3d11imports.hpp"'
165         if 'd3d11_1' in moduleNames:
166             print '#include <d3d11_1.h>'
167             import specs.d3d11_1
168         print r'#include "d3d11size.hpp"'
169         print r'#include "d3dstate.hpp"'
170         api.addModule(d3d11)
171         
172         print
173         print '''static d3dretrace::D3DDumper<ID3D11DeviceContext> d3d11Dumper;'''
174         print
175
176     retracer = D3DRetracer()
177     retracer.retraceApi(api)
178
179
180 if __name__ == '__main__':
181     main()