]> git.cworth.org Git - apitrace/blob - retrace/dxgiretrace.py
d3dretrace: Allow to force a driver type.
[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 the software renderer
78             # module LoadLibrary call
79             if 'Software' in function.argNames():
80                 print r'    if (Software) {'
81                 print r'        retrace::warning(call) << "using WARP for software device\n";'
82                 print r'        Software = LoadLibraryA("d3d10warp");'
83                 print r'    }'
84
85             # Compensate for the fact we don't trace DXGI object creation
86             if function.name.startswith('D3D11CreateDevice'):
87                 print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
88                 print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
89                 print r'    }'
90
91             if function.name.startswith('D3D10CreateDevice'):
92                 self.forceDriver('D3D10_DRIVER_TYPE')
93             if function.name.startswith('D3D11CreateDevice'):
94                 self.forceDriver('D3D_DRIVER_TYPE')
95
96         Retracer.invokeFunction(self, function)
97
98     def forceDriver(self, enum):
99         print r'    switch (retrace::driver) {'
100         print r'    case retrace::DRIVER_HARDWARE:'
101         print r'        DriverType = %s_HARDWARE;' % enum
102         print r'        Software = NULL;'
103         print r'        break;'
104         print r'    case retrace::DRIVER_SOFTWARE:'
105         print r'        pAdapter = NULL;'
106         print r'        DriverType = %s_WARP;' % enum
107         print r'        Software = NULL;'
108         print r'        break;'
109         print r'    case retrace::DRIVER_REFERENCE:'
110         print r'        pAdapter = NULL;'
111         print r'        DriverType = %s_REFERENCE;' % enum
112         print r'        Software = NULL;'
113         print r'        break;'
114         print r'    case retrace::DRIVER_NULL:'
115         print r'        pAdapter = NULL;'
116         print r'        DriverType = %s_NULL;' % enum
117         print r'        Software = NULL;'
118         print r'        break;'
119         print r'    case retrace::DRIVER_MODULE:'
120         print r'        pAdapter = NULL;'
121         print r'        DriverType = %s_SOFTWARE;' % enum
122         print r'        Software = LoadLibraryA(retrace::driverModule);'
123         print r'        if (!Software) {'
124         print r'            retrace::warning(call) << "failed to load " << retrace::driverModule << "\n";'
125         print r'        }'
126         print r'        break;'
127         print r'    default:'
128         print r'        assert(0);'
129         print r'        /* fall-through */'
130         print r'    case retrace::DRIVER_DEFAULT:'
131         print r'        if (DriverType == %s_SOFTWARE) {' % enum
132         print r'            Software = LoadLibraryA("d3d10warp");'
133         print r'            if (!Software) {'
134         print r'                retrace::warning(call) << "failed to load d3d10warp.dll\n";'
135         print r'            }'
136         print r'        }'
137         print r'        break;'
138         print r'    }'
139
140     def invokeInterfaceMethod(self, interface, method):
141         # keep track of the last used device for state dumping
142         if interface.name in ('ID3D10Device', 'ID3D10Device1'):
143             if method.name == 'Release':
144                 print r'    d3d10Dumper.unbindDevice(_this);'
145             else:
146                 print r'    d3d10Dumper.bindDevice(_this);'
147         if interface.name in ('ID3D11DeviceContext',):
148             if method.name == 'Release':
149                 print r'    d3d11Dumper.unbindDevice(_this);'
150             else:
151                 print r'    d3d11Dumper.bindDevice(_this);'
152
153         # create windows as neccessary
154         if method.name == 'CreateSwapChain':
155             print r'    createWindow(pDesc);'
156
157         # notify frame has been completed
158         if method.name == 'Present':
159             print r'    retrace::frameComplete(call);'
160
161         if 'pSharedResource' in method.argNames():
162             print r'    if (pSharedResource) {'
163             print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
164             print r'        pSharedResource = NULL;'
165             print r'    }'
166
167         Retracer.invokeInterfaceMethod(self, interface, method)
168
169         # process events after presents
170         if method.name == 'Present':
171             print r'    d3dretrace::processEvents();'
172
173         if method.name == 'Map':
174             print '    VOID *_pbData = NULL;'
175             print '    size_t _MappedSize = 0;'
176             print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames())
177             print '    if (_MappedSize) {'
178             print '        _maps[_this] = _pbData;'
179             print '    } else {'
180             print '        return;'
181             print '    }'
182         
183         if method.name == 'Unmap':
184             print '    VOID *_pbData = 0;'
185             print '    _pbData = _maps[_this];'
186             print '    if (_pbData) {'
187             print '        retrace::delRegionByPointer(_pbData);'
188             print '        _maps[_this] = 0;'
189             print '    }'
190
191
192 def main():
193     print r'#include <string.h>'
194     print
195     print r'#include <iostream>'
196     print
197     print r'#include "d3dretrace.hpp"'
198     print
199
200     moduleNames = sys.argv[1:]
201
202     api = API()
203     
204     if moduleNames:
205         api.addModule(dxgi)
206     
207     if 'd3d10' in moduleNames:
208         if 'd3d10_1' in moduleNames:
209             print r'#include "d3d10_1imports.hpp"'
210             # D3D10CreateBlob is duplicated in d3d10 and d3d10_1
211             d3d10_1.functions = [function for function in d3d10_1.functions if function.name != 'D3D10CreateBlob']
212             api.addModule(d3d10_1)
213         else:
214             print r'#include "d3d10imports.hpp"'
215         print r'#include "d3d10size.hpp"'
216         api.addModule(d3d10)
217         print
218         print '''static d3dretrace::D3DDumper<ID3D10Device> d3d10Dumper;'''
219         print
220
221     if 'd3d11' in moduleNames:
222         print r'#include "d3d11imports.hpp"'
223         if 'd3d11_1' in moduleNames:
224             print '#include <d3d11_1.h>'
225             import specs.d3d11_1
226         print r'#include "d3d11size.hpp"'
227         print r'#include "d3dstate.hpp"'
228         api.addModule(d3d11)
229         
230         print
231         print '''static d3dretrace::D3DDumper<ID3D11DeviceContext> d3d11Dumper;'''
232         print
233
234     retracer = D3DRetracer()
235     retracer.retraceApi(api)
236
237
238 if __name__ == '__main__':
239     main()