Пример #1
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            print r'    d3dretrace::pLastDirect3DDevice9 = _this;'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

        if method.name in ('Reset', 'ResetEx'):
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name == 'Present':
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        # check errors
        if str(method.type) == 'HRESULT':
            print r'    if (FAILED(_result)) {'
            print r'        retrace::warning(call) << "failed\n";'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _LockedSize = 0;'
            print '    _getLockInfo(_this, %s, _pbData, _LockedSize);' % ', '.join(method.argNames()[:-1])
            print '    _this->SetPrivateData(GUID_D3DRETRACE, &_pbData, sizeof _pbData, 0);'
        
        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    DWORD dwSizeOfData = sizeof _pbData;'
            print '    _this->GetPrivateData(GUID_D3DRETRACE, &_pbData, &dwSizeOfData);'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '    }'
Пример #2
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            print r'    d3dretrace::pLastDirect3DDevice9 = _this;'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx',
                           'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

        # notify frame has been completed
        if method.name == 'Present':
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        Retracer.invokeInterfaceMethod(self, interface, method)

        # check errors
        if str(method.type) == 'HRESULT':
            print r'    if (FAILED(_result)) {'
            print r'        retrace::warning(call) << "failed\n";'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _LockedSize = 0;'
            print '    _getLockInfo(_this, %s, _pbData, _LockedSize);' % ', '.join(
                method.argNames()[:-1])
            print '    _this->SetPrivateData(GUID_D3DRETRACE, &_pbData, sizeof _pbData, 0);'

        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    DWORD dwSizeOfData = sizeof _pbData;'
            print '    _this->GetPrivateData(GUID_D3DRETRACE, &_pbData, &dwSizeOfData);'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '    }'
Пример #3
0
    def invokeInterfaceMethod(self, interface, method):
        if interface.name == 'IDirect3D9' and method.name == 'CreateDevice':
            print 'HWND hWnd = createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print 'pPresentationParameters->hDeviceWindow = hWnd;'
            print 'hFocusWindow = hWnd;'

        Retracer.invokeInterfaceMethod(self, interface, method)

        if str(method.type) == 'HRESULT':
            print r'    if (__result != S_OK) {'
            print r'        retrace::warning(call) << "failed\n";'
            print r'    }'

        if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Lock':
            print '        if (!SizeToLock) {'
            print '            D3DVERTEXBUFFER_DESC Desc;'
            print '            _this->GetDesc(&Desc);'
            print '            SizeToLock = Desc.Size;'
            print '        }'
Пример #4
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d10Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name.startswith('ID3D11DeviceContext'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d11Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d11Dumper.bindDevice(_this);'

        # intercept private interfaces
        if method.name == 'QueryInterface':
            print r'    if (!d3dretrace::overrideQueryInterface(_this, riid, ppvObj, &_result)) {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    d3dretrace::createWindowForSwapChain(pDesc);'
        if method.name == 'CreateSwapChainForHwnd':
            print r'    WindowHandle = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            print r'    // DXGI_SCALING_NONE is only supported on Win8 and beyond'
            print r'    if (pDesc->Scaling == DXGI_SCALING_NONE && !IsWindows8OrGreater()) {'
            print r'        pDesc->Scaling = DXGI_SCALING_STRETCH;'
            print r'    }'
        if method.name == 'CreateSwapChainForComposition':
            print r'    HWND hWnd = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            print r'    _result = _this->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, NULL, pRestrictToOutput, ppSwapChain);'
            self.checkResult(interface, method)
            return
        if method.name == 'CreateTargetForHwnd':
            print r'    hwnd = d3dretrace::createWindow(1024, 768);'

        if method.name == 'SetFullscreenState':
            print r'    if (retrace::forceWindowed) {'
            print r'         Fullscreen = FALSE;'
            print r'         pTarget = NULL;'
            print r'    }'

        # notify frame has been completed
        if interface.name.startswith(
                'IDXGISwapChain') and method.name.startswith('Present'):
            if interface.name.startswith('IDXGISwapChainDWM'):
                print r'    com_ptr<IDXGISwapChain> pSwapChain;'
                print r'    if (SUCCEEDED(_this->QueryInterface(IID_IDXGISwapChain, (void **) &pSwapChain))) {'
                print r'        dxgiDumper.bindDevice(pSwapChain);'
                print r'    } else {'
                print r'        assert(0);'
                print r'    }'
            else:
                print r'    dxgiDumper.bindDevice(_this);'
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith(
                'IDXGIFactory') and method.name.startswith('EnumAdapters'):
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, reinterpret_cast<IDXGIAdapter **>(ppAdapter));'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        if interface.name.startswith(
                'ID3D10Device') and method.name.startswith(
                    'OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            self.checkResult(interface, method)
            return
        if interface.name.startswith(
                'ID3D11Device') and method.name == 'OpenSharedResource':
            # Some applications (e.g., video playing in IE11) create shared resources within the same process.
            # TODO: Generalize to other OpenSharedResource variants
            print r'    retrace::map<HANDLE>::const_iterator it = _shared_handle_map.find(hResource);'
            print r'    if (it == _shared_handle_map.end()) {'
            print r'        retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'        _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            self.checkResult(interface, method)
            print r'    } else {'
            print r'        hResource = it->second;'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return
        if interface.name.startswith(
                'ID3D11Device') and method.name.startswith(
                    'OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            if method.name == 'OpenSharedResourceByName':
                print r'    (void)lpName;'
                print r'    (void)dwDesiredAccess;'
            else:
                print r'    (void)hResource;'
            self.checkResult(interface, method)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print r'    MapFlags &= ~%s;' % flag

        if method.name.startswith('UpdateSubresource'):
            # The D3D10 debug layer is buggy (or at least inconsistent with the
            # runtime), as it seems to estimate and enforce the data size based on the
            # SrcDepthPitch, even for non 3D textures, but in some traces
            # SrcDepthPitch is garbagge for non 3D textures.
            # XXX: It also seems to expect padding bytes at the end of the last
            # row, but we never record (or allocate) those...
            print r'    if (retrace::debug && pDstBox && pDstBox->front == 0 && pDstBox->back == 1) {'
            print r'        SrcDepthPitch = 0;'
            print r'    }'

        if method.name == 'SetGammaControl':
            # This method is only supported while in full-screen mode
            print r'    if (retrace::forceWindowed) {'
            print r'        return;'
            print r'    }'

        if method.name == 'GetData':
            print r'    pData = _allocator.alloc(DataSize);'
            print r'    do {'
            self.doInvokeInterfaceMethod(interface, method)
            print r'        GetDataFlags = 0; // Prevent infinite loop'
            print r'    } while (_result == S_FALSE);'
            self.checkResult(interface, method)
            print r'    return;'

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in ('AcquireSync', 'ReleaseSync'):
            print r'    if (SUCCEEDED(_result) && _result != S_OK) {'
            print r'        retrace::warning(call) << " returned " << _result << "\n";'
            print r'    }'

        # process events after presents
        if interface.name.startswith(
                'IDXGISwapChain') and method.name.startswith('Present'):
            print r'    d3dretrace::processEvents();'

        if method.name in ('Map', 'Unmap'):
            if interface.name.startswith('ID3D11DeviceContext'):
                print '    void * & _pbData = g_Maps[_this][SubresourceKey(pResource, Subresource)];'
            else:
                subresourceArg = method.getArgByName('Subresource')
                if subresourceArg is None:
                    print '    UINT Subresource = 0;'
                print '    void * & _pbData = g_Maps[0][SubresourceKey(_this, Subresource)];'

        if method.name == 'Map':
            print '    _MAP_DESC _MapDesc;'
            print '    _getMapDesc(_this, %s, _MapDesc);' % ', '.join(
                method.argNames())
            print '    size_t _MappedSize = _MapDesc.Size;'
            print '    if (_MapDesc.Size) {'
            print '        _pbData = _MapDesc.pData;'
            if interface.name.startswith('ID3D11DeviceContext'):
                # Prevent false warnings on 1D and 2D resources, since the
                # pitches are often junk there...
                print '        _normalizeMap(pResource, pMappedResource);'
            else:
                print '        _pbData = _MapDesc.pData;'
            print '    } else {'
            print '        return;'
            print '    }'

        if method.name == 'Unmap':
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _pbData = 0;'
            print '    }'

        if interface.name.startswith('ID3D11VideoContext'):
            if method.name == 'GetDecoderBuffer':
                print '    if (*ppBuffer && *pBufferSize) {'
                print '        g_Maps[nullptr][SubresourceKey(_this, Type)] = *ppBuffer;'
                print '    }'
            if method.name == 'ReleaseDecoderBuffer':
                print '    SubresourceKey _mappingKey(_this, Type);'
                print '    void *_pBuffer = g_Maps[nullptr][_mappingKey];'
                print '    if (_pBuffer) {'
                print '        retrace::delRegionByPointer(_pBuffer);'
                print '        g_Maps[nullptr][_mappingKey] = 0;'
                print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'
Пример #5
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d10Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name in ('ID3D11DeviceContext', 'ID3D11DeviceContext1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d11Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    if (_this->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) {'
                print r'        d3d11Dumper.bindDevice(_this);'
                print r'    }'

        if interface.name == 'IDXGIFactory' and method.name == 'QueryInterface':
            print r'    if (riid == IID_IDXGIFactoryDWM) {'
            print r'        _this->AddRef();'
            print r'        *ppvObj = new d3dretrace::CDXGIFactoryDWM(_this);'
            print r'        _result = S_OK;'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    createWindow(pDesc);'

        # notify frame has been completed
        if method.name == 'Present':
            if interface.name == 'IDXGISwapChainDWM':
                print r'    dxgiDumper.bindDevice(reinterpret_cast<d3dretrace::CDXGISwapChainDWM *>(_this)->m_pSwapChain);'
            else:
                print r'    dxgiDumper.bindDevice(_this);'
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith(
                'IDXGIFactory') and method.name.startswith('EnumAdapters'):
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, reinterpret_cast<IDXGIAdapter **>(ppAdapter));'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        if interface.name.startswith(
                'ID3D10Device') and method.name == 'OpenSharedResource':
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    D3D10_TEXTURE2D_DESC Desc;'
            print r'    memset(&Desc, 0, sizeof Desc);'
            print r'    Desc.Width = 8;'
            print r'    Desc.Height = 8;'
            print r'    Desc.MipLevels = 1;'
            print r'    Desc.ArraySize = 1;'
            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
            print r'    Desc.SampleDesc.Count = 1;'
            print r'    Desc.SampleDesc.Quality = 0;'
            print r'    Desc.Usage = D3D10_USAGE_DEFAULT;'
            print r'    Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;'
            print r'    Desc.CPUAccessFlags = 0x0;'
            print r'    Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;'
            print r'''
            static const DWORD Checker[8][8] = {
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U }
            };
            static const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            '''
            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, (ID3D10Texture2D**)ppResource);'
            self.checkResult(method.type)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print r'    MapFlags &= ~%s;' % flag

        if method.name == 'UpdateSubresource':
            # The D3D10 debug layer is buggy (or at least inconsistent with the
            # runtime), as it seems to estimate and enforce the data size based on the
            # SrcDepthPitch, even for non 3D textures, but in some traces
            # SrcDepthPitch is garbagge for non 3D textures.
            # XXX: It also seems to expect padding bytes at the end of the last
            # row, but we never record (or allocate) those...
            print r'    if (retrace::debug && pDstBox && pDstBox->front == 0 && pDstBox->back == 1) {'
            print r'        SrcDepthPitch = 0;'
            print r'    }'

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name == 'Map':
            print '    _MAP_DESC _MapDesc;'
            print '    _getMapDesc(_this, %s, _MapDesc);' % ', '.join(
                method.argNames())
            print '    size_t _MappedSize = _MapDesc.Size;'
            print '    if (_MapDesc.Size) {'
            if interface.name.startswith('ID3D11DeviceContext'):
                print '        _maps[pResource] = _MapDesc.pData;'
            else:
                print '        _maps[_this] = _MapDesc.pData;'
            print '    } else {'
            print '        return;'
            print '    }'

        if method.name == 'Unmap':
            if interface.name.startswith('ID3D11DeviceContext'):
                print '    VOID *_pbData = 0;'
                print '    _pbData = _maps[pResource];'
                print '    if (_pbData) {'
                print '        retrace::delRegionByPointer(_pbData);'
                print '        _maps[pResource] = 0;'
                print '    }'
            else:
                print '    VOID *_pbData = 0;'
                print '    _pbData = _maps[_this];'
                print '    if (_pbData) {'
                print '        retrace::delRegionByPointer(_pbData);'
                print '        _maps[_this] = 0;'
                print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'
