José Fonseca | 4106eb4 | 2011-09-21 08:12:39 +0100 | [diff] [blame] | 1 | ########################################################################## |
| 2 | # |
| 3 | # Copyright 2008-2009 VMware, Inc. |
| 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 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 27 | from dlltrace import DllTracer |
José Fonseca | 04ac2fe | 2013-04-25 16:01:48 +0100 | [diff] [blame] | 28 | from specs.stdapi import API, Pointer, ObjPointer |
José Fonseca | e354d8d | 2015-02-06 10:30:01 +0000 | [diff] [blame] | 29 | from specs.d3d9 import d3d9, D3DSHADER9, IDirect3DSwapChain9Ex, d3dperf |
Jose Fonseca | f2a1305 | 2015-07-16 12:56:54 +0100 | [diff] [blame] | 30 | from specs.dxva2 import dxva2 |
José Fonseca | 12ac428 | 2012-07-25 20:47:20 +0100 | [diff] [blame] | 31 | |
José Fonseca | 4106eb4 | 2011-09-21 08:12:39 +0100 | [diff] [blame] | 32 | |
| 33 | class D3D9Tracer(DllTracer): |
| 34 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 35 | def serializeArgValue(self, function, arg): |
José Fonseca | 4106eb4 | 2011-09-21 08:12:39 +0100 | [diff] [blame] | 36 | # Dump shaders as strings |
José Fonseca | 112a132 | 2012-04-27 17:15:32 +0100 | [diff] [blame] | 37 | if arg.type is D3DSHADER9: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 38 | print(' DumpShader(trace::localWriter, %s);' % (arg.name)) |
José Fonseca | 4106eb4 | 2011-09-21 08:12:39 +0100 | [diff] [blame] | 39 | return |
| 40 | |
José Fonseca | 54f304a | 2012-01-14 19:33:08 +0000 | [diff] [blame] | 41 | DllTracer.serializeArgValue(self, function, arg) |
José Fonseca | 4106eb4 | 2011-09-21 08:12:39 +0100 | [diff] [blame] | 42 | |
José Fonseca | 04ac2fe | 2013-04-25 16:01:48 +0100 | [diff] [blame] | 43 | def wrapArg(self, function, arg): |
| 44 | # Correctly handle the wrapping of IDirect3DSwapChain9Ex objects |
| 45 | if function.name in ('GetSwapChain', 'CreateAdditionalSwapChain') \ |
| 46 | and self.interface.name == 'IDirect3DDevice9Ex' \ |
| 47 | and arg.name == 'pSwapChain': |
| 48 | self.wrapValue(Pointer(ObjPointer(IDirect3DSwapChain9Ex)), '((IDirect3DSwapChain9Ex**)pSwapChain)') |
| 49 | return |
| 50 | |
| 51 | DllTracer.wrapArg(self, function, arg) |
| 52 | |
José Fonseca | acc9062 | 2012-05-02 13:10:07 +0100 | [diff] [blame] | 53 | def enumWrapperInterfaceVariables(self, interface): |
| 54 | variables = DllTracer.enumWrapperInterfaceVariables(self, interface) |
José Fonseca | 0423d2c | 2012-01-20 19:16:17 +0000 | [diff] [blame] | 55 | |
José Fonseca | 3dfd457 | 2012-11-03 16:58:34 +0000 | [diff] [blame] | 56 | # Add additional members to track locks |
José Fonseca | 6d5372b | 2012-04-30 23:33:02 +0100 | [diff] [blame] | 57 | if interface.getMethodByName('Lock') is not None or \ |
José Fonseca | 93fa73a | 2012-05-01 22:28:28 +0100 | [diff] [blame] | 58 | interface.getMethodByName('LockRect') is not None or \ |
| 59 | interface.getMethodByName('LockBox') is not None: |
Jose Fonseca | ef26cb8 | 2016-04-27 11:58:18 +0100 | [diff] [blame] | 60 | if interface.base.name == 'IDirect3DBaseTexture9': |
Pavel Ilin | e540b63 | 2014-10-12 15:09:57 +0300 | [diff] [blame] | 61 | variables += [ |
| 62 | ('std::map<UINT, std::pair<size_t, VOID *> >', '_MappedData', 'std::map<UINT, std::pair<size_t, VOID *> >()'), |
| 63 | ] |
| 64 | else: |
| 65 | variables += [ |
| 66 | ('size_t', '_MappedSize', '0'), |
| 67 | ('VOID *', 'm_pbData', '0'), |
| 68 | ] |
José Fonseca | 0423d2c | 2012-01-20 19:16:17 +0000 | [diff] [blame] | 69 | |
Jose Fonseca | f675727 | 2016-05-13 07:23:45 -0700 | [diff] [blame] | 70 | if interface.name == 'IDirectXVideoDecoder': |
| 71 | variables += [ |
| 72 | ('std::map<UINT, std::pair<void *, UINT> >', '_MappedData', None), |
| 73 | ] |
| 74 | |
José Fonseca | acc9062 | 2012-05-02 13:10:07 +0100 | [diff] [blame] | 75 | return variables |
José Fonseca | d275d0a | 2012-04-30 23:18:05 +0100 | [diff] [blame] | 76 | |
José Fonseca | 4220b1b | 2012-02-03 19:05:29 +0000 | [diff] [blame] | 77 | def implementWrapperInterfaceMethodBody(self, interface, base, method): |
José Fonseca | 93fa73a | 2012-05-01 22:28:28 +0100 | [diff] [blame] | 78 | if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): |
Jose Fonseca | ef26cb8 | 2016-04-27 11:58:18 +0100 | [diff] [blame] | 79 | if interface.base.name == 'IDirect3DBaseTexture9': |
| 80 | assert method.getArgByName('Level') is not None |
Jose Fonseca | a0cd097 | 2017-06-01 13:29:35 +0100 | [diff] [blame] | 81 | if method.getArgByName('FaceType'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 82 | print(r' UINT _Key = static_cast<UINT>(FaceType) + Level*6;') |
Jose Fonseca | a0cd097 | 2017-06-01 13:29:35 +0100 | [diff] [blame] | 83 | else: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 84 | print(r' UINT _Key = Level;') |
| 85 | print(' std::map<UINT, std::pair<size_t, VOID *> >::iterator it = _MappedData.find(_Key);') |
| 86 | print(' if (it != _MappedData.end()) {') |
Pavel Ilin | e540b63 | 2014-10-12 15:09:57 +0300 | [diff] [blame] | 87 | self.emit_memcpy('(LPBYTE)it->second.second', 'it->second.first') |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 88 | print(' _MappedData.erase(it);') |
| 89 | print(' }') |
Pavel Ilin | e540b63 | 2014-10-12 15:09:57 +0300 | [diff] [blame] | 90 | else: |
Jose Fonseca | ef26cb8 | 2016-04-27 11:58:18 +0100 | [diff] [blame] | 91 | assert method.getArgByName('Level') is None |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 92 | print(' if (_MappedSize && m_pbData) {') |
Pavel Ilin | e540b63 | 2014-10-12 15:09:57 +0300 | [diff] [blame] | 93 | self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 94 | print(' }') |
José Fonseca | 0423d2c | 2012-01-20 19:16:17 +0000 | [diff] [blame] | 95 | |
Jose Fonseca | f675727 | 2016-05-13 07:23:45 -0700 | [diff] [blame] | 96 | if interface.name == 'IDirectXVideoDecoder' and method.name == 'ReleaseBuffer': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 97 | print(' std::map<UINT, std::pair<void *, UINT> >::iterator it = _MappedData.find(BufferType);') |
| 98 | print(' if (it != _MappedData.end()) {') |
Jose Fonseca | f675727 | 2016-05-13 07:23:45 -0700 | [diff] [blame] | 99 | self.emit_memcpy('it->second.first', 'it->second.second') |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 100 | print(' _MappedData.erase(it);') |
| 101 | print(' }') |
Jose Fonseca | f675727 | 2016-05-13 07:23:45 -0700 | [diff] [blame] | 102 | |
José Fonseca | 4220b1b | 2012-02-03 19:05:29 +0000 | [diff] [blame] | 103 | DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) |
José Fonseca | 0423d2c | 2012-01-20 19:16:17 +0000 | [diff] [blame] | 104 | |
José Fonseca | 6c77bd0 | 2012-05-02 13:15:39 +0100 | [diff] [blame] | 105 | if method.name in ('Lock', 'LockRect', 'LockBox'): |
Jose Fonseca | ef26cb8 | 2016-04-27 11:58:18 +0100 | [diff] [blame] | 106 | if interface.base.name == 'IDirect3DBaseTexture9': |
| 107 | assert method.getArgByName('Level') is not None |
Jose Fonseca | a0cd097 | 2017-06-01 13:29:35 +0100 | [diff] [blame] | 108 | if method.getArgByName('FaceType'): |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 109 | print(r' UINT _Key = static_cast<UINT>(FaceType) + Level*6;') |
Jose Fonseca | a0cd097 | 2017-06-01 13:29:35 +0100 | [diff] [blame] | 110 | else: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 111 | print(r' UINT _Key = Level;') |
| 112 | print(' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {') |
| 113 | print(' size_t mappedSize;') |
| 114 | print(' VOID * pbData;') |
| 115 | print(' _getMapInfo(_this, %s, pbData, mappedSize);' % ', '.join(method.argNames()[:-1])) |
| 116 | print(' _MappedData[_Key] = std::make_pair(mappedSize, pbData);') |
| 117 | print(' } else {') |
| 118 | print(' _MappedData.erase(_Key);') |
| 119 | print(' }') |
Pavel Ilin | e540b63 | 2014-10-12 15:09:57 +0300 | [diff] [blame] | 120 | else: |
| 121 | # FIXME: handle recursive locks |
Jose Fonseca | ef26cb8 | 2016-04-27 11:58:18 +0100 | [diff] [blame] | 122 | assert method.getArgByName('Level') is None |
Jose Fonseca | c4fb8c9 | 2016-04-27 12:06:19 +0100 | [diff] [blame] | 123 | if method.name == 'Lock': |
| 124 | # Ignore D3DLOCK_READONLY for buffers. |
| 125 | # https://github.com/apitrace/apitrace/issues/435 |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 126 | print(' if (SUCCEEDED(_result)) {') |
Jose Fonseca | c4fb8c9 | 2016-04-27 12:06:19 +0100 | [diff] [blame] | 127 | else: |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 128 | print(' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {') |
| 129 | print(' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])) |
| 130 | print(' } else {') |
| 131 | print(' m_pbData = NULL;') |
| 132 | print(' _MappedSize = 0;') |
| 133 | print(' }') |
José Fonseca | 0423d2c | 2012-01-20 19:16:17 +0000 | [diff] [blame] | 134 | |
Jose Fonseca | f675727 | 2016-05-13 07:23:45 -0700 | [diff] [blame] | 135 | if interface.name == 'IDirectXVideoDecoder' and method.name == 'GetBuffer': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 136 | print(' if (SUCCEEDED(_result)) {') |
| 137 | print(' _MappedData[BufferType] = std::make_pair(*ppBuffer, *pBufferSize);') |
| 138 | print(' } else {') |
| 139 | print(' _MappedData[BufferType] = std::make_pair(nullptr, 0);') |
| 140 | print(' }') |
Jose Fonseca | f675727 | 2016-05-13 07:23:45 -0700 | [diff] [blame] | 141 | |
José Fonseca | 4106eb4 | 2011-09-21 08:12:39 +0100 | [diff] [blame] | 142 | |
| 143 | if __name__ == '__main__': |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 144 | print('#define INITGUID') |
| 145 | print() |
| 146 | print('#include "trace_writer_local.hpp"') |
| 147 | print('#include "os.hpp"') |
| 148 | print() |
| 149 | print('#include "d3d9imports.hpp"') |
| 150 | print('#include "d3d9size.hpp"') |
| 151 | print('#include "d3d9shader.hpp"') |
| 152 | print('#include "dxva2imports.hpp"') |
| 153 | print() |
José Fonseca | 4106eb4 | 2011-09-21 08:12:39 +0100 | [diff] [blame] | 154 | |
José Fonseca | e354d8d | 2015-02-06 10:30:01 +0000 | [diff] [blame] | 155 | d3d9.mergeModule(d3dperf) |
| 156 | |
José Fonseca | 72fb9ca | 2012-11-13 08:21:15 +0000 | [diff] [blame] | 157 | api = API() |
| 158 | api.addModule(d3d9) |
Jose Fonseca | f2a1305 | 2015-07-16 12:56:54 +0100 | [diff] [blame] | 159 | api.addModule(dxva2) |
José Fonseca | 72fb9ca | 2012-11-13 08:21:15 +0000 | [diff] [blame] | 160 | tracer = D3D9Tracer() |
| 161 | tracer.traceApi(api) |
Jose Fonseca | 80dc846 | 2018-12-28 14:31:07 +0000 | [diff] [blame] | 162 | |
Piotr Podsiadły | 0b8b019 | 2019-01-03 20:39:55 +0100 | [diff] [blame] | 163 | print(r'EXTERN_C PUBLIC') |
| 164 | print(r'void __stdcall Direct3D9ForceHybridEnumeration(UINT uHybrid) {') |
| 165 | print(r' typedef void (WINAPI *PFNDIRECT3D9FORCEHYBRIDENUMERATION)(UINT);') |
| 166 | print(r' PFNDIRECT3D9FORCEHYBRIDENUMERATION pfnDirect3D9ForceHybridEnumeration =') |
| 167 | print(r' (PFNDIRECT3D9FORCEHYBRIDENUMERATION)g_modD3D9.getProcAddress(MAKEINTRESOURCEA(16));') |
| 168 | print(r' if (pfnDirect3D9ForceHybridEnumeration) {') |
| 169 | print(r' pfnDirect3D9ForceHybridEnumeration(uHybrid);') |
| 170 | print(r' } else {') |
| 171 | print(r' os::log("warning: ignoring call to unavailable function %s\n", __FUNCTION__);') |
| 172 | print(r' }') |
| 173 | print(r'}') |
| 174 | print() |