Exemple #1
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if 'pSwapChainDesc' in function.argNames():
                print r'    d3dretrace::createWindowForSwapChain(pSwapChainDesc);'

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith('D3D11CreateDevice'):
                print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
                print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
                print r'    }'

            if function.name.startswith('D3D10CreateDevice'):
                # Toggle debugging
                print r'    if (retrace::debug >= 2) {'
                print r'        Flags |= D3D10_CREATE_DEVICE_DEBUG;'
                print r'    } else if (retrace::debug < 0) {'
                print r'        Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
                print r'    }'

                # Force driver
                self.forceDriver('D3D10_DRIVER_TYPE')

            if function.name.startswith('D3D11CreateDevice'):
                # Toggle debugging
                print r'    if (retrace::debug >= 2) {'
                print r'        Flags |= D3D11_CREATE_DEVICE_DEBUG;'
                print r'    } else if (retrace::debug < 0) {'
                print r'        Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
                print r'    }'

                # Force driver
                self.forceDriver('D3D_DRIVER_TYPE')

        Retracer.invokeFunction(self, function)
Exemple #2
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses'
        print 'typedef std::pair<void *, UINT> MappingKey;'
        print 'static std::map<MappingKey, void *> _maps;'
        print

        Retracer.retraceApi(self, api)
Exemple #3
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if 'pSwapChainDesc' in function.argNames():
                print r'    d3dretrace::createWindowForSwapChain(pSwapChainDesc);'

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith('D3D11CreateDevice'):
                print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
                print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
                print r'    }'

            if function.name.startswith('D3D10CreateDevice'):
                # Toggle debugging
                print r'    if (retrace::debug) {'
                print r'        Flags |= D3D10_CREATE_DEVICE_DEBUG;'
                print r'    } else {'
                print r'        Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
                print r'    }'

                # Force driver
                self.forceDriver('D3D10_DRIVER_TYPE')

            if function.name.startswith('D3D11CreateDevice'):
                # Toggle debugging
                print r'    if (retrace::debug) {'
                print r'        Flags |= D3D11_CREATE_DEVICE_DEBUG;'
                print r'    } else {'
                print r'        Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
                print r'    }'

                # Force driver
                self.forceDriver('D3D_DRIVER_TYPE')

        Retracer.invokeFunction(self, function)
Exemple #4
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses'
        print 'static std::map<void *, void *> _maps;'
        print
        self.table_name = 'd3dretrace::dxgi_callbacks'

        Retracer.retraceApi(self, api)
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses'
        print 'static std::map<void *, void *> _maps;'
        print
        self.table_name = 'd3dretrace::dxgi_callbacks'

        Retracer.retraceApi(self, api)
Exemple #6
0
    def retraceApi(self, api):
        print 'static const GUID GUID_D3DRETRACE = {0x7D71CAC9,0x7F58,0x432C,{0xA9,0x75,0xA1,0x9F,0xCF,0xCE,0xFD,0x14}};'
        print

        self.table_name = 'd3dretrace::%s_callbacks' % api.name.lower()

        Retracer.retraceApi(self, api)
Exemple #7
0
    def retraceApi(self, api):
        print 'static const GUID GUID_D3DRETRACE = {0x7D71CAC9,0x7F58,0x432C,{0xA9,0x75,0xA1,0x9F,0xCF,0xCE,0xFD,0x14}};'
        print

        self.table_name = 'd3dretrace::%s_callbacks' % api.name.lower()

        Retracer.retraceApi(self, api)
Exemple #8
0
    def handleFailure(self, interface, methodOrFunction):
        # Catch when device is removed, and report the reason.
        if interface is not None:
            print(r'        if (_result == DXGI_ERROR_DEVICE_REMOVED) {')
            print(r'            d3dretrace::deviceRemoved(call, _this);')
            print(r'        }')

        Retracer.handleFailure(self, interface, methodOrFunction)
Exemple #9
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses, mapping a (pDeviceContext, pResource, Subresource) -> void *'
        print 'typedef std::pair< IUnknown *, UINT > SubresourceKey;'
        print 'static std::map< IUnknown *, std::map< SubresourceKey, void * > > g_Maps;'
        print
        self.table_name = 'd3dretrace::dxgi_callbacks'

        Retracer.retraceApi(self, api)
Exemple #10
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses, mapping a (pDeviceContext, pResource, Subresource) -> void *'
        print 'typedef std::pair< IUnknown *, UINT > SubresourceKey;'
        print 'static std::map< IUnknown *, std::map< SubresourceKey, void * > > g_Maps;'
        print
        self.table_name = 'd3dretrace::dxgi_callbacks'

        Retracer.retraceApi(self, api)
Exemple #11
0
    def doInvokeInterfaceMethod(self, interface, method):
        Retracer.doInvokeInterfaceMethod(self, interface, method)

        # Keep retrying IDirectXVideoDecoder::BeginFrame when returns E_PENDING
        if interface.name == 'IDirectXVideoDecoder' and method.name == 'BeginFrame':
            print r'    while (_result == E_PENDING) {'
            print r'        Sleep(1);'
            Retracer.doInvokeInterfaceMethod(self, interface, method)
            print r'    }'
