]> git.cworth.org Git - apitrace/commitdiff
d3dretrace: Dump D3D8 images too.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Wed, 12 Dec 2012 07:38:42 +0000 (07:38 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Wed, 12 Dec 2012 07:38:42 +0000 (07:38 +0000)
dispatch/d3d8imports.hpp [new file with mode: 0644]
retrace/CMakeLists.txt
retrace/d3d8state.cpp [new file with mode: 0644]
retrace/d3d8state_images.cpp [new file with mode: 0644]
retrace/d3d9retrace.py
retrace/d3dstate.hpp
wrappers/d3d8trace.py

diff --git a/dispatch/d3d8imports.hpp b/dispatch/d3d8imports.hpp
new file mode 100644 (file)
index 0000000..d081379
--- /dev/null
@@ -0,0 +1,39 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/*
+ * Central place for all D3D8 includes, and respective OS dependent headers.
+ */
+
+#ifndef _D3D8IMPORTS_HPP_
+#define _D3D8IMPORTS_HPP_
+
+#include <windows.h>
+
+#include "compat.h"
+
+#include <d3d8.h>
+
+#endif /* _D3D8IMPORTS_HPP_ */
index c6a364f30f42f66a6fdb92f7eda432dff52fef65..b271727458bb2d6db722c045eaee1eb193dbe4c5 100644 (file)
@@ -136,6 +136,10 @@ if (WIN32)
     if (DirectX_D3D8_INCLUDE_DIR) 
         include_directories (BEFORE SYSTEM ${DirectX_D3D8_INCLUDE_DIR})
         set (HAVE_D3D8 1)
+        set (D3DSTATE_SOURCES ${D3DSTATE_SOURCES}
+            d3d8state.cpp
+            d3d8state_images.cpp
+        )
     else ()
         set (HAVE_D3D8 0)
     endif ()
diff --git a/retrace/d3d8state.cpp b/retrace/d3d8state.cpp
new file mode 100644 (file)
index 0000000..60bdb6d
--- /dev/null
@@ -0,0 +1,134 @@
+/**************************************************************************
+ *
+ * Copyright 2011-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.
+ *
+ **************************************************************************/
+
+
+#include <stdio.h>
+
+#include <iostream>
+
+#include "d3d8imports.hpp"
+#include "d3dshader.hpp"
+#include "d3dstate.hpp"
+#include "json.hpp"
+
+
+namespace d3dstate {
+
+
+typedef HRESULT (STDMETHODCALLTYPE IDirect3DDevice8::*GetShaderFunctionMethod)(DWORD Handle, void* pData, DWORD* pSizeOfData);
+
+
+struct VertexShaderGetter
+{
+    HRESULT GetShader(IDirect3DDevice8 *pDevice, DWORD *pHandle) {
+        return pDevice->GetVertexShader(pHandle);
+    }
+    HRESULT GetShaderFunction(IDirect3DDevice8 *pDevice, DWORD Handle, void* pData, DWORD* pSizeOfData) {
+        return pDevice->GetVertexShaderFunction(Handle, pData, pSizeOfData);
+    }
+};
+
+struct PixelShaderGetter
+{
+    HRESULT GetShader(IDirect3DDevice8 *pDevice, DWORD *pHandle) {
+        return pDevice->GetPixelShader(pHandle);
+    }
+    HRESULT GetShaderFunction(IDirect3DDevice8 *pDevice, DWORD Handle, void* pData, DWORD* pSizeOfData) {
+        return pDevice->GetPixelShaderFunction(Handle, pData, pSizeOfData);
+    }
+};
+
+template<class Getter>
+inline void
+dumpShader(JSONWriter &json, IDirect3DDevice8 *pDevice, const char *name) {
+    Getter getter;
+    HRESULT hr;
+
+    DWORD dwShader = 0;
+    hr = getter.GetShader(pDevice, &dwShader);
+    if (FAILED(hr) || !dwShader) {
+        return;
+    }
+
+    DWORD SizeOfData = 0;
+
+    hr = getter.GetShaderFunction(pDevice, dwShader, NULL, &SizeOfData);
+    if (SUCCEEDED(hr)) {
+        void *pData;
+        pData = malloc(SizeOfData);
+        if (pData) {
+            hr = getter.GetShaderFunction(pDevice, dwShader, pData, &SizeOfData);
+            if (SUCCEEDED(hr)) {
+                IDisassemblyBuffer *pDisassembly = NULL;
+                hr = DisassembleShader((const DWORD *)pData, &pDisassembly);
+                if (SUCCEEDED(hr)) {
+                    json.beginMember(name);
+                    json.writeString((const char *)pDisassembly->GetBufferPointer() /*, pDisassembly->GetBufferSize() */);
+                    json.endMember();
+                    pDisassembly->Release();
+                }
+
+            }
+            free(pData);
+        }
+    }
+}
+
+static void
+dumpShaders(JSONWriter &json, IDirect3DDevice8 *pDevice)
+{
+    json.beginMember("shaders");
+    json.beginObject();
+
+    dumpShader<VertexShaderGetter>(json, pDevice, "vertex");
+    dumpShader<PixelShaderGetter>(json, pDevice, "pixel");
+
+    json.endObject();
+    json.endMember(); // shaders
+}
+
+void
+dumpDevice(std::ostream &os, IDirect3DDevice8 *pDevice)
+{
+    JSONWriter json(os);
+
+    /* TODO */
+    json.beginMember("parameters");
+    json.beginObject();
+    json.endObject();
+    json.endMember(); // parameters
+
+    dumpShaders(json, pDevice);
+
+    json.beginMember("textures");
+    json.beginObject();
+    json.endObject();
+    json.endMember(); // textures
+
+    dumpFramebuffer(json, pDevice);
+}
+
+
+} /* namespace d3dstate */
diff --git a/retrace/d3d8state_images.cpp b/retrace/d3d8state_images.cpp
new file mode 100644 (file)
index 0000000..89d4e06
--- /dev/null
@@ -0,0 +1,164 @@
+/**************************************************************************
+ *
+ * Copyright 2011-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.
+ *
+ **************************************************************************/
+
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "image.hpp"
+#include "json.hpp"
+#include "d3d8imports.hpp"
+#include "d3dstate.hpp"
+
+
+namespace d3dstate {
+
+
+static image::Image *
+getRenderTargetImage(IDirect3DDevice8 *pDevice,
+                     IDirect3DSurface8 *pRenderTarget) {
+    image::Image *image = NULL;
+    D3DSURFACE_DESC Desc;
+    IDirect3DSurface8 *pStagingSurface = NULL;
+    D3DLOCKED_RECT LockedRect;
+    const unsigned char *src;
+    unsigned char *dst;
+    HRESULT hr;
+
+    if (!pRenderTarget) {
+        return NULL;
+    }
+
+    hr = pRenderTarget->GetDesc(&Desc);
+    assert(SUCCEEDED(hr));
+
+    if (Desc.Format != D3DFMT_X8R8G8B8 &&
+        Desc.Format != D3DFMT_A8R8G8B8 &&
+        Desc.Format != D3DFMT_R5G6B5) {
+        std::cerr << "warning: unsupported D3DFORMAT " << Desc.Format << "\n";
+        goto no_staging;
+    }
+
+    hr = pDevice->CreateImageSurface(Desc.Width, Desc.Height, Desc.Format, &pStagingSurface);
+    if (FAILED(hr)) {
+        goto no_staging;
+    }
+
+    hr = pDevice->CopyRects(pRenderTarget, NULL, 0, pStagingSurface, NULL);
+    if (FAILED(hr)) {
+        goto no_rendertargetdata;
+    }
+
+    hr = pStagingSurface->LockRect(&LockedRect, NULL, D3DLOCK_READONLY);
+    if (FAILED(hr)) {
+        goto no_rendertargetdata;
+    }
+
+    image = new image::Image(Desc.Width, Desc.Height, 3, true);
+    if (!image) {
+        goto no_image;
+    }
+
+    dst = image->start();
+    src = (const unsigned char *)LockedRect.pBits;
+    for (unsigned y = 0; y < Desc.Height; ++y) {
+        if (Desc.Format == D3DFMT_R5G6B5) {
+            for (unsigned x = 0; x < Desc.Width; ++x) {
+                uint32_t pixel = ((const uint16_t *)src)[x];
+                dst[3*x + 0] = (( pixel        & 0x1f) * (2*0xff) + 0x1f) / (2*0x1f);
+                dst[3*x + 1] = (((pixel >>  5) & 0x3f) * (2*0xff) + 0x3f) / (2*0x3f);
+                dst[3*x + 2] = (( pixel >> 11        ) * (2*0xff) + 0x1f) / (2*0x1f);
+                dst[3*x + 3] = 0xff;
+            }
+        } else {
+            for (unsigned x = 0; x < Desc.Width; ++x) {
+                dst[3*x + 0] = src[4*x + 2];
+                dst[3*x + 1] = src[4*x + 1];
+                dst[3*x + 2] = src[4*x + 0];
+            }
+        }
+
+        src += LockedRect.Pitch;
+        dst += image->stride();
+    }
+
+no_image:
+    pStagingSurface->UnlockRect();
+no_rendertargetdata:
+    pStagingSurface->Release();
+no_staging:
+    return image;
+}
+
+
+image::Image *
+getRenderTargetImage(IDirect3DDevice8 *pDevice) {
+    HRESULT hr;
+
+    IDirect3DSurface8 *pRenderTarget = NULL;
+    hr = pDevice->GetRenderTarget(&pRenderTarget);
+    if (FAILED(hr)) {
+        return NULL;
+    }
+    assert(pRenderTarget);
+
+    image::Image *image = NULL;
+    if (pRenderTarget) {
+        image = getRenderTargetImage(pDevice, pRenderTarget);
+        pRenderTarget->Release();
+    }
+
+    return image;
+}
+
+
+void
+dumpFramebuffer(JSONWriter &json, IDirect3DDevice8 *pDevice)
+{
+    HRESULT hr;
+
+    json.beginMember("framebuffer");
+    json.beginObject();
+
+    IDirect3DSurface8 *pRenderTarget = NULL;
+    hr = pDevice->GetRenderTarget(&pRenderTarget);
+    if (SUCCEEDED(hr) && pRenderTarget) {
+        image::Image *image;
+        image = getRenderTargetImage(pDevice, pRenderTarget);
+        if (image) {
+            json.beginMember("RENDER_TARGET_0");
+            json.writeImage(image, "UNKNOWN");
+            json.endMember(); // RENDER_TARGET_*
+        }
+
+        pRenderTarget->Release();
+    }
+
+    json.endObject();
+    json.endMember(); // framebuffer
+}
+
+
+} /* namespace d3dstate */
index 72fc9ef81b6578846ed36bfe8988efdea917cb51..db92377e624b8895d0aed87f057352902119bc0b 100644 (file)
@@ -62,6 +62,11 @@ class D3DRetracer(Retracer):
                 print r'    d3d9Dumper.unbindDevice(_this);'
             else:
                 print r'    d3d9Dumper.bindDevice(_this);'
+        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
+            if method.name == 'Release':
+                print r'    d3d8Dumper.unbindDevice(_this);'
+            else:
+                print r'    d3d8Dumper.bindDevice(_this);'
 
         # create windows as neccessary
         if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
@@ -161,12 +166,11 @@ def main():
             print
         elif moduleName == 'd3d8':
             from specs.d3d8 import d3d8
-            print r'#include <windows.h>'
-            print r'#include <d3d8.h>'
+            print r'#include "d3d8imports.hpp"'
             print r'#include "d3d8size.hpp"'
             api.addModule(d3d8)
             print
-            #print '''static d3dretrace::D3DDumper<IDirect3DDevice8> d3d8Dumper;'''
+            print '''static d3dretrace::D3DDumper<IDirect3DDevice8> d3d8Dumper;'''
             print
         else:
             assert False
index 3766a91353e6710396d8801f0ffa75bdef10aa0e..eb0e3cd4f33fd0a6d73e6302fea4dc6706613bce 100644 (file)
@@ -32,6 +32,7 @@
 #include <windows.h>
 
 
+struct IDirect3DDevice8;
 struct IDirect3DDevice9;
 struct ID3D10Device;
 struct ID3D11DeviceContext;
@@ -50,6 +51,16 @@ namespace d3dstate {
 extern const GUID GUID_D3DSTATE;
 
 
+image::Image *
+getRenderTargetImage(IDirect3DDevice8 *pDevice);
+
+void
+dumpFramebuffer(JSONWriter &json, IDirect3DDevice8 *pDevice);
+
+void
+dumpDevice(std::ostream &os, IDirect3DDevice8 *pDevice);
+
+
 image::Image *
 getRenderTargetImage(IDirect3DDevice9 *pDevice);
 
index fd2c8f5303fc759c7712f03cdef8c235f7bc3e0c..9ce3aad08f802144c7ec3ebf7441b0b051aa9c82 100644 (file)
@@ -77,8 +77,7 @@ if __name__ == '__main__':
     print '#include "trace_writer_local.hpp"'
     print '#include "os.hpp"'
     print
-    print '#include <windows.h>'
-    print '#include <d3d8.h>'
+    print '#include "d3d8imports.hpp"'
     print '#include "d3d8size.hpp"'
     print '#include "d3d9shader.hpp"'
     print