Пример #6
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d9Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d8Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx',
                           'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'

        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
            # resize window
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name in ('Present', 'PresentEx'):
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in self.createDeviceMethodNames:
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(
                method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            print '    } else {'
            print '        return;'
            print '    }'

        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'
Пример #7
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d10Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name.startswith('ID3D11DeviceContext'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d11Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    if (_this->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) {'
                print r'        d3d11Dumper.bindDevice(_this);'
                print r'    }'

        # intercept private interfaces
        if method.name == 'QueryInterface':
            print r'    if (!d3dretrace::overrideQueryInterface(_this, riid, ppvObj, &_result)) {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    d3dretrace::createWindowForSwapChain(pDesc);'
        if method.name == 'CreateSwapChainForHwnd':
            print r'    WindowHandle = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            print r'    // DXGI_SCALING_NONE is only supported on Win8 and beyond'
            print r'    if (pDesc->Scaling == DXGI_SCALING_NONE && !IsWindows8OrGreater()) {'
            print r'        pDesc->Scaling = DXGI_SCALING_STRETCH;'
            print r'    }'
        if method.name == 'CreateSwapChainForComposition':
            print r'    HWND hWnd = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            print r'    _result = _this->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, NULL, pRestrictToOutput, ppSwapChain);'
            self.checkResult(interface, method)
            return
        if method.name == 'CreateTargetForHwnd':
            print r'    hwnd = d3dretrace::createWindow(1024, 768);'

        if method.name == 'SetFullscreenState':
            print r'    if (retrace::forceWindowed) {'
            print r'         Fullscreen = FALSE;'
            print r'         pTarget = NULL;'
            print r'    }'

        # notify frame has been completed
        if interface.name.startswith('IDXGISwapChain') and method.name.startswith('Present'):
            if interface.name.startswith('IDXGISwapChainDWM'):
                print r'    com_ptr<IDXGISwapChain> pSwapChain;'
                print r'    if (SUCCEEDED(_this->QueryInterface(IID_IDXGISwapChain, (void **) &pSwapChain))) {'
                print r'        dxgiDumper.bindDevice(pSwapChain);'
                print r'    } else {'
                print r'        assert(0);'
                print r'    }'
            else:
                print r'    dxgiDumper.bindDevice(_this);'
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith('IDXGIFactory') and method.name.startswith('EnumAdapters'):
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, reinterpret_cast<IDXGIAdapter **>(ppAdapter));'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        if interface.name.startswith('ID3D10Device') and method.name.startswith('OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            self.checkResult(interface, method)
            return
        if interface.name.startswith('ID3D11Device') and method.name == 'OpenSharedResource':
            # Some applications (e.g., video playing in IE11) create shared resources within the same process.
            # TODO: Generalize to other OpenSharedResource variants
            print r'    retrace::map<HANDLE>::const_iterator it = _shared_handle_map.find(hResource);'
            print r'    if (it == _shared_handle_map.end()) {'
            print r'        retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'        _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            self.checkResult(interface, method)
            print r'    } else {'
            print r'        hResource = it->second;'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return
        if interface.name.startswith('ID3D11Device') and method.name.startswith('OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            if method.name == 'OpenSharedResourceByName':
                print r'    (void)lpName;'
                print r'    (void)dwDesiredAccess;'
            else:
                print r'    (void)hResource;'
            self.checkResult(interface, method)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print r'    MapFlags &= ~%s;' % flag

        if method.name.startswith('UpdateSubresource'):
            # The D3D10 debug layer is buggy (or at least inconsistent with the
            # runtime), as it seems to estimate and enforce the data size based on the
            # SrcDepthPitch, even for non 3D textures, but in some traces
            # SrcDepthPitch is garbagge for non 3D textures.
            # XXX: It also seems to expect padding bytes at the end of the last
            # row, but we never record (or allocate) those...
            print r'    if (retrace::debug && pDstBox && pDstBox->front == 0 && pDstBox->back == 1) {'
            print r'        SrcDepthPitch = 0;'
            print r'    }'

        if method.name == 'SetGammaControl':
            # This method is only supported while in full-screen mode
            print r'    if (retrace::forceWindowed) {'
            print r'        return;'
            print r'    }'

        if method.name == 'GetData':
            print r'    pData = _allocator.alloc(DataSize);'
            print r'    do {'
            self.doInvokeInterfaceMethod(interface, method)
            print r'        GetDataFlags = 0; // Prevent infinite loop'
            print r'    } while (_result == S_FALSE);'
            self.checkResult(interface, method)
            print r'    return;'

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in ('AcquireSync', 'ReleaseSync'):
            print r'    if (SUCCEEDED(_result) && _result != S_OK) {'
            print r'        retrace::warning(call) << " returned " << _result << "\n";'
            print r'    }'

        # process events after presents
        if interface.name.startswith('IDXGISwapChain') and method.name.startswith('Present'):
            print r'    d3dretrace::processEvents();'

        if method.name in ('Map', 'Unmap'):
            if interface.name.startswith('ID3D11DeviceContext'):
                print '    void * & _pbData = g_Maps[_this][SubresourceKey(pResource, Subresource)];'
            else:
                subresourceArg = method.getArgByName('Subresource')
                if subresourceArg is None:
                    print '    UINT Subresource = 0;'
                print '    void * & _pbData = g_Maps[0][SubresourceKey(_this, Subresource)];'

        if method.name == 'Map':
            print '    _MAP_DESC _MapDesc;'
            print '    _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames())
            print '    size_t _MappedSize = _MapDesc.Size;'
            print '    if (_MapDesc.Size) {'
            print '        _pbData = _MapDesc.pData;'
            if interface.name.startswith('ID3D11DeviceContext'):
                # Prevent false warnings on 1D and 2D resources, since the
                # pitches are often junk there...
                print '        _normalizeMap(pResource, pMappedResource);'
            else:
                print '        _pbData = _MapDesc.pData;'
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name == 'Unmap':
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _pbData = 0;'
            print '    }'

        if interface.name.startswith('ID3D11VideoContext'):
            if method.name == 'GetDecoderBuffer':
                print '    if (*ppBuffer && *pBufferSize) {'
                print '        g_Maps[nullptr][SubresourceKey(_this, Type)] = *ppBuffer;'
                print '    }'
            if method.name == 'ReleaseDecoderBuffer':
                print '    SubresourceKey _mappingKey(_this, Type);'
                print '    void *_pBuffer = g_Maps[nullptr][_mappingKey];'
                print '    if (_pBuffer) {'
                print '        retrace::delRegionByPointer(_pBuffer);'
                print '        g_Maps[nullptr][_mappingKey] = 0;'
                print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'
Пример #8
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print(r'    if (call.ret->toUInt() == 0) {')
                print(r'        d3d10Dumper.unbindDevice(_this);')
                print(r'    }')
            else:
                print(r'    d3d10Dumper.bindDevice(_this);')
        if interface.name.startswith('ID3D11DeviceContext'):
            if method.name == 'Release':
                print(r'    if (call.ret->toUInt() == 0) {')
                print(r'        d3d11Dumper.unbindDevice(_this);')
                print(r'    }')
            else:
                print(r'    d3d11Dumper.bindDevice(_this);')

        # intercept private interfaces
        if method.name == 'QueryInterface':
            print(
                r'    if (!d3dretrace::overrideQueryInterface(_this, riid, ppvObj, &_result)) {'
            )
            Retracer.invokeInterfaceMethod(self, interface, method)
            print(r'    }')
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print(r'    d3dretrace::createWindowForSwapChain(pDesc);')
        if method.name == 'CreateSwapChainForHwnd':
            print(
                r'    hWnd = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            )
            print(
                r'    // DXGI_SCALING_NONE is only supported on Win8 and beyond'
            )
            print(
                r'    if (pDesc->Scaling == DXGI_SCALING_NONE && !IsWindows8OrGreater()) {'
            )
            print(r'        pDesc->Scaling = DXGI_SCALING_STRETCH;')
            print(r'    }')
        if method.name == 'CreateSwapChainForComposition':
            print(
                r'    HWND hWnd = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            )
            print(
                r'    _result = _this->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, NULL, pRestrictToOutput, ppSwapChain);'
            )
            self.checkResult(interface, method)
            return
        if method.name == 'CreateTargetForHwnd':
            print(r'    hwnd = d3dretrace::createWindow(1024, 768);')

        if method.name == 'SetFullscreenState':
            print(r'    if (retrace::forceWindowed) {')
            print(r'         DXGI_SWAP_CHAIN_DESC Desc;')
            print(r'         _this->GetDesc(&Desc);')
            print(
                r'         if (Desc.BufferDesc.Format != DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM) {'
            )
            print(r'             Fullscreen = FALSE;')
            print(r'             pTarget = nullptr;')
            print(r'        }')
            print(r'    }')

        # notify frame has been completed
        if interface.name.startswith(
                'IDXGISwapChain') and method.name.startswith('Present'):
            if interface.name.startswith('IDXGISwapChainDWM'):
                print(r'    com_ptr<IDXGISwapChain> pSwapChain;')
                print(
                    r'    if (SUCCEEDED(_this->QueryInterface(IID_IDXGISwapChain, (void **) &pSwapChain))) {'
                )
                print(r'        dxgiDumper.bindDevice(pSwapChain);')
                print(r'    } else {')
                print(r'        assert(0);')
                print(r'    }')
            else:
                print(r'    dxgiDumper.bindDevice(_this);')
            print(r'    retrace::frameComplete(call);')

        if 'pSharedResource' in method.argNames():
            print(r'    if (pSharedResource) {')
            print(
                r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            )
            print(r'        pSharedResource = NULL;')
            print(r'    }')

        if interface.name.startswith(
                'ID3D10Device') and method.name.startswith(
                    'OpenSharedResource'):
            print(
                r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            )
            print(
                r'    _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            )
            self.checkResult(interface, method)
            return
        if interface.name.startswith(
                'ID3D11Device') and method.name == 'OpenSharedResource':
            # Some applications (e.g., video playing in IE11) create shared resources within the same process.
            # TODO: Generalize to other OpenSharedResource variants
            print(
                r'    retrace::map<HANDLE>::const_iterator it = _shared_handle_map.find(hResource);'
            )
            print(r'    if (it == _shared_handle_map.end()) {')
            print(
                r'        retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            )
            print(
                r'        _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            )
            self.checkResult(interface, method)
            print(r'    } else {')
            print(r'        hResource = it->second;')
            Retracer.invokeInterfaceMethod(self, interface, method)
            print(r'    }')
            return
        if interface.name.startswith(
                'ID3D11Device') and method.name.startswith(
                    'OpenSharedResource'):
            print(
                r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            )
            print(
                r'    _result = d3dretrace::createSharedResource(_this, ReturnedInterface, ppResource);'
            )
            if method.name == 'OpenSharedResourceByName':
                print(r'    (void)lpName;')
                print(r'    (void)dwDesiredAccess;')
            else:
                print(r'    (void)hResource;')
            self.checkResult(interface, method)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print(r'    MapFlags &= ~%s;' % flag)

        if method.name.startswith('UpdateSubresource'):
            # The D3D10 debug layer is buggy (or at least inconsistent with the
            # runtime), as it seems to estimate and enforce the data size based on the
            # SrcDepthPitch, even for non 3D textures, but in some traces
            # SrcDepthPitch is garbagge for non 3D textures.
            # XXX: It also seems to expect padding bytes at the end of the last
            # row, but we never record (or allocate) those...
            print(
                r'    if (retrace::debug >= 2 && pDstBox && pDstBox->front == 0 && pDstBox->back == 1) {'
            )
            print(r'        SrcDepthPitch = 0;')
            print(r'    }')

        if method.name == 'SetGammaControl':
            # This method is only supported while in full-screen mode
            print(r'    if (retrace::forceWindowed) {')
            print(r'        return;')
            print(r'    }')

        if method.name == 'GetData':
            print(r'    pData = _allocator.alloc(DataSize);')
            print(r'    do {')
            self.doInvokeInterfaceMethod(interface, method)
            print(r'        GetDataFlags = 0; // Prevent infinite loop')
            print(r'    } while (_result == S_FALSE);')
            self.checkResult(interface, method)
            print(r'    return;')

        if method.name in ('CreateTexture1D', 'CreateTexture2D',
                           'CreateTexture3D', 'CreateBuffer'):
            # We don't capture multiple processes, so ignore keyed mutexes to avoid deadlocks
            print(
                r'    if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) {'
            )
            print(
                r'        pDesc->MiscFlags &= ~D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;'
            )
            print(r'        pDesc->MiscFlags |= D3D11_RESOURCE_MISC_SHARED;')
            print(r'    }')

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in ('AcquireSync', 'ReleaseSync'):
            print(r'    if (SUCCEEDED(_result) && _result != S_OK) {')
            print(
                r'        retrace::warning(call) << " returned " << _result << "\n";'
            )
            print(r'    }')

        # process events after presents
        if interface.name.startswith(
                'IDXGISwapChain') and method.name.startswith('Present'):
            print(r'    d3dretrace::processEvents();')

        if method.name in ('Map', 'Unmap'):
            if interface.name.startswith('ID3D11DeviceContext'):
                print(
                    '    void * & _pbData = g_Maps[_this][SubresourceKey(pResource, Subresource)];'
                )
            else:
                subresourceArg = method.getArgByName('Subresource')
                if subresourceArg is None:
                    print('    UINT Subresource = 0;')
                print(
                    '    void * & _pbData = g_Maps[0][SubresourceKey(_this, Subresource)];'
                )

        if method.name == 'Map':
            print('    _MAP_DESC _MapDesc;')
            print('    _getMapDesc(_this, %s, _MapDesc);' %
                  ', '.join(method.argNames()))
            print('    size_t _MappedSize = _MapDesc.Size;')
            print('    if (_MapDesc.Size) {')
            print('        _pbData = _MapDesc.pData;')
            if interface.name.startswith('ID3D11DeviceContext'):
                # Prevent false warnings on 1D and 2D resources, since the
                # pitches are often junk there...
                print('        _normalizeMap(pResource, pMappedResource);')
            else:
                print('        _pbData = _MapDesc.pData;')
            print('    } else {')
            print('        return;')
            print('    }')

        if method.name == 'Unmap':
            print('    if (_pbData) {')
            print('        retrace::delRegionByPointer(_pbData);')
            print('        _pbData = 0;')
            print('    }')

        if interface.name.startswith('ID3D11VideoContext'):
            if method.name == 'GetDecoderBuffer':
                print('    if (*ppBuffer && *pBufferSize) {')
                print(
                    '        g_Maps[nullptr][SubresourceKey(_this, Type)] = *ppBuffer;'
                )
                print('    }')
            if method.name == 'ReleaseDecoderBuffer':
                print('    SubresourceKey _mappingKey(_this, Type);')
                print('    void *_pBuffer = g_Maps[nullptr][_mappingKey];')
                print('    if (_pBuffer) {')
                print('        retrace::delRegionByPointer(_pBuffer);')
                print('        g_Maps[nullptr][_mappingKey] = 0;')
                print('    }')

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print(r'    if (retrace::dumpingState && SUCCEEDED(_result)) {')
            print(
                r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);'
                % ppShader.name)
            print(r'    }')

        if method.name == 'CreateBuffer':
            ppBuffer = method.args[-1]
            print(r'    if (retrace::dumpingState && SUCCEEDED(_result)) {')
            print(r'       char label[32];')
            print(
                r'       _snprintf(label, sizeof label, "0x%%llx", call.arg(%u).toArray()->values[0]->toUIntPtr());'
                % ppBuffer.index)
            print(
                r'        (*%s)->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(label)+1, label);'
                % ppBuffer.name)
            print(r'    }')
Пример #9
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    d3d10Dumper.unbindDevice(_this);'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name in ('ID3D11DeviceContext',):
            if method.name == 'Release':
                print r'    d3d11Dumper.unbindDevice(_this);'
            else:
                print r'    d3d11Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    createWindow(pDesc);'

        # notify frame has been completed
        if method.name == 'Present':
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith('IDXGIFactory') and method.name == 'EnumAdapters':
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, ppAdapter);'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name == 'Map':
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames())
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name == 'Unmap':
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'
Пример #10
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ("ID3D10Device", "ID3D10Device1"):
            if method.name == "Release":
                print r"    d3d10Dumper.unbindDevice(_this);"
            else:
                print r"    d3d10Dumper.bindDevice(_this);"
        if interface.name in ("ID3D11DeviceContext",):
            if method.name == "Release":
                print r"    d3d11Dumper.unbindDevice(_this);"
            else:
                print r"    d3d11Dumper.bindDevice(_this);"

        if interface.name == "IDXGIFactory" and method.name == "QueryInterface":
            print r"    if (riid == IID_IDXGIFactoryDWM) {"
            print r"        _this->AddRef();"
            print r"        *ppvObj = new d3dretrace::CDXGIFactoryDWM(_this);"
            print r"        _result = S_OK;"
            print r"    } else {"
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r"    }"
            return

        # create windows as neccessary
        if method.name == "CreateSwapChain":
            print r"    createWindow(pDesc);"

        # notify frame has been completed
        if method.name == "Present":
            print r"    retrace::frameComplete(call);"

        if "pSharedResource" in method.argNames():
            print r"    if (pSharedResource) {"
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r"        pSharedResource = NULL;"
            print r"    }"

        # Force driver
        if interface.name.startswith("IDXGIFactory") and method.name == "EnumAdapters":
            print r"    const char *szSoftware = NULL;"
            print r"    switch (retrace::driver) {"
            print r"    case retrace::DRIVER_REFERENCE:"
            print r"    case retrace::DRIVER_SOFTWARE:"
            print r'        szSoftware = "d3d10warp.dll";'
            print r"        break;"
            print r"    case retrace::DRIVER_MODULE:"
            print r"        szSoftware = retrace::driverModule;"
            print r"        break;"
            print r"    default:"
            print r"        break;"
            print r"    }"
            print r"    HMODULE hSoftware = NULL;"
            print r"    if (szSoftware) {"
            print r"        hSoftware = LoadLibraryA(szSoftware);"
            print r"        if (!hSoftware) {"
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r"        }"
            print r"    }"
            print r"    if (hSoftware) {"
            print r"        _result = _this->CreateSoftwareAdapter(hSoftware, ppAdapter);"
            print r"    } else {"
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r"    }"
            return

        if interface.name.startswith("ID3D10Device") and method.name == "OpenSharedResource":
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r"    D3D10_TEXTURE2D_DESC Desc;"
            print r"    memset(&Desc, 0, sizeof Desc);"
            print r"    Desc.Width = 8;"
            print r"    Desc.Height = 8;"
            print r"    Desc.MipLevels = 1;"
            print r"    Desc.ArraySize = 1;"
            print r"    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;"
            print r"    Desc.SampleDesc.Count = 1;"
            print r"    Desc.SampleDesc.Quality = 0;"
            print r"    Desc.Usage = D3D10_USAGE_DEFAULT;"
            print r"    Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;"
            print r"    Desc.CPUAccessFlags = 0x0;"
            print r"    Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;"
            print r"""
            const DWORD Checker[8][8] = {
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, }
            };
            const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            """
            print r"    _result = _this->CreateTexture2D(&Desc, &InitialData, (ID3D10Texture2D**)ppResource);"
            self.checkResult(method.type)
            return

        if method.name == "Map":
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName("MapFlags")
            for flag in mapFlagsArg.type.values:
                if flag.endswith("_MAP_FLAG_DO_NOT_WAIT"):
                    print r"    MapFlags &= ~%s;" % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == "Present":
            print r"    d3dretrace::processEvents();"

        if method.name == "Map":
            print "    VOID *_pbData = NULL;"
            print "    size_t _MappedSize = 0;"
            print "    _getMapInfo(_this, %s, _pbData, _MappedSize);" % ", ".join(method.argNames())
            print "    if (_MappedSize) {"
            print "        _maps[_this] = _pbData;"
            print "    } else {"
            print "        return;"
            print "    }"

        if method.name == "Unmap":
            print "    VOID *_pbData = 0;"
            print "    _pbData = _maps[_this];"
            print "    if (_pbData) {"
            print "        retrace::delRegionByPointer(_pbData);"
            print "        _maps[_this] = 0;"
            print "    }"

        # Attach shader byte code for lookup
        if "pShaderBytecode" in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r"    if (retrace::dumpingState && SUCCEEDED(_result)) {"
            print r"        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);" % ppShader.name
            print r"    }"
Пример #11
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d9Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d8Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
        
        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
            # resize window
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name in ('Present', 'PresentEx'):
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('Flags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_DONOTWAIT'):
                    print r'    Flags &= ~%s;' % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in self.createDeviceMethodNames:
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'
Пример #12
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d9Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d8Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
        
        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
            # resize window
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name in ('Present', 'PresentEx'):
            print r'    retrace::frameComplete(call);'
            print r'    if (retrace::profiling) {'
            print r'    retrace::profiler.addFrameEnd();'
            print r'    }'
            print r'    hDestWindowOverride = NULL;'

        # Ensure textures can be locked when dumping
        # TODO: Pre-check with CheckDeviceFormat
        if method.name in ('CreateVertexShader', 'CreatePixelShader'):
            print r'    pFunction = d3dretrace::CheckReplaceShader(pFunction,call);'
        if method.name in ('CreateTexture', 'CreateCubeTexture', 'CreateVolumeTexture'):
            print r'    if (retrace::dumpingState &&'
            print r'        Pool == D3DPOOL_DEFAULT &&'
            print r'        !(Usage & (D3DUSAGE_RENDERTARGET|D3DUSAGE_DEPTHSTENCIL))) {'
            print r'        Usage |= D3DUSAGE_DYNAMIC;'
            print r'    }'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('Flags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_DONOTWAIT'):
                    print r'    Flags &= ~%s;' % flag

        if method.name.startswith("Draw"):
            print r'    if (retrace::profiling) {'
            print r'        d3dretrace::beginProfileDX9(call, true);'
            print r'    }'
        Retracer.invokeInterfaceMethod(self, interface, method)
        if method.name.startswith("Draw"):
            print r'    if (retrace::profiling) {'
            print r'        d3dretrace::endProfileDX9(call, true);'
            print r'    }'
        if method.name in self.createDeviceMethodNames:
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        def mapping_subkey():
            if 'Level' in method.argNames():
                return ('Level',)
            else:
                return ('0',)

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[MappingKey(_this, %s)] = _pbData;' % mapping_subkey()
            self.checkPitchMismatch(method)
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    MappingKey _mappingKey(_this, %s);' % mapping_subkey()
            print '    _pbData = _maps[_mappingKey];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_mappingKey] = 0;'
            print '    }'
Пример #13
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d10Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name in ('ID3D11DeviceContext', 'ID3D11DeviceContext1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d11Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    if (_this->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) {'
                print r'        d3d11Dumper.bindDevice(_this);'
                print r'    }'

        if interface.name == 'IDXGIFactory' and method.name == 'QueryInterface':
            print r'    if (riid == IID_IDXGIFactoryDWM) {'
            print r'        _this->AddRef();'
            print r'        *ppvObj = new d3dretrace::CDXGIFactoryDWM(_this);'
            print r'        _result = S_OK;'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    createWindow(pDesc);'

        # notify frame has been completed
        if method.name == 'Present':
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith('IDXGIFactory') and method.name == 'EnumAdapters':
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, ppAdapter);'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        if interface.name.startswith('ID3D10Device') and method.name == 'OpenSharedResource':
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    D3D10_TEXTURE2D_DESC Desc;'
            print r'    memset(&Desc, 0, sizeof Desc);'
            print r'    Desc.Width = 8;'
            print r'    Desc.Height = 8;'
            print r'    Desc.MipLevels = 1;'
            print r'    Desc.ArraySize = 1;'
            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
            print r'    Desc.SampleDesc.Count = 1;'
            print r'    Desc.SampleDesc.Quality = 0;'
            print r'    Desc.Usage = D3D10_USAGE_DEFAULT;'
            print r'    Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;'
            print r'    Desc.CPUAccessFlags = 0x0;'
            print r'    Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;'
            print r'''
            const DWORD Checker[8][8] = {
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, }
            };
            const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            '''
            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, (ID3D10Texture2D**)ppResource);'
            self.checkResult(method.type)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print r'    MapFlags &= ~%s;' % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name == 'Map':
            print '    _MAP_DESC _MapDesc;'
            print '    _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames())
            print '    size_t _MappedSize = _MapDesc.Size;'
            print '    if (_MapDesc.Size) {'
            print '        _maps[_this] = _MapDesc.pData;'
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name == 'Unmap':
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'
Пример #14
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ("IDirect3DDevice9", "IDirect3DDevice9Ex"):
            if method.name == "Release":
                print r"    if (call.ret->toUInt() == 0) {"
                print r"        d3d9Dumper.unbindDevice(_this);"
                print r"    }"
            else:
                print r"    d3d9Dumper.bindDevice(_this);"
        if interface.name in ("IDirect3DDevice8", "IDirect3DDevice8Ex"):
            if method.name == "Release":
                print r"    if (call.ret->toUInt() == 0) {"
                print r"        d3d8Dumper.unbindDevice(_this);"
                print r"    }"
            else:
                print r"    d3d8Dumper.bindDevice(_this);"

        # create windows as neccessary
        if method.name in ("CreateDevice", "CreateDeviceEx", "CreateAdditionalSwapChain"):
            print r"    HWND hWnd = pPresentationParameters->hDeviceWindow;"
            if "hFocusWindow" in method.argNames():
                print r"    if (hWnd == NULL) {"
                print r"        hWnd = hFocusWindow;"
                print r"    }"
            print r"    hWnd = d3dretrace::createWindow(hWnd, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);"
            print r"    pPresentationParameters->hDeviceWindow = hWnd;"
            if "hFocusWindow" in method.argNames():
                print r"    hFocusWindow = hWnd;"

            # force windowed mode
            print r"    if (retrace::forceWindowed) {"
            print r"        pPresentationParameters->Windowed = TRUE;"
            print r"        pPresentationParameters->FullScreen_RefreshRateInHz = 0;"
            if interface.name.startswith("IDirect3D8"):
                print r"        pPresentationParameters->FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;"
            print r"    }"
            if "BehaviorFlags" in method.argNames():
                print r"    if (retrace::dumpingState) {"
                print r"        BehaviorFlags &= ~D3DCREATE_PUREDEVICE;"
                print r"    }"

            # On D3D8, ensure we use BackBufferFormat compatible with the
            # current DisplayFormat.
            #
            # TODO: BackBufferFormat doesn't need to be always exectly to
            # DisplayFormat.  For example, if DisplayFormat is D3DFMT_X1R5G5B5,
            # valid values for BackBufferFormat include D3DFMT_X1R5G5B5 and
            # D3DFMT_A1R5G5B5, but exclude D3DFMT_R5G6B5.
            if interface.name.startswith("IDirect3D8"):
                print r"    if (pPresentationParameters->Windowed) {"
                print r"        D3DDISPLAYMODE Mode;"
                print r"        HRESULT hr;"
                print r"        hr = _this->GetAdapterDisplayMode(Adapter, &Mode);"
                print r"        assert(SUCCEEDED(hr));"
                print r"        hr = _this->CheckDeviceType(Adapter, DeviceType, Mode.Format, pPresentationParameters->BackBufferFormat, pPresentationParameters->Windowed);"
                print r"        if (hr == D3DERR_NOTAVAILABLE) {"
                print r'            retrace::warning(call) << "forcing back buffer format to match display mode format\n";'
                print r"            pPresentationParameters->BackBufferFormat = Mode.Format;"
                print r"        }"
                print r"    }"

        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r"    switch (retrace::driver) {"
            print r"    case retrace::DRIVER_HARDWARE:"
            print r"        DeviceType = D3DDEVTYPE_HAL;"
            print r"        break;"
            print r"    case retrace::DRIVER_SOFTWARE:"
            print r"    case retrace::DRIVER_REFERENCE:"
            print r"        DeviceType = D3DDEVTYPE_REF;"
            print r"        break;"
            print r"    case retrace::DRIVER_NULL:"
            if interface.name.startswith("IDirect3D9"):
                print r"        DeviceType = D3DDEVTYPE_NULLREF;"
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r"        break;"
            print r"    case retrace::DRIVER_MODULE:"
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r"        break;"
            print r"    default:"
            print r"        assert(0);"
            print r"        /* fall-through */"
            print r"    case retrace::DRIVER_DEFAULT:"
            print r"        break;"
            print r"    }"

        if method.name in ("Reset", "ResetEx"):
            # force windowed mode
            print r"    if (retrace::forceWindowed) {"
            print r"        pPresentationParameters->Windowed = TRUE;"
            print r"        pPresentationParameters->FullScreen_RefreshRateInHz = 0;"
            print r"    }"
            # resize window
            print r"    if (pPresentationParameters->Windowed) {"
            print r"        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);"
            print r"    }"

        # notify frame has been completed
        if method.name in ("Present", "PresentEx"):
            if interface.name.startswith("IDirect3DSwapChain9"):
                print r"    d3d9scDumper.bindDevice(_this);"
            print r"    retrace::frameComplete(call);"
            print r"    hDestWindowOverride = NULL;"

        # Ensure textures can be locked when dumping
        # TODO: Pre-check with CheckDeviceFormat
        if method.name in ("CreateTexture", "CreateCubeTexture", "CreateVolumeTexture"):
            print r"    if (retrace::dumpingState &&"
            print r"        Pool == D3DPOOL_DEFAULT &&"
            print r"        !(Usage & (D3DUSAGE_RENDERTARGET|D3DUSAGE_DEPTHSTENCIL))) {"
            print r"        Usage |= D3DUSAGE_DYNAMIC;"
            print r"    }"

        # Deal with shared surfaces
        # https://msdn.microsoft.com/en-us/library/windows/desktop/bb219800.aspx
        # https://msdn.microsoft.com/en-gb/library/windows/desktop/ee913554.aspx
        pSharedHandleArg = method.getArgByName("pSharedHandle")
        if pSharedHandleArg:
            print r"    if (pSharedHandle) {"
            if method.name == "CreateTexture":
                # Some applications (e.g., DOTA2) create shared resources within the same process.
                # https://msdn.microsoft.com/en-us/library/windows/desktop/bb219800.aspx#Textures
                print r"        if (Pool == D3DPOOL_SYSTEMMEM) {"
                print r"            // Ensure the memory stays around."
                print r"            trace::Blob *blob = call.arg(%u).toArray()->values[0]->toBlob();" % pSharedHandleArg.index
                print r"            if (blob) {"
                print r"                blob->toPointer(true);"
                print r"            } else {"
                print r'                retrace::warning(call) << "invalid system memory\n";'
                print r"                pSharedHandle = NULL;"
                print r"            }"
                print r"        } else {"
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r"        pSharedHandle = NULL;"
            if method.name == "CreateTexture":
                print r"        }"
            print r"    }"

        if method.name in ("Lock", "LockRect", "LockBox"):
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName("Flags")
            for flag in mapFlagsArg.type.values:
                if flag.endswith("_DONOTWAIT"):
                    print r"    Flags &= ~%s;" % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in self.createDeviceMethodNames:
            print r"    if (FAILED(_result)) {"
            print r"        exit(1);"
            print r"    }"

        # process events after presents
        if method.name == "Present":
            print r"    d3dretrace::processEvents();"

        def mapping_subkey():
            if "Level" in method.argNames():
                return ("Level",)
            else:
                return ("0",)

        if method.name in ("Lock", "LockRect", "LockBox"):
            print "    VOID *_pbData = NULL;"
            print "    size_t _MappedSize = 0;"
            print "    if (!(Flags & D3DLOCK_READONLY)) {"
            print "        _getMapInfo(_this, %s, _pbData, _MappedSize);" % ", ".join(method.argNames()[:-1])
            print "    }"
            print "    if (_MappedSize) {"
            print "        _maps[MappingKey(_this, %s)] = _pbData;" % mapping_subkey()
            self.checkPitchMismatch(method)
            print "    } else {"
            print "        return;"
            print "    }"

        if method.name in ("Unlock", "UnlockRect", "UnlockBox"):
            print "    VOID *_pbData = 0;"
            print "    MappingKey _mappingKey(_this, %s);" % mapping_subkey()
            print "    _pbData = _maps[_mappingKey];"
            print "    if (_pbData) {"
            print "        retrace::delRegionByPointer(_pbData);"
            print "        _maps[_mappingKey] = 0;"
            print "    }"
Пример #15
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d9Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d8Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'

            # On D3D8, ensure we use BackBufferFormat compatible with the
            # current DisplayFormat.
            #
            # TODO: BackBufferFormat doesn't need to be always exectly to
            # DisplayFormat.  For example, if DisplayFormat is D3DFMT_X1R5G5B5,
            # valid values for BackBufferFormat include D3DFMT_X1R5G5B5 and
            # D3DFMT_A1R5G5B5, but exclude D3DFMT_R5G6B5.
            if interface.name.startswith('IDirect3D8'):
                print r'    D3DDISPLAYMODE Mode;'
                print r'    HRESULT hr;'
                print r'    hr = _this->GetAdapterDisplayMode(Adapter, &Mode);'
                print r'    hr = _this->CheckDeviceType(Adapter, DeviceType, Mode.Format, pPresentationParameters->BackBufferFormat, pPresentationParameters->Windowed);'
                print r'    if (hr == D3DERR_NOTAVAILABLE) {'
                print r'        retrace::warning(call) << "forcing back buffer format to match display mode format\n";'
                print r'        pPresentationParameters->BackBufferFormat = Mode.Format;'
                print r'    };'
        
        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
            # resize window
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name in ('Present', 'PresentEx'):
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        # Ensure textures can be locked when dumping
        # TODO: Pre-check with CheckDeviceFormat
        if method.name in ('CreateTexture', 'CreateCubeTexture', 'CreateVolumeTexture'):
            print r'    if (retrace::dumpingState &&'
            print r'        Pool == D3DPOOL_DEFAULT &&'
            print r'        !(Usage & (D3DUSAGE_RENDERTARGET|D3DUSAGE_DEPTHSTENCIL))) {'
            print r'        Usage |= D3DUSAGE_DYNAMIC;'
            print r'    }'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('Flags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_DONOTWAIT'):
                    print r'    Flags &= ~%s;' % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in self.createDeviceMethodNames:
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        def mapping_subkey():
            if 'Level' in method.argNames():
                return ('Level',)
            else:
                return ('0',)

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[MappingKey(_this, %s)] = _pbData;' % mapping_subkey()
            self.checkPitchMismatch(method)
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    MappingKey _mappingKey(_this, %s);' % mapping_subkey()
            print '    _pbData = _maps[_mappingKey];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_mappingKey] = 0;'
            print '    }'
Пример #16
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d9Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d8Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
        
        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
            # resize window
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name in ('Present', 'PresentEx'):
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        # Ensure textures can be locked when dumping
        # TODO: Pre-check with CheckDeviceFormat
        if method.name in ('CreateTexture', 'CreateCubeTexture', 'CreateVolumeTexture'):
            print r'    if (retrace::dumpingState &&'
            print r'        Pool == D3DPOOL_DEFAULT &&'
            print r'        !(Usage & (D3DUSAGE_RENDERTARGET|D3DUSAGE_DEPTHSTENCIL))) {'
            print r'        Usage |= D3DUSAGE_DYNAMIC;'
            print r'    }'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('Flags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_DONOTWAIT'):
                    print r'    Flags &= ~%s;' % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in self.createDeviceMethodNames:
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            self.checkPitchMismatch(method)
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'
Пример #17
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    d3d9Dumper.unbindDevice(_this);'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    d3d8Dumper.unbindDevice(_this);'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'
        
        if method.name in ('CreateDevice', 'CreateDeviceEx'):
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name == 'Present':
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'
            print r'    Sleep(500);'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'
Пример #18
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice7',):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d7Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d7Dumper.bindDevice(_this);'

        # create windows as neccessary
        hWndArg = method.getArgByType(HWND)
        if hWndArg is not None:
            # FIXME: Try to guess the window size (e.g., from IDirectDrawSurface7::Blt)
            print r'    if (!g_hWnd) {'
            print r'        g_hWnd = d3dretrace::createWindow(512, 512);'
            print r'    }'
            print r'    %s = g_hWnd;' % hWndArg.name


        if method.name == 'Lock':
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('dwFlags')
            if mapFlagsArg is not None:
                print r'    dwFlags &= DDLOCK_DONOTWAIT;'
                print r'    dwFlags |= DDLOCK_WAIT;'

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name == 'CreateDevice':
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # notify frame has been completed
        # process events after presents
        if interface.name == 'IDirectDrawSurface7' and method.name == 'Blt':
            print r'    DDSCAPS2 ddsCaps;'
            print r'    if (SUCCEEDED(_this->GetCaps(&ddsCaps)) &&'
            print r'        (ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {'
            print r'        retrace::frameComplete(call);'
            print r'        d3dretrace::processEvents();'
            print r'    }'

        if method.name == 'Lock':
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            # FIXME: determine the mapping size
            #print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            # TODO: check pitches match
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name == 'Unlock':
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'
Пример #19
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d10Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name in ('ID3D11DeviceContext', 'ID3D11DeviceContext1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d11Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    if (_this->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) {'
                print r'        d3d11Dumper.bindDevice(_this);'
                print r'    }'

        # intercept private interfaces
        if method.name == 'QueryInterface':
            print r'    if (!d3dretrace::overrideQueryInterface(_this, riid, ppvObj, &_result)) {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    d3dretrace::createWindowForSwapChain(pDesc);'
        if method.name == 'CreateSwapChainForComposition':
            print r'    HWND hWnd = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            print r'    _result = _this->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, NULL, pRestrictToOutput, ppSwapChain);'
            self.checkResult(method.type)
            return

        if method.name == 'SetFullscreenState':
            print r'    if (retrace::forceWindowed) {'
            print r'         Fullscreen = FALSE;'
            print r'         pTarget = NULL;'
            print r'    }'

        # notify frame has been completed
        if method.name == 'Present':
            if interface.name == 'IDXGISwapChainDWM':
                print r'    com_ptr<IDXGISwapChain> pSwapChain;'
                print r'    if (SUCCEEDED(_this->QueryInterface(IID_IDXGISwapChain, (void **) &pSwapChain))) {'
                print r'        dxgiDumper.bindDevice(pSwapChain);'
                print r'    } else {'
                print r'        assert(0);'
                print r'    }'
            else:
                print r'    dxgiDumper.bindDevice(_this);'
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith('IDXGIFactory') and method.name.startswith('EnumAdapters'):
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, reinterpret_cast<IDXGIAdapter **>(ppAdapter));'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        if interface.name.startswith('ID3D10Device') and method.name.startswith('OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    D3D10_TEXTURE2D_DESC Desc;'
            print r'    memset(&Desc, 0, sizeof Desc);'
            print r'    Desc.Width = 8;'
            print r'    Desc.Height = 8;'
            print r'    Desc.MipLevels = 1;'
            print r'    Desc.ArraySize = 1;'
            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
            print r'    Desc.SampleDesc.Count = 1;'
            print r'    Desc.SampleDesc.Quality = 0;'
            print r'    Desc.Usage = D3D10_USAGE_DEFAULT;'
            print r'    Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;'
            print r'    Desc.CPUAccessFlags = 0x0;'
            print r'    Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;'
            print r'''
            static const DWORD Checker[8][8] = {
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U }
            };
            static const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            '''
            print r'    com_ptr<ID3D10Texture2D> pResource;'
            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, &pResource);'
            print r'    if (SUCCEEDED(_result)) {'
            print r'         _result = pResource->QueryInterface(ReturnedInterface, ppResource);'
            print r'    }'
            self.checkResult(method.type)
            return
        if interface.name.startswith('ID3D11Device') and method.name.startswith('OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print
            if method.name == 'OpenSharedResourceByName':
                print r'    (void)lpName;'
                print r'    (void)dwDesiredAccess;'
                print
            print r'    D3D11_TEXTURE2D_DESC Desc;'
            print r'    memset(&Desc, 0, sizeof Desc);'
            print r'    Desc.Width = 8;'
            print r'    Desc.Height = 8;'
            print r'    Desc.MipLevels = 1;'
            print r'    Desc.ArraySize = 1;'
            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
            print r'    Desc.SampleDesc.Count = 1;'
            print r'    Desc.SampleDesc.Quality = 0;'
            print r'    Desc.Usage = D3D11_USAGE_DEFAULT;'
            print r'    Desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;'
            print r'    Desc.CPUAccessFlags = 0x0;'
            print r'    Desc.MiscFlags = 0 /* D3D11_RESOURCE_MISC_SHARED */;'
            print r'''
            static const DWORD Checker[8][8] = {
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U }
            };
            static const D3D11_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            '''
            print r'    com_ptr<ID3D11Texture2D> pResource;'
            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, &pResource);'
            print r'    if (SUCCEEDED(_result)) {'
            print r'         _result = pResource->QueryInterface(ReturnedInterface, ppResource);'
            print r'    }'
            self.checkResult(method.type)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print r'    MapFlags &= ~%s;' % flag

        if method.name.startswith('UpdateSubresource'):
            # The D3D10 debug layer is buggy (or at least inconsistent with the
            # runtime), as it seems to estimate and enforce the data size based on the
            # SrcDepthPitch, even for non 3D textures, but in some traces
            # SrcDepthPitch is garbagge for non 3D textures.
            # XXX: It also seems to expect padding bytes at the end of the last
            # row, but we never record (or allocate) those...
            print r'    if (retrace::debug && pDstBox && pDstBox->front == 0 && pDstBox->back == 1) {'
            print r'        SrcDepthPitch = 0;'
            print r'    }'

        if method.name == 'SetGammaControl':
            # This method is only supported while in full-screen mode
            print r'    if (retrace::forceWindowed) {'
            print r'        return;'
            print r'    }'

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name in ('Map', 'Unmap'):
            if interface.name.startswith('ID3D11DeviceContext'):
                print '    void * & _pbData = g_Maps[_this][SubresourceKey(pResource, Subresource)];'
            else:
                subresourceArg = method.getArgByName('Subresource')
                if subresourceArg is None:
                    print '    UINT Subresource = 0;'
                print '    void * & _pbData = g_Maps[0][SubresourceKey(_this, Subresource)];'

        if method.name == 'Map':
            print '    _MAP_DESC _MapDesc;'
            print '    _getMapDesc(_this, %s, _MapDesc);' % ', '.join(method.argNames())
            print '    size_t _MappedSize = _MapDesc.Size;'
            print '    if (_MapDesc.Size) {'
            print '        _pbData = _MapDesc.pData;'
            if interface.name.startswith('ID3D11DeviceContext'):
                # XXX: Unforunately this cause many false warnings on 1D and 2D
                # resources, since the pitches are junk there...
                #self.checkPitchMismatch(method)
                pass
            else:
                print '        _pbData = _MapDesc.pData;'
                self.checkPitchMismatch(method)
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name == 'Unmap':
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _pbData = 0;'
            print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'
Пример #20
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d10Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name in ('ID3D11DeviceContext', 'ID3D11DeviceContext1'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d11Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    if (_this->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) {'
                print r'        d3d11Dumper.bindDevice(_this);'
                print r'    }'

        # intercept private interfaces
        if method.name == 'QueryInterface':
            print r'    if (!d3dretrace::overrideQueryInterface(_this, riid, ppvObj, &_result)) {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    d3dretrace::createWindowForSwapChain(pDesc);'
        if method.name == 'CreateSwapChainForComposition':
            print r'    HWND hWnd = d3dretrace::createWindow(pDesc->Width, pDesc->Height);'
            print r'    _result = _this->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, NULL, pRestrictToOutput, ppSwapChain);'
            self.checkResult(interface, method)
            return

        if method.name == 'SetFullscreenState':
            print r'    if (retrace::forceWindowed) {'
            print r'         Fullscreen = FALSE;'
            print r'         pTarget = NULL;'
            print r'    }'

        # notify frame has been completed
        if method.name == 'Present':
            if interface.name == 'IDXGISwapChainDWM':
                print r'    com_ptr<IDXGISwapChain> pSwapChain;'
                print r'    if (SUCCEEDED(_this->QueryInterface(IID_IDXGISwapChain, (void **) &pSwapChain))) {'
                print r'        dxgiDumper.bindDevice(pSwapChain);'
                print r'    } else {'
                print r'        assert(0);'
                print r'    }'
            else:
                print r'    dxgiDumper.bindDevice(_this);'
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith(
                'IDXGIFactory') and method.name.startswith('EnumAdapters'):
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, reinterpret_cast<IDXGIAdapter **>(ppAdapter));'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        if interface.name.startswith(
                'ID3D10Device') and method.name.startswith(
                    'OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    D3D10_TEXTURE2D_DESC Desc;'
            print r'    memset(&Desc, 0, sizeof Desc);'
            print r'    Desc.Width = 8;'
            print r'    Desc.Height = 8;'
            print r'    Desc.MipLevels = 1;'
            print r'    Desc.ArraySize = 1;'
            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
            print r'    Desc.SampleDesc.Count = 1;'
            print r'    Desc.SampleDesc.Quality = 0;'
            print r'    Desc.Usage = D3D10_USAGE_DEFAULT;'
            print r'    Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;'
            print r'    Desc.CPUAccessFlags = 0x0;'
            print r'    Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;'
            print r'''
            static const DWORD Checker[8][8] = {
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U }
            };
            static const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            '''
            print r'    com_ptr<ID3D10Texture2D> pResource;'
            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, &pResource);'
            print r'    if (SUCCEEDED(_result)) {'
            print r'         _result = pResource->QueryInterface(ReturnedInterface, ppResource);'
            print r'    }'
            self.checkResult(interface, method)
            return
        if interface.name.startswith(
                'ID3D11Device') and method.name.startswith(
                    'OpenSharedResource'):
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print
            if method.name == 'OpenSharedResourceByName':
                print r'    (void)lpName;'
                print r'    (void)dwDesiredAccess;'
                print
            print r'    D3D11_TEXTURE2D_DESC Desc;'
            print r'    memset(&Desc, 0, sizeof Desc);'
            print r'    Desc.Width = 8;'
            print r'    Desc.Height = 8;'
            print r'    Desc.MipLevels = 1;'
            print r'    Desc.ArraySize = 1;'
            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
            print r'    Desc.SampleDesc.Count = 1;'
            print r'    Desc.SampleDesc.Quality = 0;'
            print r'    Desc.Usage = D3D11_USAGE_DEFAULT;'
            print r'    Desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;'
            print r'    Desc.CPUAccessFlags = 0x0;'
            print r'    Desc.MiscFlags = 0 /* D3D11_RESOURCE_MISC_SHARED */;'
            print r'''
            static const DWORD Checker[8][8] = {
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U },
               { 0U, ~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U },
               {~0U,  0U, ~0U,  0U, ~0U,  0U, ~0U,  0U }
            };
            static const D3D11_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            '''
            print r'    com_ptr<ID3D11Texture2D> pResource;'
            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, &pResource);'
            print r'    if (SUCCEEDED(_result)) {'
            print r'         _result = pResource->QueryInterface(ReturnedInterface, ppResource);'
            print r'    }'
            self.checkResult(interface, method)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print r'    MapFlags &= ~%s;' % flag

        if method.name.startswith('UpdateSubresource'):
            # The D3D10 debug layer is buggy (or at least inconsistent with the
            # runtime), as it seems to estimate and enforce the data size based on the
            # SrcDepthPitch, even for non 3D textures, but in some traces
            # SrcDepthPitch is garbagge for non 3D textures.
            # XXX: It also seems to expect padding bytes at the end of the last
            # row, but we never record (or allocate) those...
            print r'    if (retrace::debug && pDstBox && pDstBox->front == 0 && pDstBox->back == 1) {'
            print r'        SrcDepthPitch = 0;'
            print r'    }'

        if method.name == 'SetGammaControl':
            # This method is only supported while in full-screen mode
            print r'    if (retrace::forceWindowed) {'
            print r'        return;'
            print r'    }'

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name in ('Map', 'Unmap'):
            if interface.name.startswith('ID3D11DeviceContext'):
                print '    void * & _pbData = g_Maps[_this][SubresourceKey(pResource, Subresource)];'
            else:
                subresourceArg = method.getArgByName('Subresource')
                if subresourceArg is None:
                    print '    UINT Subresource = 0;'
                print '    void * & _pbData = g_Maps[0][SubresourceKey(_this, Subresource)];'

        if method.name == 'Map':
            print '    _MAP_DESC _MapDesc;'
            print '    _getMapDesc(_this, %s, _MapDesc);' % ', '.join(
                method.argNames())
            print '    size_t _MappedSize = _MapDesc.Size;'
            print '    if (_MapDesc.Size) {'
            print '        _pbData = _MapDesc.pData;'
            if interface.name.startswith('ID3D11DeviceContext'):
                # XXX: Unforunately this cause many false warnings on 1D and 2D
                # resources, since the pitches are junk there...
                #self.checkPitchMismatch(method)
                pass
            else:
                print '        _pbData = _MapDesc.pData;'
                self.checkPitchMismatch(method)
            print '    } else {'
            print '        return;'
            print '    }'

        if method.name == 'Unmap':
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _pbData = 0;'
            print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'
