def invokeMethod(self, interface, base, method): DllTracer.invokeMethod(self, interface, base, method) # When D2D is used on top of WARP software rasterizer it seems to do # most of its rendering via the undocumented and opaque IWarpPrivateAPI # interface. Althought hiding this interface will affect behavior, # there's little point in traces that use it, as they lack enough # information to replay correctly. # # Returning E_NOINTERFACE when for IID_IWarpPrivateAPI matches what # happens when D2D is used with drivers other than WARP. if method.name == 'QueryInterface': print r' if (_result == S_OK && riid == IID_IWarpPrivateAPI && ppvObj && *ppvObj) {' print r' static_cast<IUnknown *>(*ppvObj)->Release();' print r' *ppvObj = nullptr;' print r' _result = E_NOINTERFACE;' print r' os::log("apitrace: warning: hiding IWarpPrivateAPI interface\n");' print r' }' # Ensure buffers are initialized, otherwise we can fail to detect # changes when unititialized data matches what the app wrote. if method.name == 'CreateBuffer': print r' if (SUCCEEDED(_result) && !pInitialData) {' print r' _initializeBuffer(_this, pDesc, *ppBuffer);' print r' }'
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Map', 'Unmap'): # On D3D11 Map/Unmap is not a resource method, but a context method instead. resourceArg = method.getArgByName('pResource') if resourceArg is None: print ' _MAP_DESC & _MapDesc = m_MapDesc;' else: print ' _MAP_DESC & _MapDesc = m_MapDescs[std::pair<%s, UINT>(pResource, Subresource)];' % resourceArg.type if method.name == 'Unmap': print ' if (_MapDesc.Size && _MapDesc.pData) {' self.emit_memcpy('_MapDesc.pData', '_MapDesc.Size') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print ' if (SUCCEEDED(_result)) {' print ' _getMapDesc(_this, %s, _MapDesc);' % ', '.join( method.argNames()) print ' } else {' print ' _MapDesc.pData = NULL;' print ' _MapDesc.Size = 0;' print ' }'
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.getArgByName('pInitialData'): pDesc1 = method.getArgByName('pDesc1') if pDesc1 is not None: print r' %s pDesc = pDesc1;' % (pDesc1.type,) if method.name in ('Map', 'Unmap'): # On D3D11 Map/Unmap is not a resource method, but a context method instead. resourceArg = method.getArgByName('pResource') if resourceArg is None: print ' _MAP_DESC & _MapDesc = m_MapDesc;' else: print ' _MAP_DESC & _MapDesc = m_MapDescs[std::pair<%s, UINT>(pResource, Subresource)];' % resourceArg.type if method.name == 'Unmap': print ' if (_MapDesc.Size && _MapDesc.pData) {' self.emit_memcpy('_MapDesc.pData', '_MapDesc.Size') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print ' if (SUCCEEDED(_result)) {' print ' _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames()) print ' } else {' print ' _MapDesc.pData = NULL;' print ' _MapDesc.Size = 0;' print ' }'
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Map', 'Unmap'): # On D3D11 Map/Unmap is not a resource method, but a context method instead. resourceArg = method.getArgByName('pResource') if resourceArg is None: pResource = 'this' else: wrapperInterfaceName = getWrapperInterfaceName(resourceArg.type.type) print ' %s * _pResource = static_cast<%s*>(%s);' % (wrapperInterfaceName, wrapperInterfaceName, resourceArg.name) pResource = '_pResource' if method.name == 'Unmap': print ' _MAP_DESC _MapDesc = %s->_MapDesc;' % pResource #print r' os::log("%%p -> %%p+%%lu\n", %s,_MapDesc.pData, (unsigned long)_MapDesc.Size);' % pResource print ' if (_MapDesc.Size && _MapDesc.pData) {' self.emit_memcpy('_MapDesc.pData', '_MapDesc.Size') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print ' _MAP_DESC _MapDesc;' print ' if (SUCCEEDED(_result)) {' print ' _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames()) print ' } else {' print ' _MapDesc.pData = NULL;' print ' _MapDesc.Size = 0;' print ' }' #print r' os::log("%%p <- %%p+%%lu\n", %s,_MapDesc.pData, (unsigned long)_MapDesc.Size);' % pResource print ' %s->_MapDesc = _MapDesc;' % pResource
def serializeArgValue(self, function, arg): # Dump shaders as strings if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'): print ' DumpShader(trace::localWriter, %s, %s);' % (arg.name, arg.type.size) return DllTracer.serializeArgValue(self, function, arg)
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): print ' if (_MappedSize && m_pbData) {' self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name in ('Lock', 'LockRect', 'LockBox'): # FIXME: handle recursive locks print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join(method.argNames()[:-1]) print ' } else {' print ' m_pbData = NULL;' print ' _MappedSize = 0;' print ' }' # Clamp capabilities if method.name == 'GetDeviceCaps': print ' if (SUCCEEDED(_result)) {' print ' clampCaps(pCaps);' print ' }' if method.name == 'CheckDeviceFormat': print ' if (SUCCEEDED(_result)) {' print ' if (!clampFormat(Usage, RType, CheckFormat)) {' print ' _result = D3DERR_NOTAVAILABLE;' print ' }' print ' }' if method.name == 'CheckDeviceMultiSampleType': print ' if (SUCCEEDED(_result)) {' print ' if (!clampMultiSampleType(SurfaceFormat, MultiSampleType, pQualityLevels)) {' print ' _result = D3DERR_NOTAVAILABLE;' print ' }' print ' }'
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.getArgByName('pInitialData'): pDesc1 = method.getArgByName('pDesc1') if pDesc1 is not None: print r' %s pDesc = pDesc1;' % (pDesc1.type,) if method.name in ('Map', 'Unmap'): # On D3D11 Map/Unmap is not a resource method, but a context method instead. resourceArg = method.getArgByName('pResource') if resourceArg is None: print ' _MAP_DESC & _MapDesc = m_MapDesc;' print ' MemoryShadow & _MapShadow = m_MapShadow;' print ' %s *pResourceInstance = m_pInstance;' % interface.name else: print ' _MAP_DESC & _MapDesc = m_MapDescs[std::pair<%s, UINT>(pResource, Subresource)];' % resourceArg.type print ' MemoryShadow & _MapShadow = m_MapShadows[std::pair<%s, UINT>(pResource, Subresource)];' % resourceArg.type print ' Wrap%spResourceInstance = static_cast<Wrap%s>(%s);' % (resourceArg.type, resourceArg.type, resourceArg.name) if method.name == 'Unmap': print ' if (_MapDesc.Size && _MapDesc.pData) {' print ' if (_shouldShadowMap(pResourceInstance)) {' print ' _MapShadow.update(trace::fakeMemcpy);' print ' } else {' self.emit_memcpy('_MapDesc.pData', '_MapDesc.Size') print ' }' print ' }' if interface.hasBase(d3d11.ID3D11VideoContext) and \ method.name == 'ReleaseDecoderBuffer': print ' std::map<UINT, std::pair<void *, UINT> >::iterator it = m_MapDesc.find(Type);' print ' if (it != m_MapDesc.end()) {' self.emit_memcpy('it->second.first', 'it->second.second') print ' m_MapDesc.erase(it);' print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print ' if (SUCCEEDED(_result)) {' print ' _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames()) print ' if (_MapDesc.pData && _shouldShadowMap(pResourceInstance)) {' if interface.name.startswith('IDXGI'): print ' (void)_MapShadow;' else: print ' bool _discard = MapType == 4 /* D3D1[01]_MAP_WRITE_DISCARD */;' print ' _MapShadow.cover(_MapDesc.pData, _MapDesc.Size, _discard);' print ' }' print ' } else {' print ' _MapDesc.pData = NULL;' print ' _MapDesc.Size = 0;' print ' }' if interface.hasBase(d3d11.ID3D11VideoContext) and \ method.name == 'GetDecoderBuffer': print ' if (SUCCEEDED(_result)) {' print ' m_MapDesc[Type] = std::make_pair(*ppBuffer, *pBufferSize);' print ' } else {' print ' m_MapDesc[Type] = std::make_pair(nullptr, 0);' print ' }'
def serializeArgValue(self, function, arg): # Dump shaders as strings if arg.type is D3DSHADER8: print(' DumpShader(trace::localWriter, %s);' % (arg.name)) return DllTracer.serializeArgValue(self, function, arg)
def serializeArgValue(self, function, arg): # Dump shaders as strings if arg.type is D3DSHADER9: print ' DumpShader(trace::localWriter, %s);' % (arg.name) return DllTracer.serializeArgValue(self, function, arg)
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): if interface.name in ['IDirect3DTexture9']: print ' std::map<UINT, std::pair<size_t, VOID *> >::iterator it = _MappedData.find(Level);' print ' if (it != _MappedData.end()) {' self.emit_memcpy('(LPBYTE)it->second.second', 'it->second.first') print ' _MappedData.erase(it);' print ' }' else: print ' if (_MappedSize && m_pbData) {' self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name in ('Lock', 'LockRect', 'LockBox'): if interface.name in ['IDirect3DTexture9']: print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' size_t mappedSize;' print ' VOID * pbData;' print ' _getMapInfo(_this, %s, pbData, mappedSize);' % ', '.join(method.argNames()[:-1]) print ' _MappedData[Level] = std::make_pair(mappedSize, pbData);' print ' } else {' print ' _MappedData.erase(Level);' print ' }' else: # FIXME: handle recursive locks print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join(method.argNames()[:-1]) print ' } else {' print ' m_pbData = NULL;' print ' _MappedSize = 0;' print ' }'
def serializeArgValue(self, function, arg): # Dump shaders as strings if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction': print ' DumpShader(trace::localWriter, %s);' % (arg.name) return DllTracer.serializeArgValue(self, function, arg)
def serializeArgValue(self, function, arg): # Dump shaders as strings if function.name in ("CreateVertexShader", "CreatePixelShader") and arg.name == "pFunction": print " DumpShader(trace::localWriter, %s);" % (arg.name) return DllTracer.serializeArgValue(self, function, arg)
def wrapArg(self, function, arg): # Correctly handle the wrapping of IDirect3DSwapChain9Ex objects if function.name in ('GetSwapChain', 'CreateAdditionalSwapChain') \ and self.interface.name == 'IDirect3DDevice9Ex' \ and arg.name == 'pSwapChain': self.wrapValue(Pointer(ObjPointer(IDirect3DSwapChain9Ex)), '((IDirect3DSwapChain9Ex**)pSwapChain)') return DllTracer.wrapArg(self, function, arg)
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): if interface.base.name == 'IDirect3DBaseTexture9': assert method.getArgByName('Level') is not None print ' std::map<UINT, std::pair<size_t, VOID *> >::iterator it = _MappedData.find(Level);' print ' if (it != _MappedData.end()) {' self.emit_memcpy('(LPBYTE)it->second.second', 'it->second.first') print ' _MappedData.erase(it);' print ' }' else: assert method.getArgByName('Level') is None print ' if (_MappedSize && m_pbData) {' self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') print ' }' if interface.name == 'IDirectXVideoDecoder' and method.name == 'ReleaseBuffer': print ' std::map<UINT, std::pair<void *, UINT> >::iterator it = _MappedData.find(BufferType);' print ' if (it != _MappedData.end()) {' self.emit_memcpy('it->second.first', 'it->second.second') print ' _MappedData.erase(it);' print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name in ('Lock', 'LockRect', 'LockBox'): if interface.base.name == 'IDirect3DBaseTexture9': assert method.getArgByName('Level') is not None print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' size_t mappedSize;' print ' VOID * pbData;' print ' _getMapInfo(_this, %s, pbData, mappedSize);' % ', '.join(method.argNames()[:-1]) print ' _MappedData[Level] = std::make_pair(mappedSize, pbData);' print ' } else {' print ' _MappedData.erase(Level);' print ' }' else: # FIXME: handle recursive locks assert method.getArgByName('Level') is None if method.name == 'Lock': # Ignore D3DLOCK_READONLY for buffers. # https://github.com/apitrace/apitrace/issues/435 print ' if (SUCCEEDED(_result)) {' else: print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join(method.argNames()[:-1]) print ' } else {' print ' m_pbData = NULL;' print ' _MappedSize = 0;' print ' }' if interface.name == 'IDirectXVideoDecoder' and method.name == 'GetBuffer': print ' if (SUCCEEDED(_result)) {' print ' _MappedData[BufferType] = std::make_pair(*ppBuffer, *pBufferSize);' print ' } else {' print ' _MappedData[BufferType] = std::make_pair(nullptr, 0);' print ' }'
def invokeMethod(self, interface, base, method): if method.name == 'CreateBuffer': if interface.name.startswith('ID3D11'): print(r' D3D11_SUBRESOURCE_DATA initialData;') else: print(r' D3D10_SUBRESOURCE_DATA initialData;') print(r' if (!pInitialData) {') print(r' pInitialData = &initialData;') print(r' _initialBufferAlloc(pDesc, &initialData);') print(r' }') DllTracer.invokeMethod(self, interface, base, method) # When D2D is used on top of WARP software rasterizer it seems to do # most of its rendering via the undocumented and opaque IWarpPrivateAPI # interface. Althought hiding this interface will affect behavior, # there's little point in traces that use it, as they lack enough # information to replay correctly. # # Returning E_NOINTERFACE when for IID_IWarpPrivateAPI matches what # happens when D2D is used with drivers other than WARP. if method.name == 'QueryInterface': print( r' if (_result == S_OK && riid == IID_IWarpPrivateAPI && ppvObj && *ppvObj) {' ) print(r' static_cast<IUnknown *>(*ppvObj)->Release();') print(r' *ppvObj = nullptr;') print(r' _result = E_NOINTERFACE;') print( r' os::log("apitrace: warning: hiding IWarpPrivateAPI interface\n");' ) print(r' }') if interface.name.startswith( 'ID3D11Device') and method.name == 'CheckFeatureSupport': print(r' if (FORCE_D3D_FEATURE_LEVEL_11_0 &&') print(r' _result == S_OK &&') print(r' Feature >= D3D11_FEATURE_D3D11_OPTIONS) {') print( r' ZeroMemory(pFeatureSupportData, FeatureSupportDataSize);' ) print(r' }') if method.name == 'CheckMultisampleQualityLevels': print(r' if (FORCE_D3D_FEATURE_LEVEL_11_0 &&') print(r' _result == S_OK &&') print(r' pNumQualityLevels && *pNumQualityLevels > 1) {') print(r' *pNumQualityLevels = 1;') print(r' }') # Ensure buffers are initialized, otherwise we can fail to detect # changes when unititialized data matches what the app wrote. if method.name == 'CreateBuffer': print(r' if (pInitialData == &initialData) {') print(r' _initialBufferFree(&initialData);') print(r' }')
def serializeArg(self, function, arg): if function.name == 'DirectDrawCreateEx' and arg.name == 'lplpDD': print ' if (*lplpDD) {' for iface in interfaces: print ' if (iid == IID_%s) {' % iface.name print ' *lplpDD = (LPVOID) new Wrap%s((%s *)*lplpDD);' % (iface.name, iface.name) print ' }' print ' }' DllTracer.serializeArg(self, function, arg)
def serializeArgValue(self, function, arg): # Dump shaders as strings if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'): print ' DumpShader(trace::localWriter, %s, %s);' % ( arg.name, arg.type.size) return # Serialize the swapchain dimensions if function.name == 'CreateSwapChain' and arg.name == 'pDesc' \ or arg.name == 'pSwapChainDesc': print r' DXGI_SWAP_CHAIN_DESC *_pSwapChainDesc = NULL;' print r' DXGI_SWAP_CHAIN_DESC _SwapChainDesc;' print r' if (%s) {' % arg.name print r' _SwapChainDesc = *%s;' % arg.name if function.name != 'CreateSwapChain' or not self.interface.name.endswith( 'DWM'): # Obtain size from the window print r' RECT _rect;' print r' if (GetClientRect(%s->OutputWindow, &_rect)) {' % arg.name print r' if (%s->BufferDesc.Width == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Width = _rect.right - _rect.left;' print r' }' print r' if (%s->BufferDesc.Height == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Height = _rect.bottom - _rect.top;' print r' }' print r' }' else: # Obtain size from the output print r' DXGI_OUTPUT_DESC _OutputDesc;' print r' if (SUCCEEDED(pOutput->GetDesc(&_OutputDesc))) {' print r' _SwapChainDesc.BufferDesc.Width = _OutputDesc.DesktopCoordinates.right - _OutputDesc.DesktopCoordinates.left;' print r' _SwapChainDesc.BufferDesc.Height = _OutputDesc.DesktopCoordinates.bottom - _OutputDesc.DesktopCoordinates.top;' print r' }' print r' _pSwapChainDesc = &_SwapChainDesc;' print r' }' self.serializeValue(arg.type, '_pSwapChainDesc') return # Serialize object names # http://blogs.msdn.com/b/chuckw/archive/2010/04/15/object-naming.aspx if function.name == 'SetPrivateData' and arg.name == 'pData': iid = function.args[0].name print r' if (%s == WKPDID_D3DDebugObjectName) {' % iid print r' trace::localWriter.writeString(static_cast<const char *>(pData), DataSize);' print r' } else {' DllTracer.serializeArgValue(self, function, arg) print r' }' return DllTracer.serializeArgValue(self, function, arg)
def serializeArgValue(self, function, arg): # Dump shaders as strings if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'): print ' DumpShader(trace::localWriter, %s, %s);' % (arg.name, arg.type.size) return # Serialize the swapchain dimensions if function.name == 'CreateSwapChain' and arg.name == 'pDesc' \ or arg.name == 'pSwapChainDesc': print r' DXGI_SWAP_CHAIN_DESC *_pSwapChainDesc = NULL;' print r' DXGI_SWAP_CHAIN_DESC _SwapChainDesc;' print r' if (%s) {' % arg.name print r' _SwapChainDesc = *%s;' % arg.name if function.name != 'CreateSwapChain' or not self.interface.name.endswith('DWM'): # Obtain size from the window print r' RECT _rect;' print r' if (GetClientRect(%s->OutputWindow, &_rect)) {' % arg.name print r' if (%s->BufferDesc.Width == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Width = _rect.right - _rect.left;' print r' }' print r' if (%s->BufferDesc.Height == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Height = _rect.bottom - _rect.top;' print r' }' print r' }' else: # Obtain size from the output print r' DXGI_OUTPUT_DESC _OutputDesc;' print r' if (SUCCEEDED(pOutput->GetDesc(&_OutputDesc))) {' print r' _SwapChainDesc.BufferDesc.Width = _OutputDesc.DesktopCoordinates.right - _OutputDesc.DesktopCoordinates.left;' print r' _SwapChainDesc.BufferDesc.Height = _OutputDesc.DesktopCoordinates.bottom - _OutputDesc.DesktopCoordinates.top;' print r' }' print r' _pSwapChainDesc = &_SwapChainDesc;' print r' }' self.serializeValue(arg.type, '_pSwapChainDesc') return # Serialize object names # http://blogs.msdn.com/b/chuckw/archive/2010/04/15/object-naming.aspx if function.name == 'SetPrivateData' and arg.name == 'pData': iid = function.args[0].name print r' if (%s == WKPDID_D3DDebugObjectName) {' % iid print r' trace::localWriter.writeString(static_cast<const char *>(pData), DataSize);' print r' } else {' DllTracer.serializeArgValue(self, function, arg) print r' }' return DllTracer.serializeArgValue(self, function, arg)
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name == 'Unmap': print ' if (_MappedSize && _pMappedData) {' self.emit_memcpy('_pMappedData', '_pMappedData', '_MappedSize') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print ' if (SUCCEEDED(_result)) {' print ' _getMapInfo(_this, %s, _pMappedData, _MappedSize);' % ', '.join(method.argNames()) print ' } else {' print ' _pMappedData = NULL;' print ' _MappedSize = 0;' print ' }'
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): print ' if (_MappedSize && m_pbData) {' self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name in ('Lock', 'LockRect', 'LockBox'): # FIXME: handle recursive locks print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join(method.argNames()[:-1]) print ' } else {' print ' m_pbData = NULL;' print ' _MappedSize = 0;' print ' }'
def enumWrapperInterfaceVariables(self, interface): variables = DllTracer.enumWrapperInterfaceVariables(self, interface) # Add additional members to track locks if interface.getMethodByName('Lock') is not None or \ interface.getMethodByName('LockRect') is not None or \ interface.getMethodByName('LockBox') is not None: if interface.base.name == 'IDirect3DBaseTexture9': variables += [ ('std::map<UINT, std::pair<size_t, VOID *> >', '_MappedData', 'std::map<UINT, std::pair<size_t, VOID *> >()'), ] else: variables += [ ('size_t', '_MappedSize', '0'), ('VOID *', 'm_pbData', '0'), ] if interface.name == 'IDirectXVideoDecoder': variables += [ ('std::map<UINT, std::pair<void *, UINT> >', '_MappedData', None), ] return variables
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): print(' if (_MappedSize && m_pbData) {') self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') print(' }') DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name in ('Lock', 'LockRect', 'LockBox'): # FIXME: handle recursive locks print(' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {') print(' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])) print(' } else {') print(' m_pbData = NULL;') print(' _MappedSize = 0;') print(' }')
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name == 'Unmap': print ' if (_MappedSize && _pMappedData) {' self.emit_memcpy('_pMappedData', '_pMappedData', '_MappedSize') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print ' if (SUCCEEDED(_result)) {' print ' _getMapInfo(_this, %s, _pMappedData, _MappedSize);' % ', '.join( method.argNames()) print ' } else {' print ' _pMappedData = NULL;' print ' _MappedSize = 0;' print ' }'
def invokeMethod(self, interface, base, method): DllTracer.invokeMethod(self, interface, base, method) # When D2D is used on top of WARP software rasterizer it seems to do # most of its rendering via the undocumented and opaque IWarpPrivateAPI # interface. Althought hiding this interface will affect behavior, # there's little point in traces that use it, as they lack enough # information to replay correctly. # # Returning E_NOINTERFACE when for IID_IWarpPrivateAPI matches what # happens when D2D is used with drivers other than WARP. if method.name == 'QueryInterface': print r' if (_result == S_OK && riid == IID_IWarpPrivateAPI && ppvObj && *ppvObj) {' print r' static_cast<IUnknown *>(*ppvObj)->Release();' print r' *ppvObj = nullptr;' print r' _result = E_NOINTERFACE;' print r' os::log("apitrace: warning: hiding IWarpPrivateAPI interface\n");' print r' }'
def enumWrapperInterfaceVariables(self, interface): variables = DllTracer.enumWrapperInterfaceVariables(self, interface) # Add additional members to track maps if interface.hasBase(*self.mapInterfaces): variables += [ ('_MAP_DESC', '_MapDesc', None), ] return variables
def enumWrapperInterfaceVariables(self, interface): variables = DllTracer.enumWrapperInterfaceVariables(self, interface) # Add additional members to track maps if interface.getMethodByName('Map') is not None: variables += [ ('VOID *', '_pMappedData', '0'), ('size_t', '_MappedSize', '0'), ] return variables
def enumWrapperInterfaceVariables(self, interface): variables = DllTracer.enumWrapperInterfaceVariables(self, interface) if interface.getMethodByName('Lock') is not None or \ interface.getMethodByName('LockRect') is not None or \ interface.getMethodByName('LockBox') is not None: variables += [ ('size_t', '_LockedSize', '0'), ('VOID *', 'm_pbData', '0'), ] return variables
def serializeArgValue(self, function, arg): # Dump shaders as strings if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'): print ' DumpShader(trace::localWriter, %s, %s);' % ( arg.name, arg.type.size) return # Serialize the swapchain dimensions if function.name == 'CreateSwapChain' and arg.name == 'pDesc' \ or arg.name == 'pSwapChainDesc': print r' DXGI_SWAP_CHAIN_DESC *_pSwapChainDesc = NULL;' print r' DXGI_SWAP_CHAIN_DESC _SwapChainDesc;' print r' if (%s) {' % arg.name print r' _SwapChainDesc = *%s;' % arg.name if function.name != 'CreateSwapChain' or not self.interface.name.endswith( 'DWM'): # Obtain size from the window print r' RECT _rect;' print r' if (GetClientRect(%s->OutputWindow, &_rect)) {' % arg.name print r' if (%s->BufferDesc.Width == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Width = _rect.right - _rect.left;' print r' }' print r' if (%s->BufferDesc.Height == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Height = _rect.bottom - _rect.top;' print r' }' print r' }' else: # Obtain size from the output print r' DXGI_OUTPUT_DESC _OutputDesc;' print r' if (SUCCEEDED(pOutput->GetDesc(&_OutputDesc))) {' print r' _SwapChainDesc.BufferDesc.Width = _OutputDesc.DesktopCoordinates.right - _OutputDesc.DesktopCoordinates.left;' print r' _SwapChainDesc.BufferDesc.Height = _OutputDesc.DesktopCoordinates.bottom - _OutputDesc.DesktopCoordinates.top;' print r' }' print r' _pSwapChainDesc = &_SwapChainDesc;' print r' }' self.serializeValue(arg.type, '_pSwapChainDesc') return DllTracer.serializeArgValue(self, function, arg)
def enumWrapperInterfaceVariables(self, interface): variables = DllTracer.enumWrapperInterfaceVariables(self, interface) # Add additional members to track locks if interface.getMethodByName('Lock') is not None or \ interface.getMethodByName('LockRect') is not None or \ interface.getMethodByName('LockBox') is not None: variables += [ ('size_t', '_MappedSize', '0'), ('VOID *', 'm_pbData', '0'), ] return variables
def implementWrapperInterfaceMethodBody(self, interface, base, method): if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Unlock': print ' if (m_pbData) {' self.emit_memcpy('(LPBYTE)m_pbData', '(LPBYTE)m_pbData', 'm_SizeToLock') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Lock': # FIXME: handle recursive locks print ' if (__result == D3D_OK && !(Flags & D3DLOCK_READONLY)) {' print ' if (SizeToLock) {' print ' m_SizeToLock = SizeToLock;' print ' } else {' print ' D3DVERTEXBUFFER_DESC Desc;' print ' m_pInstance->GetDesc(&Desc);' print ' m_SizeToLock = Desc.Size;' print ' }' print ' m_pbData = *ppbData;' print ' } else {' print ' m_pbData = NULL;' print ' }'
def implementWrapperInterfaceMethodBody(self, interface, base, method): if interface.name == "IDirect3DVertexBuffer9" and method.name == "Unlock": print " if (m_pbData) {" self.emit_memcpy("(LPBYTE)m_pbData", "(LPBYTE)m_pbData", "m_SizeToLock") print " }" DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if interface.name == "IDirect3DVertexBuffer9" and method.name == "Lock": # FIXME: handle recursive locks print " if (__result == D3D_OK && !(Flags & D3DLOCK_READONLY)) {" print " if (SizeToLock) {" print " m_SizeToLock = SizeToLock;" print " } else {" print " D3DVERTEXBUFFER_DESC Desc;" print " m_pInstance->GetDesc(&Desc);" print " m_SizeToLock = Desc.Size;" print " }" print " m_pbData = *ppbData;" print " } else {" print " m_pbData = NULL;" print " }"
def enumWrapperInterfaceVariables(self, interface): variables = DllTracer.enumWrapperInterfaceVariables(self, interface) # Add additional members to track maps if interface.hasBase(*self.mapInterfaces): variables += [ ('_MAP_DESC', 'm_MapDesc', None), ] if interface.hasBase(d3d11.ID3D11DeviceContext): variables += [ ('std::map< std::pair<ID3D11Resource *, UINT>, _MAP_DESC >', 'm_MapDescs', None), ] return variables
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): if interface.name in ['IDirect3DTexture9']: print ' std::map<UINT, std::pair<size_t, VOID *> >::iterator it = _MappedData.find(Level);' print ' if (it != _MappedData.end()) {' self.emit_memcpy('(LPBYTE)it->second.second', 'it->second.first') print ' _MappedData.erase(it);' print ' }' else: print ' if (_MappedSize && m_pbData) {' self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name in ('Lock', 'LockRect', 'LockBox'): if interface.name in ['IDirect3DTexture9']: print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' size_t mappedSize;' print ' VOID * pbData;' print ' _getMapInfo(_this, %s, pbData, mappedSize);' % ', '.join( method.argNames()[:-1]) print ' _MappedData[Level] = std::make_pair(mappedSize, pbData);' print ' } else {' print ' _MappedData.erase(Level);' print ' }' else: # FIXME: handle recursive locks print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join( method.argNames()[:-1]) print ' } else {' print ' m_pbData = NULL;' print ' _MappedSize = 0;' print ' }'
def serializeArgValue(self, function, arg): # Dump shaders as strings if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'): print ' DumpShader(trace::localWriter, %s, %s);' % (arg.name, arg.type.size) return # Serialize the swapchain dimensions if function.name == 'CreateSwapChain' and arg.name == 'pDesc' \ or arg.name == 'pSwapChainDesc': print r' DXGI_SWAP_CHAIN_DESC *_pSwapChainDesc = NULL;' print r' DXGI_SWAP_CHAIN_DESC _SwapChainDesc;' print r' if (%s) {' % arg.name print r' _SwapChainDesc = *%s;' % arg.name if function.name != 'CreateSwapChain' or not self.interface.name.endswith('DWM'): # Obtain size from the window print r' RECT _rect;' print r' if (GetClientRect(%s->OutputWindow, &_rect)) {' % arg.name print r' if (%s->BufferDesc.Width == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Width = _rect.right - _rect.left;' print r' }' print r' if (%s->BufferDesc.Height == 0) {' % arg.name print r' _SwapChainDesc.BufferDesc.Height = _rect.bottom - _rect.top;' print r' }' print r' }' else: # Obtain size from the output print r' DXGI_OUTPUT_DESC _OutputDesc;' print r' if (SUCCEEDED(pOutput->GetDesc(&_OutputDesc))) {' print r' _SwapChainDesc.BufferDesc.Width = _OutputDesc.DesktopCoordinates.right - _OutputDesc.DesktopCoordinates.left;' print r' _SwapChainDesc.BufferDesc.Height = _OutputDesc.DesktopCoordinates.bottom - _OutputDesc.DesktopCoordinates.top;' print r' }' print r' _pSwapChainDesc = &_SwapChainDesc;' print r' }' self.serializeValue(arg.type, '_pSwapChainDesc') return DllTracer.serializeArgValue(self, function, arg)
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Map', 'Unmap'): # On D3D11 Map/Unmap is not a resource method, but a context method instead. resourceArg = method.getArgByName('pResource') if resourceArg is None: pResource = 'this' else: wrapperInterfaceName = getWrapperInterfaceName( resourceArg.type.type) print ' %s * _pResource = static_cast<%s*>(%s);' % ( wrapperInterfaceName, wrapperInterfaceName, resourceArg.name) pResource = '_pResource' if method.name == 'Unmap': print ' _MAP_DESC _MapDesc = %s->_MapDesc;' % pResource #print r' os::log("%%p -> %%p+%%lu\n", %s,_MapDesc.pData, (unsigned long)_MapDesc.Size);' % pResource print ' if (_MapDesc.Size && _MapDesc.pData) {' self.emit_memcpy('_MapDesc.pData', '_MapDesc.Size') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print ' _MAP_DESC _MapDesc;' print ' if (SUCCEEDED(_result)) {' print ' _getMapDesc(_this, %s, _MapDesc);' % ', '.join( method.argNames()) print ' } else {' print ' _MapDesc.pData = NULL;' print ' _MapDesc.Size = 0;' print ' }' #print r' os::log("%%p <- %%p+%%lu\n", %s,_MapDesc.pData, (unsigned long)_MapDesc.Size);' % pResource print ' %s->_MapDesc = _MapDesc;' % pResource
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'): print ' if (_MappedSize && m_pbData) {' self.emit_memcpy('(LPBYTE)m_pbData', '_MappedSize') print ' }' DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name in ('Lock', 'LockRect', 'LockBox'): # FIXME: handle recursive locks print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {' print ' _getMapInfo(_this, %s, m_pbData, _MappedSize);' % ', '.join( method.argNames()[:-1]) print ' } else {' print ' m_pbData = NULL;' print ' _MappedSize = 0;' print ' }' # Clamp capabilities if method.name == 'GetDeviceCaps': print ' if (SUCCEEDED(_result)) {' print ' clampCaps(pCaps);' print ' }' if method.name == 'CheckDeviceFormat': print ' if (SUCCEEDED(_result)) {' print ' if (!clampFormat(Usage, RType, CheckFormat)) {' print ' _result = D3DERR_NOTAVAILABLE;' print ' }' print ' }' if method.name == 'CheckDeviceMultiSampleType': print ' if (SUCCEEDED(_result)) {' print ' if (!clampMultiSampleType(SurfaceFormat, MultiSampleType, pQualityLevels)) {' print ' _result = D3DERR_NOTAVAILABLE;' print ' }' print ' }'
def enumWrapperInterfaceVariables(self, interface): variables = DllTracer.enumWrapperInterfaceVariables(self, interface) # Add additional members to track locks if interface.getMethodByName('Lock') is not None or \ interface.getMethodByName('LockRect') is not None or \ interface.getMethodByName('LockBox') is not None: if interface.name in ['IDirect3DTexture9']: variables += [ ('std::map<UINT, std::pair<size_t, VOID *> >', '_MappedData', 'std::map<UINT, std::pair<size_t, VOID *> >()'), ] else: variables += [ ('size_t', '_MappedSize', '0'), ('VOID *', 'm_pbData', '0'), ] return variables
def traceFunctionImplBody(self, function): if function.name in ('AcquireDDThreadLock', 'ReleaseDDThreadLock'): self.invokeFunction(function) return DllTracer.traceFunctionImplBody(self, function)
print '#include <ddraw.h>' print '#include <d3d.h>' print print ''' #ifndef DDBLT_EXTENDED_FLAGS #define DDBLT_EXTENDED_FLAGS 0x40000000l #endif #ifndef DDBLT_EXTENDED_LINEAR_CONTENT #define DDBLT_EXTENDED_LINEAR_CONTENT 0x00000004l #endif #ifndef D3DLIGHT_PARALLELPOINT #define D3DLIGHT_PARALLELPOINT (D3DLIGHTTYPE)4 #endif #ifndef D3DLIGHT_GLSPOT #define D3DLIGHT_GLSPOT (D3DLIGHTTYPE)5 #endif ''' print '#include "trace_writer_local.hpp"' print '#include "os.hpp"' print api = API() api.addModule(ddraw) tracer = DllTracer() tracer.traceApi(api)
# furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # ##########################################################################/ from dlltrace import DllTracer from specs.d3d10_1 import d3d10_1 if __name__ == '__main__': print '#define INITGUID' print print '#include "trace_writer_local.hpp"' print '#include "os.hpp"' print print '#include "d3d10_1imports.hpp"' print tracer = DllTracer('d3d10_1.dll') tracer.traceApi(d3d10_1)
def serializeArgValue(self, function, arg): # Dump shaders as strings if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'): print(' DumpShader(trace::localWriter, %s, %s);' % (arg.name, arg.type.size)) return # Serialize the swap-chain dimensions if function.name.startswith('CreateSwapChain') and arg.name == 'pDesc' \ or arg.name == 'pSwapChainDesc': assert isinstance(arg.type, stdapi.Pointer) descType = arg.type.type.mutable() print(r' %s *_pSwapChainDesc = nullptr;' % descType) print(r' %s _SwapChainDesc;' % descType) print(r' if (%s) {' % arg.name) print(r' _SwapChainDesc = *%s;' % arg.name) if self.interface is not None and self.interface.name.endswith( 'DWM'): # Obtain size from the output print(r' assert(pOutput);') print(r' DXGI_OUTPUT_DESC _OutputDesc;') print( r' if (SUCCEEDED(pOutput->GetDesc(&_OutputDesc))) {' ) print( r' _SwapChainDesc.BufferDesc.Width = _OutputDesc.DesktopCoordinates.right - _OutputDesc.DesktopCoordinates.left;' ) print( r' _SwapChainDesc.BufferDesc.Height = _OutputDesc.DesktopCoordinates.bottom - _OutputDesc.DesktopCoordinates.top;' ) print(r' }') elif function.name == 'CreateSwapChainForHwnd': # Obtain size from the window print(r' RECT _rect;') print(r' if (GetClientRect(hWnd, &_rect)) {') print(r' if (%s->Width == 0) {' % arg.name) print( r' _SwapChainDesc.Width = _rect.right - _rect.left;' ) print(r' }') print(r' if (%s->Height == 0) {' % arg.name) print( r' _SwapChainDesc.Height = _rect.bottom - _rect.top;' ) print(r' }') print(r' }') elif function.name.startswith('CreateSwapChainFor'): # TODO pass else: # Obtain size from the window print(r' RECT _rect;') print( r' if (GetClientRect(%s->OutputWindow, &_rect)) {' % arg.name) print(r' if (%s->BufferDesc.Width == 0) {' % arg.name) print( r' _SwapChainDesc.BufferDesc.Width = _rect.right - _rect.left;' ) print(r' }') print(r' if (%s->BufferDesc.Height == 0) {' % arg.name) print( r' _SwapChainDesc.BufferDesc.Height = _rect.bottom - _rect.top;' ) print(r' }') print(r' }') print(r' _pSwapChainDesc = &_SwapChainDesc;') print(r' }') self.serializeValue(arg.type, '_pSwapChainDesc') return # Serialize object names if function.name == 'SetPrivateData' and arg.name == 'pData': iid = function.args[0].name print(r' if (%s == WKPDID_D3DDebugObjectName) {' % iid) print( r' trace::localWriter.writeString(static_cast<const char *>(pData), DataSize);' ) print(r' } else {') DllTracer.serializeArgValue(self, function, arg) print(r' }') return DllTracer.serializeArgValue(self, function, arg)
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # ##########################################################################/ from specs.d3d10misc import d3d10 from dlltrace import DllTracer if __name__ == '__main__': print '#define INITGUID' print print '#include "trace_writer_local.hpp"' print '#include "os.hpp"' print print '#include <windows.h>' print '#include <tchar.h>' print print '#include "compat.h"' print print '#include <d3d10.h>' print tracer = DllTracer('d3d10.dll') tracer.trace_api(d3d10)
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # ##########################################################################/ from dlltrace import DllTracer from specs.stdapi import API from specs.dwrite import dwrite from specs.d2d1 import d2d1 if __name__ == '__main__': print('#include "guids_defs.hpp"') print() print('#include "trace_writer_local.hpp"') print('#include "os.hpp"') print() print('#define DWRITE_EXPORT WINAPI') print() print('#include "d2dimports.hpp"') print() api = API() api.addModule(d2d1) api.addModule(dwrite) tracer = DllTracer() tracer.traceApi(api)
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # ##########################################################################/ from dlltrace import DllTracer from specs.d3d10_1 import d3d10_1 if __name__ == '__main__': print '#define INITGUID' print print '#include "trace_writer_local.hpp"' print '#include "os.hpp"' print print '#include <windows.h>' print '#include <tchar.h>' print print '#include "compat.h"' print print '#include <d3d10_1.h>' print '#include <d3dx10.h>' print tracer = DllTracer('d3d10_1.dll') tracer.traceApi(d3d10_1)
def implementWrapperInterfaceMethodBody(self, interface, base, method): if method.getArgByName('pInitialData'): pDesc1 = method.getArgByName('pDesc1') if pDesc1 is not None: print(r' %s pDesc = pDesc1;' % (pDesc1.type, )) if method.name in ('Map', 'Unmap'): # On D3D11 Map/Unmap is not a resource method, but a context method instead. resourceArg = method.getArgByName('pResource') if resourceArg is None: print(' _MAP_DESC & _MapDesc = m_MapDesc;') print(' MemoryShadow & _MapShadow = m_MapShadow;') print(' %s *pResourceInstance = m_pInstance;' % interface.name) else: print(r' static bool _warned = false;') print( r' if (_this->GetType() == D3D11_DEVICE_CONTEXT_DEFERRED && !_warned) {' ) print( r' os::log("apitrace: warning: map with deferred context may not be realiably traced\n");' ) print(r' _warned = true;') print(r' }') print( ' _MAP_DESC & _MapDesc = m_MapDescs[std::pair<%s, UINT>(pResource, Subresource)];' % resourceArg.type) print( ' MemoryShadow & _MapShadow = m_MapShadows[std::pair<%s, UINT>(pResource, Subresource)];' % resourceArg.type) print( ' Wrap%spResourceInstance = static_cast<Wrap%s>(%s);' % (resourceArg.type, resourceArg.type, resourceArg.name)) if method.name == 'Unmap': print(' if (_MapDesc.Size && _MapDesc.pData) {') print(' if (_shouldShadowMap(pResourceInstance)) {') print(' _MapShadow.update(trace::fakeMemcpy);') print(' } else {') self.emit_memcpy('_MapDesc.pData', '_MapDesc.Size') print(' }') print(' }') if interface.hasBase(d3d11.ID3D11VideoContext) and \ method.name == 'ReleaseDecoderBuffer': print( ' std::map<UINT, std::pair<void *, UINT> >::iterator it = m_MapDesc.find(Type);' ) print(' if (it != m_MapDesc.end()) {') self.emit_memcpy('it->second.first', 'it->second.second') print(' m_MapDesc.erase(it);') print(' }') DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method) if method.name == 'Map': # NOTE: recursive locks are explicitely forbidden print(' if (SUCCEEDED(_result)) {') print(' _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames())) print( ' if (_MapDesc.pData && _shouldShadowMap(pResourceInstance)) {' ) if interface.name.startswith('IDXGI'): print(' (void)_MapShadow;') else: print( ' bool _discard = MapType == 4 /* D3D1[01]_MAP_WRITE_DISCARD */;' ) print( ' _MapShadow.cover(_MapDesc.pData, _MapDesc.Size, _discard);' ) print(' }') print(' } else {') print(' _MapDesc.pData = NULL;') print(' _MapDesc.Size = 0;') print(' }') if interface.hasBase(d3d11.ID3D11VideoContext) and \ method.name == 'GetDecoderBuffer': print(' if (SUCCEEDED(_result)) {') print( ' m_MapDesc[Type] = std::make_pair(*ppBuffer, *pBufferSize);' ) print(' } else {') print(' m_MapDesc[Type] = std::make_pair(nullptr, 0);') print(' }')