Exemple #12
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if 'pSwapChainDesc' in function.argNames():
                print(r'    if (pSwapChainDesc) {')
                print(r'        d3dretrace::createWindowForSwapChain(pSwapChainDesc);')
                print(r'    }')

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith('D3D11CreateDevice'):
                print(r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {')
                print(r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;')
                print(r'    }')

            if function.name.startswith('D3D10CreateDevice'):
                # Toggle debugging
                print(r'    if (retrace::debug >= 2) {')
                print(r'        Flags |= D3D10_CREATE_DEVICE_DEBUG;')
                print(r'    } else if (retrace::debug < 0) {')
                print(r'        Flags &= ~D3D10_CREATE_DEVICE_DEBUG;')
                print(r'    }')

                # Force driver
                self.forceDriver('D3D10_DRIVER_TYPE')

            if function.name.startswith('D3D11CreateDevice'):
                # Toggle debugging
                print(r'    if (retrace::debug >= 2) {')
                print(r'        Flags |= D3D11_CREATE_DEVICE_DEBUG;')
                print(r'    } else if (retrace::debug < 0) {')
                print(r'        Flags &= ~D3D11_CREATE_DEVICE_DEBUG;')
                print(r'    }')
                print(r'    if (IsWindows8OrGreater()) {')
                print(r'        Flags |= D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT;')
                print(r'    }')

                # Force driver
                self.forceDriver('D3D_DRIVER_TYPE')

        Retracer.invokeFunction(self, function)

        if function.name in self.createDeviceFunctionNames:
            print(r'''
    if (retrace::driver != retrace::DRIVER_DEFAULT &&
        ppDevice && *ppDevice) {
        com_ptr<IDXGIDevice> pDXGIDevice;
        HRESULT hr = (*ppDevice)->QueryInterface(IID_IDXGIDevice, (void **)&pDXGIDevice);
        assert(SUCCEEDED(hr));
        com_ptr<IDXGIAdapter> pDXGIAdapter;
        hr = pDXGIDevice->GetAdapter(&pDXGIAdapter);
        assert(SUCCEEDED(hr));
        DXGI_ADAPTER_DESC AdapterDesc;
        hr = pDXGIAdapter->GetDesc(&AdapterDesc);
        assert(SUCCEEDED(hr));
        std::wcerr << L"info: using " << AdapterDesc.Description << std::endl;
    }
''')
Exemple #13
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses'
        print 'static std::map<void *, void *> _maps;'
        print
        # TODO: Keep a table of windows
        print 'static HWND g_hWnd;'
        print

        Retracer.retraceApi(self, api)
Exemple #14
0
    def doInvokeInterfaceMethod(self, interface, method):
        Retracer.doInvokeInterfaceMethod(self, interface, method)

        # Keep retrying ID3D11VideoContext::DecoderBeginFrame when returns E_PENDING
        if interface.name == 'ID3D11VideoContext' and method.name == 'DecoderBeginFrame':
            print r'    while (_result == D3DERR_WASSTILLDRAWING || _result == E_PENDING) {'
            print r'        Sleep(1);'
            Retracer.doInvokeInterfaceMethod(self, interface, method)
            print r'    }'
Exemple #15
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses'
        print 'static std::map<void *, void *> _maps;'
        print
        # TODO: Keep a table of windows
        print 'static HWND g_hWnd;'
        print

        Retracer.retraceApi(self, api)
Exemple #16
0
    def doInvokeInterfaceMethod(self, interface, method):
        Retracer.doInvokeInterfaceMethod(self, interface, method)

        # Keep retrying ID3D11VideoContext::DecoderBeginFrame when returns E_PENDING
        if interface.name == 'ID3D11VideoContext' and method.name == 'DecoderBeginFrame':
            print r'    while (_result == D3DERR_WASSTILLDRAWING || _result == E_PENDING) {'
            print r'        Sleep(1);'
            Retracer.doInvokeInterfaceMethod(self, interface, method)
            print r'    }'
Exemple #17
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if 'pSwapChainDesc' in function.argNames():
                print(r'    if (pSwapChainDesc) {')
                print(
                    r'        d3dretrace::createWindowForSwapChain(pSwapChainDesc);'
                )
                print(r'    }')

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith('D3D11CreateDevice'):
                print(
                    r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
                )
                print(r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;')
                print(r'    }')

            if function.name.startswith('D3D10CreateDevice'):
                # Toggle debugging
                print(r'    if (retrace::debug >= 2) {')
                print(r'        Flags |= D3D10_CREATE_DEVICE_DEBUG;')
                print(r'    } else if (retrace::debug < 0) {')
                print(r'        Flags &= ~D3D10_CREATE_DEVICE_DEBUG;')
                print(r'    }')

                # D3D10CreateDevice(D3D10_DRIVER_TYPE_REFERENCE) fails with
                # DXGI_ERROR_UNSUPPORTED on 64bits.
                print(r'#ifdef _WIN64')
                print(r'    if (DriverType == D3D10_DRIVER_TYPE_REFERENCE) {')
                print(r'        DriverType = D3D10_DRIVER_TYPE_WARP;')
                print(r'    }')
                print(r'#endif')

                # Force driver
                self.forceDriver('D3D10_DRIVER_TYPE_HARDWARE')

            if function.name.startswith('D3D11CreateDevice'):
                # Toggle debugging
                print(r'    if (retrace::debug >= 2) {')
                print(r'        Flags |= D3D11_CREATE_DEVICE_DEBUG;')
                print(r'    } else if (retrace::debug < 0) {')
                print(r'        Flags &= ~D3D11_CREATE_DEVICE_DEBUG;')
                print(r'    }')
                print(r'    if (IsWindows8OrGreater()) {')
                print(
                    r'        Flags |= D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT;'
                )
                print(r'    }')

                # Force driver
                self.forceDriver('D3D_DRIVER_TYPE_UNKNOWN')

        Retracer.invokeFunction(self, function)
Exemple #18
0
    def extractArg(self, function, arg, arg_type, lvalue, rvalue):
        # Handle DDCREATE_* flags
        if arg.type is DDCREATE_LPGUID:
            print '    if (%s.toArray()) {' % rvalue
            Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
            print '    } else {'
            print '        %s = static_cast<%s>(%s.toPointer());' % (lvalue, arg_type, rvalue)
            print '    }'
            return

        Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
Exemple #19
0
    def handleFailure(self, interface, methodOrFunction):
        # Catch when device is removed, and report the reason.
        if interface is not None:
            getDeviceRemovedReasonMethod = interface.getMethodByName("GetDeviceRemovedReason")
            if getDeviceRemovedReasonMethod is not None:
                print r'        if (_result == DXGI_ERROR_DEVICE_REMOVED) {'
                print r'            HRESULT _reason = _this->GetDeviceRemovedReason();'
                print r'            retrace::failed(call, _reason);'
                print r'            exit(EXIT_FAILURE);'
                print r'        }'

        Retracer.handleFailure(self, interface, methodOrFunction)
Exemple #20
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 '    }'
Exemple #21
0
    def handleFailure(self, interface, methodOrFunction):
        if methodOrFunction.name in self.createDeviceMethodNames:
            print r'        exit(EXIT_FAILURE);'
            return

        # https://msdn.microsoft.com/en-us/library/windows/desktop/bb324479.aspx
        if methodOrFunction.name in ('Present', 'PresentEx'):
            print r'        if (_result == D3DERR_DEVICELOST) {'
            print r'            exit(EXIT_FAILURE);'
            print r'        }'

        Retracer.handleFailure(self, interface, methodOrFunction)
Exemple #22
0
    def extractArg(self, function, arg, arg_type, lvalue, rvalue):
        # Handle DDCREATE_* flags
        if arg.type is DDCREATE_LPGUID:
            print '    if (%s.toArray()) {' % rvalue
            Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
            print '    } else {'
            print '        %s = static_cast<%s>(%s.toPointer());' % (
                lvalue, arg_type, rvalue)
            print '    }'
            return

        Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
Exemple #23
0
    def handleFailure(self, interface, methodOrFunction):
        # Catch when device is removed, and report the reason.
        if interface is not None:
            getDeviceRemovedReasonMethod = interface.getMethodByName("GetDeviceRemovedReason")
            if getDeviceRemovedReasonMethod is not None:
                print r'        if (_result == DXGI_ERROR_DEVICE_REMOVED) {'
                print r'            HRESULT _reason = _this->GetDeviceRemovedReason();'
                print r'            retrace::failed(call, _reason);'
                print r'            exit(EXIT_FAILURE);'
                print r'        }'

        Retracer.handleFailure(self, interface, methodOrFunction)
Exemple #24
0
    def invokeFunction(self, function):
        if function.name in ('Direct3DCreate9', 'Direct3DCreate9Ex'):
            print 'if (retrace::debug && !g_szD3D9DllName) {'
            print '    /* '
            print '     * XXX: D3D9D only works for simple things, it often introduces errors'
            print '     * on complex traces, or traces which use unofficial D3D9 features.'
            print '     */'
            print '    if (0) {'
            print '        g_szD3D9DllName = "d3d9d.dll";'
            print '    }'
            print '}'

        Retracer.invokeFunction(self, function)
Exemple #25
0
    def invokeFunction(self, function):
        if function.name in ('Direct3DCreate9', 'Direct3DCreate9Ex'):
            print 'if (retrace::debug && !g_szD3D9DllName) {'
            print '    /* '
            print '     * XXX: D3D9D only works for simple things, it often introduces errors'
            print '     * on complex traces, or traces which use unofficial D3D9 features.'
            print '     */'
            print '    if (0) {'
            print '        g_szD3D9DllName = "d3d9d.dll";'
            print '    }'
            print '}'

        Retracer.invokeFunction(self, function)
Exemple #26
0
    def retraceInterfaceMethodBody(self, interface, method):
        Retracer.retraceInterfaceMethodBody(self, interface, method)

        # Add pitch swizzling information to the region
        if method.name == 'Map' and interface.name not in ('ID3D10Buffer',
                                                           'ID3D10Texture1D'):
            if interface.name.startswith('ID3D11DeviceContext'):
                outArg = method.getArgByName('pMappedResource')
                memberNames = ('pData', 'RowPitch', 'DepthPitch')
            elif interface.name.startswith('ID3D10'):
                outArg = method.args[-1]
                memberNames = ('pData', 'RowPitch', 'DepthPitch')
            elif interface.name == 'IDXGISurface':
                outArg = method.getArgByName('pLockedRect')
                memberNames = ('pBits', 'Pitch', None)
            else:
                raise NotImplementedError
            struct = outArg.type.type
            dataMemberName, rowPitchMemberName, depthPitchMemberName = memberNames
            dataMemberIndex = struct.getMemberByName(dataMemberName)
            rowPitchMemberIndex = struct.getMemberByName(rowPitchMemberName)
            print r'    if (_pbData && %s->%s != 0) {' % (outArg.name,
                                                          rowPitchMemberName)
            print r'        const trace::Array *_%s = call.arg(%u).toArray();' % (
                outArg.name, outArg.index)
            print r'        if (%s) {' % outArg.name
            print r'            const trace::Struct *_struct = _%s->values[0]->toStruct();' % (
                outArg.name)
            print r'            if (_struct) {'
            print r'                unsigned long long traceAddress = _struct->members[%u]->toUIntPtr();' % dataMemberIndex
            print r'                int traceRowPitch = _struct->members[%u]->toSInt();' % rowPitchMemberIndex
            print r'                int realRowPitch = %s->%s;' % (
                outArg.name, rowPitchMemberName)
            print r'                if (realRowPitch && traceRowPitch != realRowPitch) {'
            print r'                    retrace::setRegionPitch(traceAddress, 2, traceRowPitch, realRowPitch);'
            print r'                }'
            try:
                depthPitchMemberIndex = struct.getMemberByName(
                    depthPitchMemberName)
            except ValueError:
                assert len(struct.members) < 3
                pass
            else:
                assert depthPitchMemberName == 'DepthPitch'
                print r'                if (%s->DepthPitch) {' % outArg.name
                print r'                    retrace::checkMismatch(call, "DepthPitch", _struct->members[%u], %s->DepthPitch);' % (
                    struct.getMemberByName('DepthPitch'), outArg.name)
                print r'                }'
            print r'            }'
            print r'        }'
            print r'    }'
Exemple #27
0
    def extractArg(self, function, arg, arg_type, lvalue, rvalue):
        # Set object names
        if function.name == 'SetPrivateData' and arg.name == 'pData':
            iid = function.args[0].name
            print r'    if (%s != WKPDID_D3DDebugObjectName) {' % iid
            print r'        return;'
            print r'    }'
            # Interpret argument as string
            Retracer.extractArg(self, function, arg, LPCSTR, lvalue, rvalue)
            print r'    assert(pData);'
            print r'    assert(DataSize == strlen((const char *)pData));'
            return

        Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
Exemple #28
0
    def invokeFunction(self, function):
        if function.name in ('Direct3DCreate9', 'Direct3DCreate9Ex'):
            print 'if (retrace::debug >= 2 && !g_szD3D9DllName && LoadLibraryA("d3d9d.dll")) {'
            print '    /*'
            print '     * D3D9D only works for simple applications, it will often report bogus errors'
            print '     * on complex traces, or traces which use unofficial D3D9 features.'
            print '     */'
            print '    g_szD3D9DllName = "d3d9d.dll";'
            print '    SDKVersion |= 0x80000000;'
            print '} else {'
            print '    SDKVersion &= ~0x80000000;'
            print '}'

        Retracer.invokeFunction(self, function)
Exemple #29
0
    def extractArg(self, function, arg, arg_type, lvalue, rvalue):
        # Set object names
        if function.name == "SetPrivateData" and arg.name == "pData":
            iid = function.args[0].name
            print r"    if (%s != WKPDID_D3DDebugObjectName) {" % iid
            print r"        return;"
            print r"    }"
            # Interpret argument as string
            Retracer.extractArg(self, function, arg, LPCSTR, lvalue, rvalue)
            print r"    assert(pData);"
            print r"    assert(DataSize == strlen((const char *)pData));"
            return

        Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
Exemple #30
0
    def invokeFunction(self, function):
        if function.name in ('Direct3DCreate9', 'Direct3DCreate9Ex'):
            print 'if (retrace::debug >= 2 && !g_szD3D9DllName && LoadLibraryA("d3d9d.dll")) {'
            print '    /*'
            print '     * D3D9D only works for simple applications, it will often report bogus errors'
            print '     * on complex traces, or traces which use unofficial D3D9 features.'
            print '     */'
            print '    g_szD3D9DllName = "d3d9d.dll";'
            print '    SDKVersion |= 0x80000000;'
            print '} else {'
            print '    SDKVersion &= ~0x80000000;'
            print '}'

        Retracer.invokeFunction(self, function)
Exemple #31
0
    def extractArg(self, function, arg, arg_type, lvalue, rvalue):
        # Set object names
        if function.name == 'SetPrivateData' and arg.name == 'pData':
            iid = function.args[0].name
            print r'    if (%s != WKPDID_D3DDebugObjectName) {' % iid
            print r'        return;'
            print r'    }'
            # Interpret argument as string
            Retracer.extractArg(self, function, arg, LPCSTR, lvalue, rvalue)
            print r'    assert(pData);'
            print r'    assert(DataSize == strlen((const char *)pData));'
            return

        Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
Exemple #32
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 '    }'
Exemple #33
0
    def checkResult(self, interface, methodOrFunction):
        # Catch when device is removed, and report the reason.
        if str(methodOrFunction.type) == 'HRESULT':
            if interface is not None:
                getDeviceRemovedReasonMethod = interface.getMethodByName("GetDeviceRemovedReason")
                if getDeviceRemovedReasonMethod is not None:
                    print r'    if (FAILED(_result)) {'
                    print r'        retrace::failed(call, _result);'
                    print r'        if (_result == DXGI_ERROR_DEVICE_REMOVED) {'
                    print r'            HRESULT _reason = _this->GetDeviceRemovedReason();'
                    print r'            retrace::failed(call, _reason);'
                    print r'            exit(1);'
                    print r'        }'
                    print r'        return;'
                    print r'    }'
                    return

        Retracer.checkResult(self, interface, methodOrFunction)
Exemple #34
0
    def checkResult(self, interface, methodOrFunction):
        if interface is not None and interface.name == 'IDXGIKeyedMutex' and methodOrFunction.name == 'AcquireSync':
            print(r'    if (_result != S_OK) {')
            print(r'        retrace::failed(call, _result);')
            self.handleFailure(interface, methodOrFunction)
            print(r'    }')
            return

        return Retracer.checkResult(self, interface, methodOrFunction)
Exemple #35
0
    def handleFailure(self, interface, methodOrFunction):
        # Catch when device is removed, and report the reason.
        if interface is not None:
            print r'        if (_result == DXGI_ERROR_DEVICE_REMOVED) {'
            getDeviceRemovedReasonMethod = interface.getMethodByName("GetDeviceRemovedReason")
            if getDeviceRemovedReasonMethod is not None:
                print r'            HRESULT _reason = _this->GetDeviceRemovedReason();'
                print r'            retrace::failed(call, _reason);'
            getDeviceMethod = interface.getMethodByName("GetDevice")
            if getDeviceMethod is not None and len(getDeviceMethod.args) == 1:
                print r'            com_ptr<%s> _pDevice;' % getDeviceMethod.args[0].type.type.type
                print r'            _this->GetDevice(&_pDevice);'
                print r'            HRESULT _reason = _pDevice->GetDeviceRemovedReason();'
                print r'            retrace::failed(call, _reason);'
            print r'            exit(EXIT_FAILURE);'
            print r'        }'

        Retracer.handleFailure(self, interface, methodOrFunction)
Exemple #36
0
    def extractArg(self, function, arg, arg_type, lvalue, rvalue):
        # Set object names
        if function.name == 'SetPrivateData' and arg.name == 'pData':
            iid = function.args[0].name
            print r'    if (%s != WKPDID_D3DDebugObjectName) {' % iid
            print r'        return;'
            print r'    }'
            # Interpret argument as string
            Retracer.extractArg(self, function, arg, LPCSTR, lvalue, rvalue)
            print r'    if (!pData) {'
            print r'        return;'
            print r'    }'
            print r'    assert(DataSize >= strlen((const char *)pData));'
            print r'    // Some applications include the trailing zero terminator in the data'
            print r'    DataSize = strlen((const char *)pData);'
            return

        Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
Exemple #37
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses'
        print 'static std::map<void *, void *> _maps;'
        print
        print r'''
static void 
createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
    UINT Width  = pSwapChainDesc->BufferDesc.Width;
    UINT Height = pSwapChainDesc->BufferDesc.Height;
    if (!Width)  Width = 1024;
    if (!Height) Height = 768;
    pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height);
}
'''

        self.table_name = 'd3dretrace::dxgi_callbacks'

        Retracer.retraceApi(self, api)
Exemple #38
0
    def retraceApi(self, api):
        print '// Swizzling mapping for lock addresses'
        print 'static std::map<void *, void *> _maps;'
        print
        print r'''
static void 
createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
    UINT Width  = pSwapChainDesc->BufferDesc.Width;
    UINT Height = pSwapChainDesc->BufferDesc.Height;
    if (!Width)  Width = 1024;
    if (!Height) Height = 768;
    pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height);
}
'''

        self.table_name = 'd3dretrace::dxgi_callbacks'

        Retracer.retraceApi(self, api)
Exemple #39
0
    def handleFailure(self, interface, methodOrFunction):
        # Catch when device is removed, and report the reason.
        if interface is not None:
            print r'        if (_result == DXGI_ERROR_DEVICE_REMOVED) {'
            getDeviceRemovedReasonMethod = interface.getMethodByName("GetDeviceRemovedReason")
            if getDeviceRemovedReasonMethod is not None:
                print r'            HRESULT _reason = _this->GetDeviceRemovedReason();'
                print r'            retrace::failed(call, _reason);'
            getDeviceMethod = interface.getMethodByName("GetDevice")
            if getDeviceMethod is not None and len(getDeviceMethod.args) == 1:
                print r'            com_ptr<%s> _pDevice;' % getDeviceMethod.args[0].type.type.type
                print r'            _this->GetDevice(&_pDevice);'
                print r'            HRESULT _reason = _pDevice->GetDeviceRemovedReason();'
                print r'            retrace::failed(call, _reason);'
            print r'            exit(EXIT_FAILURE);'
            print r'        }'

        Retracer.handleFailure(self, interface, methodOrFunction)
Exemple #40
0
    def extractArg(self, function, arg, arg_type, lvalue, rvalue):
        # Set object names
        if function.name == 'SetPrivateData' and arg.name == 'pData':
            iid = function.args[0].name
            print r'    if (%s != WKPDID_D3DDebugObjectName) {' % iid
            print r'        return;'
            print r'    }'
            # Interpret argument as string
            Retracer.extractArg(self, function, arg, LPCSTR, lvalue, rvalue)
            print r'    if (!pData) {'
            print r'        return;'
            print r'    }'
            print r'    assert(DataSize >= strlen((const char *)pData));'
            print r'    // Some applications include the trailing zero terminator in the data'
            print r'    DataSize = strlen((const char *)pData);'
            return

        Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
Exemple #41
0
    def checkResult(self, interface, methodOrFunction):
        # Catch when device is removed, and report the reason.
        if str(methodOrFunction.type) == 'HRESULT':
            if interface is not None:
                getDeviceRemovedReasonMethod = interface.getMethodByName("GetDeviceRemovedReason")
                if getDeviceRemovedReasonMethod is not None:
                    print r'    if (FAILED(_result)) {'
                    print r'        retrace::failed(call, _result);'
                    print r'        if (_result == DXGI_ERROR_DEVICE_REMOVED) {'
                    print r'            HRESULT _reason = _this->GetDeviceRemovedReason();'
                    print r'            retrace::failed(call, _reason);'
                    print r'            exit(1);'
                    print r'        }'
                    print r'        return;'
                    print r'    }'
                    return

        Retracer.checkResult(self, interface, methodOrFunction)
Exemple #42
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if 'pSwapChainDesc' in function.argNames():
                print r'    d3dretrace::createWindowForSwapChain(pSwapChainDesc);'

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith('D3D11CreateDevice'):
                print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
                print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
                print r'    }'

            if function.name.startswith('D3D10CreateDevice'):
                # Toggle debugging
                print r'    Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
                print r'    if (retrace::debug) {'
                print r'        HMODULE hD3d10SdkLayers = LoadLibraryA("d3d10sdklayers");'
                print r'        if (hD3d10SdkLayers) {'
                print r'            FreeLibrary(hD3d10SdkLayers);'
                print r'            Flags |= D3D10_CREATE_DEVICE_DEBUG;'
                print r'        } else {'
                print r'            retrace::warning(call) << "Direct3D 10.x SDK Debug Layer (d3d10sdklayers.dll) not available, continuing without debug output\n";'
                print r'        }'
                print r'    }'

                # Force driver
                self.forceDriver('D3D10_DRIVER_TYPE')

            if function.name.startswith('D3D11CreateDevice'):
                # Toggle debugging
                print r'    Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
                print r'    if (retrace::debug) {'
                print r'        HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, 0, D3D11_CREATE_DEVICE_DEBUG, NULL, 0, D3D11_SDK_VERSION, NULL, NULL, NULL);'
                print r'        if (SUCCEEDED(hr)) {'
                print r'            Flags |= D3D11_CREATE_DEVICE_DEBUG;'
                print r'        } else {'
                print r'            retrace::warning(call) << "Direct3D 11.x SDK Debug Layer (d3d11*sdklayers.dll) not available, continuing without debug output\n";'
                print r'        }'
                print r'    }'

                # Force driver
                self.forceDriver('D3D_DRIVER_TYPE')

        Retracer.invokeFunction(self, function)
Exemple #43
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if 'pSwapChainDesc' in function.argNames():
                print r'    d3dretrace::createWindowForSwapChain(pSwapChainDesc);'

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith('D3D11CreateDevice'):
                print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
                print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
                print r'    }'

            if function.name.startswith('D3D10CreateDevice'):
                # Toggle debugging
                print r'    Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
                print r'    if (retrace::debug) {'
                print r'        HMODULE hD3d10SdkLayers = LoadLibraryA("d3d10sdklayers");'
                print r'        if (hD3d10SdkLayers) {'
                print r'            FreeLibrary(hD3d10SdkLayers);'
                print r'            Flags |= D3D10_CREATE_DEVICE_DEBUG;'
                print r'        } else {'
                print r'            retrace::warning(call) << "Direct3D 10.x SDK Debug Layer (d3d10sdklayers.dll) not available, continuing without debug output\n";'
                print r'        }'
                print r'    }'

                # Force driver
                self.forceDriver('D3D10_DRIVER_TYPE')

            if function.name.startswith('D3D11CreateDevice'):
                # Toggle debugging
                print r'    Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
                print r'    if (retrace::debug) {'
                print r'        HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, 0, D3D11_CREATE_DEVICE_DEBUG, NULL, 0, D3D11_SDK_VERSION, NULL, NULL, NULL);'
                print r'        if (SUCCEEDED(hr)) {'
                print r'            Flags |= D3D11_CREATE_DEVICE_DEBUG;'
                print r'        } else {'
                print r'            retrace::warning(call) << "Direct3D 11.x SDK Debug Layer (d3d11*sdklayers.dll) not available, continuing without debug output\n";'
                print r'        }'
                print r'    }'

                # Force driver
                self.forceDriver('D3D_DRIVER_TYPE')

        Retracer.invokeFunction(self, function)
Exemple #44
0
    def retraceInterfaceMethodBody(self, interface, method):
        Retracer.retraceInterfaceMethodBody(self, interface, method)

        # Add pitch swizzling information to the region
        if method.name == 'Map' and interface.name not in ('ID3D10Buffer', 'ID3D10Texture1D'):
            if interface.name.startswith('ID3D11DeviceContext'):
                outArg = method.getArgByName('pMappedResource')
                memberNames = ('pData', 'RowPitch', 'DepthPitch')
            elif interface.name.startswith('ID3D10'):
                outArg = method.args[-1]
                memberNames = ('pData', 'RowPitch', 'DepthPitch')
            elif interface.name == 'IDXGISurface':
                outArg = method.getArgByName('pLockedRect')
                memberNames = ('pBits', 'Pitch', None)
            else:
                raise NotImplementedError
            struct = outArg.type.type
            dataMemberName, rowPitchMemberName, depthPitchMemberName = memberNames
            dataMemberIndex = struct.getMemberByName(dataMemberName)
            rowPitchMemberIndex = struct.getMemberByName(rowPitchMemberName)
            print r'    if (_pbData && %s->%s != 0) {' % (outArg.name, rowPitchMemberName)
            print r'        const trace::Array *_%s = call.arg(%u).toArray();' % (outArg.name, outArg.index)
            print r'        if (%s) {' % outArg.name
            print r'            const trace::Struct *_struct = _%s->values[0]->toStruct();' % (outArg.name)
            print r'            if (_struct) {'
            print r'                unsigned long long traceAddress = _struct->members[%u]->toUIntPtr();' % dataMemberIndex
            print r'                int traceRowPitch = _struct->members[%u]->toSInt();' % rowPitchMemberIndex
            print r'                int realRowPitch = %s->%s;' % (outArg.name, rowPitchMemberName)
            print r'                if (realRowPitch && traceRowPitch != realRowPitch) {'
            print r'                    retrace::setRegionPitch(traceAddress, 2, traceRowPitch, realRowPitch);'
            print r'                }'
            try:
                depthPitchMemberIndex = struct.getMemberByName(depthPitchMemberName)
            except ValueError:
                assert len(struct.members) < 3
                pass
            else:
                assert depthPitchMemberName == 'DepthPitch'
                print r'                if (%s->DepthPitch) {' % outArg.name
                print r'                    retrace::checkMismatch(call, "DepthPitch", _struct->members[%u], %s->DepthPitch);' % (struct.getMemberByName('DepthPitch'), outArg.name)
                print r'                }'
            print r'            }'
            print r'        }'
            print r'    }'
Exemple #45
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 '        }'
Exemple #46
0
    def invokeFunction(self, function):
        if function.name in ("Direct3DCreate9", "Direct3DCreate9Ex"):
            print 'if (retrace::debug >= 2 && !g_szD3D9DllName && LoadLibraryA("d3d9d.dll")) {'
            print "    /*"
            print "     * D3D9D only works for simple applications, it will often report bogus errors"
            print "     * on complex traces, or traces which use unofficial D3D9 features."
            print "     */"
            print '    g_szD3D9DllName = "d3d9d.dll";'
            print "    SDKVersion |= 0x80000000;"
            print "} else {"
            print "    SDKVersion &= ~0x80000000;"
            print "}"

        # d3d8d.dll can be found in the Aug 2007 DXSDK.  It works on XP, but
        # not on Windows 7.
        if function.name in ("Direct3DCreate8"):
            print 'if (retrace::debug >= 2 && !g_szD3D8DllName && LoadLibraryA("d3d8d.dll")) {'
            print '    g_szD3D8DllName = "d3d8d.dll";'
            print "}"

        Retracer.invokeFunction(self, function)
Exemple #47
0
    def doInvokeFunction(self, function):
        Retracer.doInvokeFunction(self, function)

        # Handle missing debug layer.  While it's possible to detect whether
        # the debug layers are present, by creating a null device, and checking
        # the result.  It's simpler to retry.
        if function.name.startswith('D3D10CreateDevice'):
            print(
                r'        if ((_result == E_FAIL || _result == DXGI_ERROR_SDK_COMPONENT_MISSING) && (Flags & D3D10_CREATE_DEVICE_DEBUG)) {'
            )
            print(
                r'            retrace::warning(call) << "Direct3D 10.x SDK Debug Layer (d3d10sdklayers.dll) not available, continuing without debug output\n";'
            )
            print(r'            Flags &= ~D3D10_CREATE_DEVICE_DEBUG;')
            Retracer.doInvokeFunction(self, function)
            print(r'        }')
        if function.name.startswith('D3D11CreateDevice'):
            print(
                r'        if ((_result == E_FAIL || _result == DXGI_ERROR_SDK_COMPONENT_MISSING) && (Flags & D3D11_CREATE_DEVICE_DEBUG)) {'
            )
            print(
                r'            retrace::warning(call) << "Direct3D 11.x SDK Debug Layer (d3d11*sdklayers.dll) not available, continuing without debug output\n";'
            )
            print(r'            Flags &= ~D3D11_CREATE_DEVICE_DEBUG;')
            Retracer.doInvokeFunction(self, function)
            print(r'        }')
Exemple #48
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if "pSwapChainDesc" in function.argNames():
                print r"    createWindow(pSwapChainDesc);"

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith("D3D11CreateDevice"):
                print r"    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {"
                print r"        DriverType = D3D_DRIVER_TYPE_HARDWARE;"
                print r"    }"

            if function.name.startswith("D3D10CreateDevice"):
                # Toggle debugging
                print r"    Flags &= ~D3D10_CREATE_DEVICE_DEBUG;"
                print r"    if (retrace::debug) {"
                print r'        if (LoadLibraryA("d3d10sdklayers")) {'
                print r"            Flags |= D3D10_CREATE_DEVICE_DEBUG;"
                print r"        }"
                print r"    }"

                # Force driver
                self.forceDriver("D3D10_DRIVER_TYPE")

            if function.name.startswith("D3D11CreateDevice"):
                # Toggle debugging
                print r"    Flags &= ~D3D11_CREATE_DEVICE_DEBUG;"
                print r"    if (retrace::debug) {"
                print r'        if (LoadLibraryA("d3d11sdklayers")) {'
                print r"            Flags |= D3D11_CREATE_DEVICE_DEBUG;"
                print r"        }"
                print r"    }"

                # Force driver
                self.forceDriver("D3D_DRIVER_TYPE")

        Retracer.invokeFunction(self, function)
Exemple #49
0
    def doInvokeFunction(self, function):
        Retracer.doInvokeFunction(self, function)

        # Handle missing debug layer.  While it's possible to detect whether
        # the debug layers are present, by creating a null device, and checking
        # the result.  It's simpler to retry.
        if function.name.startswith('D3D10CreateDevice'):
            print r'        if ((_result == E_FAIL || _result == DXGI_ERROR_SDK_COMPONENT_MISSING) && (Flags & D3D10_CREATE_DEVICE_DEBUG)) {'
            print r'            retrace::warning(call) << "Direct3D 10.x SDK Debug Layer (d3d10sdklayers.dll) not available, continuing without debug output\n";'
            print r'            Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
            Retracer.doInvokeFunction(self, function)
            print r'        }'
        if function.name.startswith('D3D11CreateDevice'):
            print r'        if ((_result == E_FAIL || _result == DXGI_ERROR_SDK_COMPONENT_MISSING) && (Flags & D3D11_CREATE_DEVICE_DEBUG)) {'
            print r'            retrace::warning(call) << "Direct3D 11.x SDK Debug Layer (d3d11*sdklayers.dll) not available, continuing without debug output\n";'
            print r'            Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
            Retracer.doInvokeFunction(self, function)
            print r'        }'
Exemple #50
0
    def invokeFunction(self, function):
        if function.name.startswith('Direct3DCreate9'):
            print r'    if (retrace::debug >= 3 && !g_szD3D9DllName && LoadLibraryA("d3d9d.dll")) {'
            print r'        /*'
            print r'         * D3D9D only works for simple applications, it will often report bogus errors'
            print r'         * on complex traces, or traces which use unofficial D3D9 features.'
            print r'         */'
            print r'        g_szD3D9DllName = "d3d9d.dll";'
            print r'        SDKVersion |= 0x80000000;'
            print r'    } else {'
            print r'        SDKVersion &= ~0x80000000;'
            print r'    }'

        # d3d8d.dll can be found in the Aug 2007 DXSDK.  It works on XP, but
        # not on Windows 7.
        if function.name.startswith('Direct3DCreate8'):
            print r'    if (retrace::debug >= 3 && !g_szD3D8DllName && LoadLibraryA("d3d8d.dll")) {'
            print r'        g_szD3D8DllName = "d3d8d.dll";'
            print r'    }'

        if function.name.startswith('Direct3DCreate9'):
            print r'    // 0: default'
            print r'    // 1: force discrete'
            print r'    // 2/3: force integrated'
            print r'    UINT uHybrid = 0;'
            print r'    if (retrace::driver == retrace::DRIVER_DISCRETE) {'
            print r'        uHybrid = 1;'
            print r'    }'
            print r'    if (retrace::driver == retrace::DRIVER_INTEGRATED) {'
            print r'        uHybrid = 2;'
            print r'    }'
            print r'    if (uHybrid != 0) {'
            print r'        HMODULE hD3D9 = LoadLibraryA("D3D9");'
            print r'        assert(hD3D9);'
            print r'        typedef void (WINAPI *PFNDIRECT3D9FORCEHYBRIDENUMERATION)(UINT);'
            print r'        PFNDIRECT3D9FORCEHYBRIDENUMERATION pfnDirect3D9ForceHybridEnumeration ='
            print r'            (PFNDIRECT3D9FORCEHYBRIDENUMERATION)GetProcAddress(hD3D9, MAKEINTRESOURCEA(16));'
            print r'        if (pfnDirect3D9ForceHybridEnumeration) {'
            print r'            pfnDirect3D9ForceHybridEnumeration(uHybrid);'
            print r'        }'
            print r'    }'

        Retracer.invokeFunction(self, function)

        if function.name.startswith('Direct3DCreate'):
            print r'    if (retrace::driver == retrace::DRIVER_DISCRETE ||'
            print r'        retrace::driver == retrace::DRIVER_INTEGRATED) {'
            if function.name == 'Direct3DCreate9Ex':
                print r'        auto pD3D = SUCCEEDED(_result) ? *ppD3D : nullptr;'
            else:
                print r'        auto pD3D = _result;'
            if function.name.startswith('Direct3DCreate9'):
                print r'        D3DADAPTER_IDENTIFIER9 Identifier;'
            else:
                assert function.name.startswith('Direct3DCreate8')
                print r'        D3DADAPTER_IDENTIFIER8 Identifier;'
            print r'        if (pD3D) {'
            print r'            if (SUCCEEDED(pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &Identifier))) {'
            print r'                std::cerr << "info: using " << Identifier.Description << std::endl;'
            print r'            }'
            print r'        }'
            print r'    }'
Exemple #51
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 '    }'
Exemple #52
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 '    }'
Exemple #53
0
    def invokeFunction(self, function):
        if function.name in self.createDeviceFunctionNames:
            # create windows as neccessary
            if 'pSwapChainDesc' in function.argNames():
                print r'    createWindow(pSwapChainDesc);'

            # Compensate for the fact we don't trace DXGI object creation
            if function.name.startswith('D3D11CreateDevice'):
                print r'    if (DriverType == D3D_DRIVER_TYPE_UNKNOWN && !pAdapter) {'
                print r'        DriverType = D3D_DRIVER_TYPE_HARDWARE;'
                print r'    }'

            if function.name.startswith('D3D10CreateDevice'):
                # Toggle debugging
                print r'    Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
                print r'    if (retrace::debug) {'
                print r'        if (LoadLibraryA("d3d10sdklayers")) {'
                print r'            Flags |= D3D10_CREATE_DEVICE_DEBUG;'
                print r'        }'
                print r'    }'

                # Force driver
                self.forceDriver('D3D10_DRIVER_TYPE')

            if function.name.startswith('D3D11CreateDevice'):
                # Toggle debugging
                print r'    Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
                print r'    if (retrace::debug) {'
                print r'        const char *szD3d11SdkLayers = IsWindows8OrGreater() ? "d3d11_1sdklayers" : "d3d11sdklayers";'
                print r'        if (LoadLibraryA(szD3d11SdkLayers)) {'
                print r'            Flags |= D3D11_CREATE_DEVICE_DEBUG;'
                print r'        }'
                print r'    }'

                # Force driver
                self.forceDriver('D3D_DRIVER_TYPE')

        Retracer.invokeFunction(self, function)

        # Debug layers with Windows 8 or Windows 7 Platform update are a mess.
        # It's not possible to know before hand whether they are or not
        # available, so always retry with debug flag off..
        if function.name in self.createDeviceFunctionNames:
            print r'    if (FAILED(_result)) {'

            if function.name.startswith('D3D10CreateDevice'):
                print r'        if (_result == E_FAIL && (Flags & D3D10_CREATE_DEVICE_DEBUG)) {'
                print r'            retrace::warning(call) << "debug layer (d3d10sdklayers.dll) not installed\n";'
                print r'            Flags &= ~D3D10_CREATE_DEVICE_DEBUG;'
                Retracer.invokeFunction(self, function)
                print r'        }'
            elif function.name.startswith('D3D11CreateDevice'):
                print r'        if (_result == E_FAIL && (Flags & D3D11_CREATE_DEVICE_DEBUG)) {'
                print r'            retrace::warning(call) << "debug layer (d3d11sdklayers.dll for Windows 7, d3d11_1sdklayers.dll for Windows 8 or Windows 7 with KB 2670838) not properly installed\n";'
                print r'            Flags &= ~D3D11_CREATE_DEVICE_DEBUG;'
                Retracer.invokeFunction(self, function)
                print r'        }'
            else:
                assert False

            print r'        if (FAILED(_result)) {'
            print r'            exit(1);'
            print r'        }'

            print r'    }'
Exemple #54
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'    }'
Exemple #55
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 '    }'