Пример #21
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d9Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d8Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx',
                           'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = pPresentationParameters->hDeviceWindow;'
            if 'hFocusWindow' in method.argNames():
                print r'    if (hWnd == NULL) {'
                print r'        hWnd = hFocusWindow;'
                print r'    }'
            print r'    hWnd = d3dretrace::createWindow(hWnd, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            if interface.name.startswith('IDirect3D8'):
                print r'        pPresentationParameters->FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;'
            print r'    }'
            if 'BehaviorFlags' in method.argNames():
                print r'    if (retrace::dumpingState) {'
                print r'        BehaviorFlags &= ~D3DCREATE_PUREDEVICE;'
                print r'    }'

            # On D3D8, ensure we use BackBufferFormat compatible with the
            # current DisplayFormat.
            #
            # TODO: BackBufferFormat doesn't need to be always exectly to
            # DisplayFormat.  For example, if DisplayFormat is D3DFMT_X1R5G5B5,
            # valid values for BackBufferFormat include D3DFMT_X1R5G5B5 and
            # D3DFMT_A1R5G5B5, but exclude D3DFMT_R5G6B5.
            if interface.name.startswith('IDirect3D8'):
                print r'    if (pPresentationParameters->Windowed) {'
                print r'        D3DDISPLAYMODE Mode;'
                print r'        HRESULT hr;'
                print r'        hr = _this->GetAdapterDisplayMode(Adapter, &Mode);'
                print r'        assert(SUCCEEDED(hr));'
                print r'        hr = _this->CheckDeviceType(Adapter, DeviceType, Mode.Format, pPresentationParameters->BackBufferFormat, pPresentationParameters->Windowed);'
                print r'        if (hr == D3DERR_NOTAVAILABLE) {'
                print r'            retrace::warning(call) << "forcing back buffer format to match display mode format\n";'
                print r'            pPresentationParameters->BackBufferFormat = Mode.Format;'
                print r'        }'
                print r'    }'

        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
            # resize window
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name in ('Present', 'PresentEx'):
            if interface.name.startswith('IDirect3DSwapChain9'):
                print r'    d3d9scDumper.bindDevice(_this);'
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        # Ensure textures can be locked when dumping
        # TODO: Pre-check with CheckDeviceFormat
        if method.name in ('CreateTexture', 'CreateCubeTexture',
                           'CreateVolumeTexture'):
            print r'    if (retrace::dumpingState &&'
            print r'        Pool == D3DPOOL_DEFAULT &&'
            print r'        !(Usage & (D3DUSAGE_RENDERTARGET|D3DUSAGE_DEPTHSTENCIL))) {'
            print r'        Usage |= D3DUSAGE_DYNAMIC;'
            print r'    }'

        if 'pSharedHandle' in method.argNames():
            print r'    if (pSharedHandle) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('Flags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_DONOTWAIT'):
                    print r'    Flags &= ~%s;' % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name in self.createDeviceMethodNames:
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        def mapping_subkey():
            if 'Level' in method.argNames():
                return ('Level', )
            else:
                return ('0', )

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    if (!(Flags & D3DLOCK_READONLY)) {'
            print '        _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(
                method.argNames()[:-1])
            print '    }'
            print '    if (_MappedSize) {'
            print '        _maps[MappingKey(_this, %s)] = _pbData;' % mapping_subkey(
            )
            self.checkPitchMismatch(method)
            print '    } else {'
            print '        return;'
            print '    }'

        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = 0;'
            print '    MappingKey _mappingKey(_this, %s);' % mapping_subkey()
            print '    _pbData = _maps[_mappingKey];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_mappingKey] = 0;'
            print '    }'
