From 75cbb8c52730680271ce5fe939ff6607ab004eaa Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 12 Feb 2013 16:19:23 +0000 Subject: [PATCH] Get DWM traces working. Sort-of -- shared resources still don't work correctly. --- dispatch/dxgiint.h | 26 ++-- retrace/d3dretrace_dxgi.hpp | 241 ++++++++++++++++++++++++++++++++++++ retrace/dxgiretrace.py | 59 +++++++-- 3 files changed, 305 insertions(+), 21 deletions(-) create mode 100644 retrace/d3dretrace_dxgi.hpp diff --git a/dispatch/dxgiint.h b/dispatch/dxgiint.h index f985ed1..13853b3 100644 --- a/dispatch/dxgiint.h +++ b/dispatch/dxgiint.h @@ -45,18 +45,18 @@ struct IDXGIFactoryDWM: public IUnknown virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGIOutput *pOutput, IDXGISwapChainDWM **ppSwapChain) = 0; }; -struct IDXGISwapChainDWM: public IDXGIDeviceSubObject -{ - virtual HRESULT STDMETHODCALLTYPE Present (UINT SyncInterval, UINT Flags) = 0; - virtual HRESULT STDMETHODCALLTYPE GetBuffer (UINT Buffer, REFIID riid, void **ppSurface) = 0; - virtual HRESULT STDMETHODCALLTYPE GetDesc (DXGI_SWAP_CHAIN_DESC *pDesc) = 0; - virtual HRESULT STDMETHODCALLTYPE ResizeBuffers (UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) = 0; - virtual HRESULT STDMETHODCALLTYPE ResizeTarget (const DXGI_MODE_DESC *pNewTargetParameters) = 0; - virtual HRESULT STDMETHODCALLTYPE GetContainingOutput (IDXGIOutput **ppOutput) = 0; - virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics (DXGI_FRAME_STATISTICS *pStats) = 0; - virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount (UINT *pLastPresentCount) = 0; - virtual HRESULT STDMETHODCALLTYPE SetFullscreenState (BOOL Fullscreen, IDXGIOutput *pTarget) = 0; - virtual HRESULT STDMETHODCALLTYPE GetFullscreenState (BOOL *pFullscreen, IDXGIOutput **ppTarget) = 0; -}; +struct IDXGISwapChainDWM: public IDXGIDeviceSubObject +{ + virtual HRESULT STDMETHODCALLTYPE Present(UINT SyncInterval, UINT Flags) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBuffer(UINT Buffer, REFIID riid, void **ppSurface) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDesc(DXGI_SWAP_CHAIN_DESC *pDesc) = 0; + virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) = 0; + virtual HRESULT STDMETHODCALLTYPE ResizeTarget(const DXGI_MODE_DESC *pNewTargetParameters) = 0; + virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(IDXGIOutput **ppOutput) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats) = 0; + virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount) = 0; + virtual HRESULT STDMETHODCALLTYPE SetFullscreenState(BOOL Fullscreen, IDXGIOutput *pTarget) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFullscreenState(BOOL *pFullscreen, IDXGIOutput **ppTarget) = 0; +}; #endif /* _DXGIINT_H_ */ diff --git a/retrace/d3dretrace_dxgi.hpp b/retrace/d3dretrace_dxgi.hpp new file mode 100644 index 0000000..b36352e --- /dev/null +++ b/retrace/d3dretrace_dxgi.hpp @@ -0,0 +1,241 @@ +/************************************************************************** + * + * Copyright 2012 VMware Inc + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _D3DRETRACE_DXGI_HPP_ +#define _D3DRETRACE_DXGI_HPP_ + + +#include "dxgiint.h" + + +/* + * This module implements the IDXGIFactoryDWM and IDXGISwapChainDWM + * undocumented interfaces used by DWM, in terms of the standard IDXGIFactory + * and IDXGISwapChain interfaces, just for sake of d3dretrace. Retracing on + * top of the undocumented interfaces works, but it may interfere with running + * DWM and causes corruption of the desktop upon exit. + */ + + +namespace d3dretrace { + + +class CDXGISwapChainDWM : public IDXGISwapChainDWM +{ +private: + IDXGISwapChain *m_pSwapChain; + +public: + CDXGISwapChainDWM(IDXGISwapChain *pSwapChain); + ~CDXGISwapChainDWM(); + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj); + ULONG STDMETHODCALLTYPE AddRef(void); + ULONG STDMETHODCALLTYPE Release(void); + HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData); + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown); + HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData); + HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent); + HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void **ppDevice); + + HRESULT STDMETHODCALLTYPE Present(UINT SyncInterval, UINT Flags); + HRESULT STDMETHODCALLTYPE GetBuffer(UINT Buffer, REFIID riid, void **ppSurface); + HRESULT STDMETHODCALLTYPE GetDesc(DXGI_SWAP_CHAIN_DESC *pDesc); + HRESULT STDMETHODCALLTYPE ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags); + HRESULT STDMETHODCALLTYPE ResizeTarget(const DXGI_MODE_DESC *pNewTargetParameters); + HRESULT STDMETHODCALLTYPE GetContainingOutput(IDXGIOutput **ppOutput); + HRESULT STDMETHODCALLTYPE GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats); + HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount); + HRESULT STDMETHODCALLTYPE SetFullscreenState(BOOL Fullscreen, IDXGIOutput *pTarget); + HRESULT STDMETHODCALLTYPE GetFullscreenState(BOOL *pFullscreen, IDXGIOutput **ppTarget); +}; + +CDXGISwapChainDWM::CDXGISwapChainDWM(IDXGISwapChain *pSwapChain) : + m_pSwapChain(pSwapChain) +{ +} + +CDXGISwapChainDWM::~CDXGISwapChainDWM() +{ + m_pSwapChain->SetFullscreenState(FALSE, NULL); + m_pSwapChain->Release(); +} + + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::QueryInterface(REFIID riid, void **ppvObj) +{ + return m_pSwapChain->QueryInterface(riid, ppvObj); +} + +ULONG STDMETHODCALLTYPE CDXGISwapChainDWM::AddRef(void) +{ + // FIXME + return 1; +} + +ULONG STDMETHODCALLTYPE CDXGISwapChainDWM::Release(void) +{ + // FIXME + return 1; +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::SetPrivateData(REFGUID Name, UINT DataSize, const void *pData) +{ + return m_pSwapChain->SetPrivateData(Name, DataSize, pData); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown) +{ + return m_pSwapChain->SetPrivateDataInterface(Name, pUnknown); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData) +{ + return m_pSwapChain->GetPrivateData(Name, pDataSize, pData); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetParent(REFIID riid, void **ppParent) +{ + return m_pSwapChain->GetParent(riid, ppParent); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetDevice(REFIID riid, void **ppDevice) +{ + return m_pSwapChain->GetDevice(riid, ppDevice); +} + + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::Present(UINT SyncInterval, UINT Flags) +{ + return m_pSwapChain->Present(SyncInterval, Flags); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetBuffer(UINT Buffer, REFIID riid, void **ppSurface) +{ + return m_pSwapChain->GetBuffer(Buffer, riid, ppSurface); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetDesc(DXGI_SWAP_CHAIN_DESC *pDesc) +{ + return m_pSwapChain->GetDesc(pDesc); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) +{ + return m_pSwapChain->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::ResizeTarget(const DXGI_MODE_DESC *pNewTargetParameters) +{ + return m_pSwapChain->ResizeTarget(pNewTargetParameters); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetContainingOutput(IDXGIOutput **ppOutput) +{ + return m_pSwapChain->GetContainingOutput(ppOutput); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats) +{ + return m_pSwapChain->GetFrameStatistics(pStats); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetLastPresentCount(UINT *pLastPresentCount) +{ + return m_pSwapChain->GetLastPresentCount(pLastPresentCount); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::SetFullscreenState(BOOL Fullscreen, IDXGIOutput *pTarget) +{ + return m_pSwapChain->SetFullscreenState(Fullscreen, pTarget); +} + +HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetFullscreenState(BOOL *pFullscreen, IDXGIOutput **ppTarget) +{ + return m_pSwapChain->GetFullscreenState(pFullscreen, ppTarget); +} + + + +class CDXGIFactoryDWM : public IDXGIFactoryDWM +{ +private: + IDXGIFactory *m_pFactory; + + ~CDXGIFactoryDWM(); + +public: + CDXGIFactoryDWM(IDXGIFactory *pFactory); + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj); + ULONG STDMETHODCALLTYPE AddRef(void); + ULONG STDMETHODCALLTYPE Release(void); + HRESULT STDMETHODCALLTYPE CreateSwapChain(IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGIOutput *pOutput, IDXGISwapChainDWM **ppSwapChain); +}; + +CDXGIFactoryDWM::CDXGIFactoryDWM(IDXGIFactory *pFactory) : + m_pFactory(pFactory) +{} + +CDXGIFactoryDWM::~CDXGIFactoryDWM() +{ + m_pFactory->Release(); +} + + +HRESULT STDMETHODCALLTYPE CDXGIFactoryDWM::QueryInterface(REFIID riid, void **ppvObj) +{ + return m_pFactory->QueryInterface(riid, ppvObj); +} + +ULONG STDMETHODCALLTYPE CDXGIFactoryDWM::AddRef(void) +{ + // FIXME + return 1; +} + +ULONG STDMETHODCALLTYPE CDXGIFactoryDWM::Release(void) +{ + // FIXME + return 1; +} + +HRESULT STDMETHODCALLTYPE CDXGIFactoryDWM::CreateSwapChain(IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGIOutput *pOutput, IDXGISwapChainDWM **ppSwapChain) +{ + IDXGISwapChain *pSwapChain = NULL; + HRESULT hr = m_pFactory->CreateSwapChain(pDevice, pDesc, &pSwapChain); + if (SUCCEEDED(hr)) { + pSwapChain->SetFullscreenState(TRUE, pOutput); + *ppSwapChain = new CDXGISwapChainDWM(pSwapChain); + } + return hr; +} + + + +} /* namespace d3dretrace */ + + +#endif /* _D3DRETRACE_DXGI_HPP_ */ diff --git a/retrace/dxgiretrace.py b/retrace/dxgiretrace.py index 8de3c98..69bc3ba 100644 --- a/retrace/dxgiretrace.py +++ b/retrace/dxgiretrace.py @@ -29,6 +29,7 @@ import sys from dllretrace import DllRetracer as Retracer +import specs.dxgi from specs.stdapi import API from specs.dxgi import dxgi from specs.d3d10 import d3d10 @@ -45,13 +46,11 @@ class D3DRetracer(Retracer): print r''' static void createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) { - if (pSwapChainDesc->Windowed) { - UINT Width = pSwapChainDesc->BufferDesc.Width; - UINT Height = pSwapChainDesc->BufferDesc.Height; - if (!Width) Width = 1024; - if (!Height) Height = 768; - pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height); - } + UINT Width = pSwapChainDesc->BufferDesc.Width; + UINT Height = pSwapChainDesc->BufferDesc.Height; + if (!Width) Width = 1024; + if (!Height) Height = 768; + pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height); } ''' @@ -163,6 +162,16 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) { 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);' @@ -205,7 +214,38 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) { print r' }' return - Retracer.invokeInterfaceMethod(self, interface, method) + 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) + else: + Retracer.invokeInterfaceMethod(self, interface, method) # process events after presents if method.name == 'Present': @@ -239,6 +279,8 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) { def main(): + print r'#define INITGUID' + print print r'#include ' print print r'#include ' @@ -251,6 +293,7 @@ def main(): api = API() if moduleNames: + print r'#include "d3dretrace_dxgi.hpp"' api.addModule(dxgi) if 'd3d10' in moduleNames: -- 2.43.0