]> git.cworth.org Git - apitrace/blob - retrace/dxgiretrace.py
d3dretrace: Remove left ofer redundant code.
[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                 self.forceDriver('D3D10_DRIVER_TYPE')
85             if function.name.startswith('D3D11CreateDevice'):
86                 self.forceDriver('D3D_DRIVER_TYPE')
87
88         Retracer.invokeFunction(self, function)
89
90     def forceDriver(self, enum):
91         print r'    switch (retrace::driver) {'
92         print r'    case retrace::DRIVER_HARDWARE:'
93         print r'        DriverType = %s_HARDWARE;' % enum
94         print r'        Software = NULL;'
95         print r'        break;'
96         print r'    case retrace::DRIVER_SOFTWARE:'
97         print r'        pAdapter = NULL;'
98         print r'        DriverType = %s_WARP;' % enum
99         print r'        Software = NULL;'
100         print r'        break;'
101         print r'    case retrace::DRIVER_REFERENCE:'
102         print r'        pAdapter = NULL;'
103         print r'        DriverType = %s_REFERENCE;' % enum
104         print r'        Software = NULL;'
105         print r'        break;'
106         print r'    case retrace::DRIVER_NULL:'
107         print r'        pAdapter = NULL;'
108         print r'        DriverType = %s_NULL;' % enum
109         print r'        Software = NULL;'
110         print r'        break;'
111         print r'    case retrace::DRIVER_MODULE:'
112         print r'        pAdapter = NULL;'
113         print r'        DriverType = %s_SOFTWARE;' % enum
114         print r'        Software = LoadLibraryA(retrace::driverModule);'
115         print r'        if (!Software) {'
116         print r'            retrace::warning(call) << "failed to load " << retrace::driverModule << "\n";'
117         print r'        }'
118         print r'        break;'
119         print r'    default:'
120         print r'        assert(0);'
121         print r'        /* fall-through */'
122         print r'    case retrace::DRIVER_DEFAULT:'
123         print r'        if (DriverType == %s_SOFTWARE) {' % enum
124         print r'            Software = LoadLibraryA("d3d10warp");'
125         print r'            if (!Software) {'
126         print r'                retrace::warning(call) << "failed to load d3d10warp.dll\n";'
127         print r'            }'
128         print r'        }'
129         print r'        break;'
130         print r'    }'
131
132     def invokeInterfaceMethod(self, interface, method):
133         # keep track of the last used device for state dumping
134         if interface.name in ('ID3D10Device', 'ID3D10Device1'):
135             if method.name == 'Release':
136                 print r'    d3d10Dumper.unbindDevice(_this);'
137             else:
138                 print r'    d3d10Dumper.bindDevice(_this);'
139         if interface.name in ('ID3D11DeviceContext',):
140             if method.name == 'Release':
141                 print r'    d3d11Dumper.unbindDevice(_this);'
142             else:
143                 print r'    d3d11Dumper.bindDevice(_this);'
144
145         # create windows as neccessary
146         if method.name == 'CreateSwapChain':
147             print r'    createWindow(pDesc);'
148
149         # notify frame has been completed
150         if method.name == 'Present':
151             print r'    retrace::frameComplete(call);'
152
153         if 'pSharedResource' in method.argNames():
154             print r'    if (pSharedResource) {'
155             print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
156             print r'        pSharedResource = NULL;'
157             print r'    }'
158
159         Retracer.invokeInterfaceMethod(self, interface, method)
160
161         # process events after presents
162         if method.name == 'Present':
163             print r'    d3dretrace::processEvents();'
164
165         if method.name == 'Map':
166             print '    VOID *_pbData = NULL;'
167             print '    size_t _MappedSize = 0;'
168             print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames())
169             print '    if (_MappedSize) {'
170             print '        _maps[_this] = _pbData;'
171             print '    } else {'
172             print '        return;'
173             print '    }'
174         
175         if method.name == 'Unmap':
176             print '    VOID *_pbData = 0;'
177             print '    _pbData = _maps[_this];'
178             print '    if (_pbData) {'
179             print '        retrace::delRegionByPointer(_pbData);'
180             print '        _maps[_this] = 0;'
181             print '    }'
182
183         # Attach shader byte code for lookup
184         if 'pShaderBytecode' in method.argNames():
185             ppShader = method.args[-1]
186             assert ppShader.output
187             print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
188             print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
189             print r'    }'
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             api.addModule(d3d10_1)
211         else:
212             print r'#include "d3d10imports.hpp"'
213         print r'#include "d3d10size.hpp"'
214         api.addModule(d3d10)
215         print
216         print '''static d3dretrace::D3DDumper<ID3D10Device> d3d10Dumper;'''
217         print
218
219     if 'd3d11' in moduleNames:
220         print r'#include "d3d11imports.hpp"'
221         if 'd3d11_1' in moduleNames:
222             print '#include <d3d11_1.h>'
223             import specs.d3d11_1
224         print r'#include "d3d11size.hpp"'
225         print r'#include "d3dstate.hpp"'
226         api.addModule(d3d11)
227         
228         print
229         print '''static d3dretrace::D3DDumper<ID3D11DeviceContext> d3d11Dumper;'''
230         print
231
232     retracer = D3DRetracer()
233     retracer.retraceApi(api)
234
235
236 if __name__ == '__main__':
237     main()