Пример #22
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice7', ):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d7Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d7Dumper.bindDevice(_this);'

        # create windows as neccessary
        hWndArg = method.getArgByType(HWND)
        if hWndArg is not None:
            # FIXME: Try to guess the window size (e.g., from IDirectDrawSurface7::Blt)
            print r'    if (!g_hWnd) {'
            print r'        g_hWnd = d3dretrace::createWindow(512, 512);'
            print r'    }'
            print r'    %s = g_hWnd;' % hWndArg.name

        if method.name == 'Lock':
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('dwFlags')
            if mapFlagsArg is not None:
                print r'    dwFlags &= ~DDLOCK_DONOTWAIT;'
                print r'    dwFlags |= DDLOCK_WAIT;'

        Retracer.invokeInterfaceMethod(self, interface, method)

        if method.name == 'CreateDevice':
            print r'    if (FAILED(_result)) {'
            print r'        exit(1);'
            print r'    }'

        # notify frame has been completed
        # process events after presents
        if interface.name == 'IDirectDrawSurface7' and method.name == 'Blt':
            print r'    DDSCAPS2 ddsCaps;'
            print r'    if (SUCCEEDED(_this->GetCaps(&ddsCaps)) &&'
            print r'        (ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {'
            print r'        retrace::frameComplete(call);'
            print r'        d3dretrace::processEvents();'
            print r'    }'

        if method.name == 'Lock':
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            # FIXME: determine the mapping size
            #print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            # TODO: check pitches match
            print '    } else {'
            print '        return;'
            print '    }'

        if method.name == 'Unlock':
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'
Пример #23
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d9Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d9Dumper.bindDevice(_this);'
        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
            if method.name == 'Release':
                print r'    if (call.ret->toUInt() == 0) {'
                print r'        d3d8Dumper.unbindDevice(_this);'
                print r'    }'
            else:
                print r'    d3d8Dumper.bindDevice(_this);'

        if method.name in self.createDeviceMethodNames:
            # override the device type
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_HARDWARE:'
            print r'    case retrace::DRIVER_DISCRETE:'
            print r'    case retrace::DRIVER_INTEGRATED:'
            print r'        DeviceType = D3DDEVTYPE_HAL;'
            print r'        break;'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        BehaviorFlags &= ~D3DCREATE_PUREDEVICE;'
            print r'        BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;'
            print r'        BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;'
            print r'        break;'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'        DeviceType = D3DDEVTYPE_REF;'
            print r'        BehaviorFlags &= ~D3DCREATE_PUREDEVICE;'
            print r'        BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;'
            print r'        BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;'
            print r'        break;'
            print r'    case retrace::DRIVER_NULL:'
            if interface.name.startswith('IDirect3D9'):
                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
            else:
                print r'        retrace::warning(call) << "null driver not supported\n";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        retrace::warning(call) << "driver module not supported\n";'
            print r'        break;'
            print r'    default:'
            print r'        assert(0);'
            print r'        /* fall-through */'
            print r'    case retrace::DRIVER_DEFAULT:'
            print r'        break;'
            print r'    }'

        # create windows as neccessary
        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
            print r'    HWND hWnd = pPresentationParameters->hDeviceWindow;'
            if 'hFocusWindow' in method.argNames():
                print r'    if (hWnd == NULL) {'
                print r'        hWnd = hFocusWindow;'
                print r'    }'
            print r'    hWnd = d3dretrace::createWindow(hWnd, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
            if 'hFocusWindow' in method.argNames():
                print r'    hFocusWindow = hWnd;'

            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            if interface.name.startswith('IDirect3D8'):
                print r'        pPresentationParameters->FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;'
            print r'    }'
            if 'BehaviorFlags' in method.argNames():
                print r'    if (retrace::dumpingState) {'
                print r'        BehaviorFlags &= ~D3DCREATE_PUREDEVICE;'
                print r'    }'

            # On D3D8, ensure we use BackBufferFormat compatible with the
            # current DisplayFormat.
            #
            # TODO: BackBufferFormat doesn't need to be always exectly to
            # DisplayFormat.  For example, if DisplayFormat is D3DFMT_X1R5G5B5,
            # valid values for BackBufferFormat include D3DFMT_X1R5G5B5 and
            # D3DFMT_A1R5G5B5, but exclude D3DFMT_R5G6B5.
            if interface.name.startswith('IDirect3D8'):
                print r'    if (pPresentationParameters->Windowed) {'
                print r'        D3DDISPLAYMODE Mode;'
                print r'        HRESULT hr;'
                print r'        hr = _this->GetAdapterDisplayMode(Adapter, &Mode);'
                print r'        assert(SUCCEEDED(hr));'
                print r'        hr = _this->CheckDeviceType(Adapter, DeviceType, Mode.Format, pPresentationParameters->BackBufferFormat, pPresentationParameters->Windowed);'
                print r'        if (hr == D3DERR_NOTAVAILABLE) {'
                print r'            retrace::warning(call) << "forcing back buffer format to match display mode format\n";'
                print r'            pPresentationParameters->BackBufferFormat = Mode.Format;'
                print r'        }'
                print r'    }'

        if method.name in ('Reset', 'ResetEx'):
            # force windowed mode
            print r'    if (retrace::forceWindowed) {'
            print r'        pPresentationParameters->Windowed = TRUE;'
            print r'        pPresentationParameters->FullScreen_RefreshRateInHz = 0;'
            print r'    }'
            # resize window
            print r'    if (pPresentationParameters->Windowed) {'
            print r'        d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
            print r'    }'

        # notify frame has been completed
        if method.name in ('Present', 'PresentEx'):
            if interface.name.startswith('IDirect3DSwapChain9'):
                print r'    d3d9scDumper.bindDevice(_this);'
            print r'    retrace::frameComplete(call);'
            print r'    hDestWindowOverride = NULL;'

        # Ensure textures can be locked when dumping
        # TODO: Pre-check with CheckDeviceFormat
        if method.name in ('CreateTexture', 'CreateCubeTexture', 'CreateVolumeTexture'):
            print r'    if (retrace::dumpingState &&'
            print r'        Pool == D3DPOOL_DEFAULT &&'
            print r'        !(Usage & (D3DUSAGE_RENDERTARGET|D3DUSAGE_DEPTHSTENCIL))) {'
            print r'        Usage |= D3DUSAGE_DYNAMIC;'
            print r'    }'

        # Deal with shared surfaces
        # https://msdn.microsoft.com/en-us/library/windows/desktop/bb219800.aspx
        # https://msdn.microsoft.com/en-gb/library/windows/desktop/ee913554.aspx
        pSharedHandleArg = method.getArgByName('pSharedHandle')
        if pSharedHandleArg:
            print r'    if (pSharedHandle) {'
            if method.name == 'CreateTexture':
                # Some applications (e.g., DOTA2) create shared resources within the same process.
                # https://msdn.microsoft.com/en-us/library/windows/desktop/bb219800.aspx#Textures
                print r'        if (Pool == D3DPOOL_SYSTEMMEM) {'
                print r'            // Ensure the memory stays around.'
                print r'            trace::Blob *blob = call.arg(%u).toArray()->values[0]->toBlob();' % pSharedHandleArg.index
                print r'            if (blob) {'
                print r'                blob->toPointer(true);'
                print r'            } else {'
                print r'                retrace::warning(call) << "invalid system memory\n";'
                print r'                pSharedHandle = NULL;'
                print r'            }'
                print r'        } else {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedHandle = NULL;'
            if method.name == 'CreateTexture':
                print r'        }'
            print r'    }'

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            # Reset _DONOTWAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('Flags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_DONOTWAIT'):
                    print r'    Flags &= ~%s;' % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        def mapping_subkey():
            # A single texture object might have multiple mappings.  This key
            # allows to tell them apart.
            if 'FaceType' in method.argNames():
                return ('static_cast<UINT>(FaceType) + Level*6',)
            elif 'Level' in method.argNames():
                return ('Level',)
            else:
                return ('0',)

        if method.name in ('Lock', 'LockRect', 'LockBox'):
            print '    VOID *_pbData = nullptr;'
            print '    size_t _MappedSize = 0;'
            if method.name == 'Lock':
                # Ignore D3DLOCK_READONLY for buffers.
                # https://github.com/apitrace/apitrace/issues/435
                print '    if (true) {'
            else:
                print '    if (!(Flags & D3DLOCK_READONLY)) {'
            print '        _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(method.argNames()[:-1])
            print '    }'
            print '    if (_MappedSize) {'
            print '        _maps[MappingKey(_this, %s)] = _pbData;' % mapping_subkey()
            self.checkPitchMismatch(method)
            print '    } else {'
            print '        return;'
            print '    }'
        
        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
            print '    VOID *_pbData = nullptr;'
            print '    MappingKey _mappingKey(_this, %s);' % mapping_subkey()
            print '    _pbData = _maps[_mappingKey];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_mappingKey] = nullptr;'
            print '    }'

        if interface.name == 'IDirectXVideoDecoder':
            if method.name == 'GetBuffer':
                print '    if (*ppBuffer && *pBufferSize) {'
                print '        _maps[MappingKey(_this, BufferType)] = *ppBuffer;'
                print '    }'
            if method.name == 'ReleaseBuffer':
                print '    MappingKey _mappingKey(_this, BufferType);'
                print '    void *_pBuffer = _maps[_mappingKey];'
                print '    if (_pBuffer) {'
                print '        retrace::delRegionByPointer(_pBuffer);'
                print '        _maps[_mappingKey] = nullptr;'
                print '    }'
