]> git.cworth.org Git - apitrace/blobdiff - retrace/d3dretrace.py
Refactor d3d9 lock tracking code further.
[apitrace] / retrace / d3dretrace.py
index 0d6374684f3807324edabdfe25bb17509b8302e7..cbf57d4aab981fe8f1bfa5b59a57bb73efd59661 100644 (file)
 ##########################################################################/
 
 
-"""GL retracer generator."""
+"""D3D retracer generator."""
 
 
 from dllretrace import DllRetracer as Retracer
 import specs.stdapi as stdapi
-from specs.d3d9 import d3d9
+from specs.d3d9 import *
 
 
 class D3DRetracer(Retracer):
@@ -42,38 +42,59 @@ class D3DRetracer(Retracer):
     ]
 
     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;'
+        # 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'):
+            print r'    HWND hWnd = createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
+            print r'    hFocusWindow = hWnd;'
+            print r'    pPresentationParameters->hDeviceWindow = hWnd;'
+
+        # notify frame has been completed
+        if method.name == 'Present':
+            print r'    retrace::frameComplete(call);'
+
+        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 (__result != S_OK) {'
+            print r'    if (FAILED(_result)) {'
             print r'        retrace::warning(call) << "failed\n";'
             print r'    }'
 
-        if interface.name in self.bufferInterfaceNames and method.name == 'Lock':
-            getDescMethod = interface.getMethodByName('GetDesc')
-            descArg = getDescMethod.args[0]
-            assert descArg.output
-            descType = getDescMethod.args[0].type.type
-
-            print '        if (!SizeToLock) {'
-            print '            %s Desc;' % descType
-            print '            _this->GetDesc(&Desc);'
-            print '            SizeToLock = Desc.Size;'
-            print '        }'
+        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_APITRACE, &_pbData, sizeof _pbData, 0);'
+        
+        if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
+            print '    VOID *_pbData = 0;'
+            print '    DWORD dwSizeOfData = sizeof _pbData;'
+            print '    _this->GetPrivateData(GUID_APITRACE, &_pbData, &dwSizeOfData);'
+            print '    if (_pbData) {'
+            print '        retrace::delRegionByPointer(_pbData);'
+            print '    }'
 
 
 if __name__ == '__main__':
     print r'''
+#define INITGUID
+
 #include <string.h>
 
 #include <iostream>
 
 #include "d3d9imports.hpp"
+#include "d3dsize.hpp"
 #include "d3dretrace.hpp"
 
 
@@ -100,6 +121,9 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 }
 
 
+DEFINE_GUID(GUID_APITRACE,0X7D71CAC9,0X7F58,0X432C,0XA9,0X75,0XA1,0X9F,0XCF,0XCE,0XFD,0X14);
+
+
 static HWND
 createWindow(int width, int height) {
     static bool first = TRUE;
@@ -150,6 +174,69 @@ createWindow(int width, int height) {
     return hWnd;
 }
 
+
+
+typedef HRESULT
+(WINAPI *PD3DXASSEMBLESHADER)(
+    LPCSTR pSrcData,
+    UINT SrcDataLen,
+    const D3DXMACRO *pDefines,
+    LPD3DXINCLUDE pInclude,
+    DWORD Flags,
+    LPD3DXBUFFER *ppShader,
+    LPD3DXBUFFER *ppErrorMsgs
+);
+
+DWORD *
+extractShader(LPCSTR pSrcData)
+{
+    static BOOL firsttime = TRUE;
+    static HMODULE hD3DXModule = NULL;
+    static PD3DXASSEMBLESHADER pfnD3DXAssembleShader = NULL;
+
+    if (firsttime) {
+        if (!hD3DXModule) {
+            unsigned release;
+            int version;
+            for (release = 0; release <= 1; ++release) {
+                /* Version 41 corresponds to Mar 2009 version of DirectX Runtime / SDK */
+                for (version = 41; version >= 0; --version) {
+                    char filename[256];
+                    _snprintf(filename, sizeof(filename),
+                              "d3dx9%s%s%u.dll", release ? "" : "d", version ? "_" : "", version);
+                    hD3DXModule = LoadLibraryA(filename);
+                    if (hD3DXModule)
+                        goto found;
+                }
+            }
+found:
+            ;
+        }
+
+        if (hD3DXModule) {
+            if (!pfnD3DXAssembleShader) {
+                pfnD3DXAssembleShader = (PD3DXASSEMBLESHADER)GetProcAddress(hD3DXModule, "D3DXAssembleShader");
+            }
+        }
+
+        firsttime = FALSE;
+    }
+
+    if (pfnD3DXAssembleShader) {
+        LPD3DXBUFFER pTokens = NULL;
+        HRESULT hr;
+
+        hr = pfnD3DXAssembleShader(pSrcData, strlen(pSrcData), NULL, NULL, 0, &pTokens, NULL);
+        if (SUCCEEDED(hr)) {
+            return (DWORD *)pTokens->GetBufferPointer();
+        }
+
+        // FIXME: Don't leak pTokens
+    }
+
+    return NULL;
+}
 '''
+
     retracer = D3DRetracer()
     retracer.retraceApi(d3d9)