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