Пример #24
0
    def invokeInterfaceMethod(self, interface, method):
        # keep track of the last used device for state dumping
        if interface.name in ('ID3D10Device', 'ID3D10Device1'):
            if method.name == 'Release':
                print r'    d3d10Dumper.unbindDevice(_this);'
            else:
                print r'    d3d10Dumper.bindDevice(_this);'
        if interface.name in ('ID3D11DeviceContext', 'ID3D11DeviceContext1'):
            if method.name == 'Release':
                print r'    d3d11Dumper.unbindDevice(_this);'
            else:
                print r'    d3d11Dumper.bindDevice(_this);'

        if interface.name == 'IDXGIFactory' and method.name == 'QueryInterface':
            print r'    if (riid == IID_IDXGIFactoryDWM) {'
            print r'        _this->AddRef();'
            print r'        *ppvObj = new d3dretrace::CDXGIFactoryDWM(_this);'
            print r'        _result = S_OK;'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        # create windows as neccessary
        if method.name == 'CreateSwapChain':
            print r'    createWindow(pDesc);'

        # notify frame has been completed
        if method.name == 'Present':
            print r'    retrace::frameComplete(call);'

        if 'pSharedResource' in method.argNames():
            print r'    if (pSharedResource) {'
            print r'        retrace::warning(call) << "shared surfaces unsupported\n";'
            print r'        pSharedResource = NULL;'
            print r'    }'

        # Force driver
        if interface.name.startswith(
                'IDXGIFactory') and method.name == 'EnumAdapters':
            print r'    const char *szSoftware = NULL;'
            print r'    switch (retrace::driver) {'
            print r'    case retrace::DRIVER_REFERENCE:'
            print r'    case retrace::DRIVER_SOFTWARE:'
            print r'        szSoftware = "d3d10warp.dll";'
            print r'        break;'
            print r'    case retrace::DRIVER_MODULE:'
            print r'        szSoftware = retrace::driverModule;'
            print r'        break;'
            print r'    default:'
            print r'        break;'
            print r'    }'
            print r'    HMODULE hSoftware = NULL;'
            print r'    if (szSoftware) {'
            print r'        hSoftware = LoadLibraryA(szSoftware);'
            print r'        if (!hSoftware) {'
            print r'            retrace::warning(call) << "failed to load " << szSoftware << "\n";'
            print r'        }'
            print r'    }'
            print r'    if (hSoftware) {'
            print r'        _result = _this->CreateSoftwareAdapter(hSoftware, ppAdapter);'
            print r'    } else {'
            Retracer.invokeInterfaceMethod(self, interface, method)
            print r'    }'
            return

        if interface.name.startswith(
                'ID3D10Device') and method.name == 'OpenSharedResource':
            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
            print r'    D3D10_TEXTURE2D_DESC Desc;'
            print r'    memset(&Desc, 0, sizeof Desc);'
            print r'    Desc.Width = 8;'
            print r'    Desc.Height = 8;'
            print r'    Desc.MipLevels = 1;'
            print r'    Desc.ArraySize = 1;'
            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
            print r'    Desc.SampleDesc.Count = 1;'
            print r'    Desc.SampleDesc.Quality = 0;'
            print r'    Desc.Usage = D3D10_USAGE_DEFAULT;'
            print r'    Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;'
            print r'    Desc.CPUAccessFlags = 0x0;'
            print r'    Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;'
            print r'''
            const DWORD Checker[8][8] = {
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
               {~0,  0, ~0,  0, ~0,  0, ~0,  0, }
            };
            const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
            '''
            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, (ID3D10Texture2D**)ppResource);'
            self.checkResult(method.type)
            return

        if method.name == 'Map':
            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
            # way to cope with it (other than retry).
            mapFlagsArg = method.getArgByName('MapFlags')
            for flag in mapFlagsArg.type.values:
                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
                    print r'    MapFlags &= ~%s;' % flag

        Retracer.invokeInterfaceMethod(self, interface, method)

        # process events after presents
        if method.name == 'Present':
            print r'    d3dretrace::processEvents();'

        if method.name == 'Map':
            print '    VOID *_pbData = NULL;'
            print '    size_t _MappedSize = 0;'
            print '    _getMapInfo(_this, %s, _pbData, _MappedSize);' % ', '.join(
                method.argNames())
            print '    if (_MappedSize) {'
            print '        _maps[_this] = _pbData;'
            print '    } else {'
            print '        return;'
            print '    }'

        if method.name == 'Unmap':
            print '    VOID *_pbData = 0;'
            print '    _pbData = _maps[_this];'
            print '    if (_pbData) {'
            print '        retrace::delRegionByPointer(_pbData);'
            print '        _maps[_this] = 0;'
            print '    }'

        # Attach shader byte code for lookup
        if 'pShaderBytecode' in method.argNames():
            ppShader = method.args[-1]
            assert ppShader.output
            print r'    if (retrace::dumpingState && SUCCEEDED(_result)) {'
            print r'        (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
            print r'    }'