]> git.cworth.org Git - apitrace/commitdiff
Get DWM traces working.
authorJosé Fonseca <jfonseca@vmware.com>
Tue, 12 Feb 2013 16:19:23 +0000 (16:19 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 13 Feb 2013 15:18:24 +0000 (15:18 +0000)
Sort-of -- shared resources still don't work correctly.

dispatch/dxgiint.h
retrace/d3dretrace_dxgi.hpp [new file with mode: 0644]
retrace/dxgiretrace.py

index f985ed1839bf4ea3340a1529ae3afa4fc93fb227..13853b34ace26833f2884fecd66edd97a5c6c083 100644 (file)
@@ -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 (file)
index 0000000..b36352e
--- /dev/null
@@ -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_ */
index 8de3c989efa5f46057c6b04c19cbee22665af4f0..69bc3bac0966fe27c4cd08a5bacba013dd197ec8 100644 (file)
@@ -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 <string.h>'
     print
     print r'#include <iostream>'
@@ -251,6 +293,7 @@ def main():
     api = API()
     
     if moduleNames:
+        print r'#include "d3dretrace_dxgi.hpp"'
         api.addModule(dxgi)
     
     if 'd3d10' in moduleNames: