]> git.cworth.org Git - apitrace/blobdiff - retrace/d3d9retrace.py
d3dretrace: Recognize IDirect3DDevice9Ex::PresentEx as frame terminator.
[apitrace] / retrace / d3d9retrace.py
index 4b5853bdd3e2be3e0b987cbe2c9a9daf4b429a61..ccd8a723e98a9c68f6abcb788d3b4cb9c7b8ab60 100644 (file)
 """D3D retracer generator."""
 
 
+import sys
 from dllretrace import DllRetracer as Retracer
 from specs.stdapi import API
-from specs.d3d9 import *
 
 
 class D3DRetracer(Retracer):
 
     def retraceApi(self, api):
-        print '''
-static IDirect3DDevice9 *
-pLastDirect3DDevice9 = NULL;
-
-image::Image *
-retrace::getSnapshot(void) {
-    if (!pLastDirect3DDevice9) {
-        return NULL;
-    }
-    return d3dstate::getRenderTargetImage(pLastDirect3DDevice9);
-}
-
-
-bool
-retrace::dumpState(std::ostream &os)
-{
-    if (!pLastDirect3DDevice9) {
-        return false;
-    }
-    d3dstate::dumpDevice(os, pLastDirect3DDevice9);
-    return true;
-}
-'''
-
         print '// Swizzling mapping for lock addresses'
         print 'static std::map<void *, void *> _maps;'
         print
 
-        self.table_name = 'd3dretrace::d3d9_callbacks'
-
         Retracer.retraceApi(self, api)
 
     def invokeFunction(self, function):
@@ -84,7 +58,15 @@ retrace::dumpState(std::ostream &os)
     def invokeInterfaceMethod(self, interface, method):
         # keep track of the last used device for state dumping
         if interface.name in ('IDirect3DDevice9', 'IDirect3DDevice9Ex'):
-            print r'    pLastDirect3DDevice9 = _this;'
+            if method.name == 'Release':
+                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'):
@@ -92,6 +74,31 @@ retrace::dumpState(std::ostream &os)
             print r'    pPresentationParameters->hDeviceWindow = hWnd;'
             if 'hFocusWindow' in method.argNames():
                 print r'    hFocusWindow = hWnd;'
+        
+        if method.name in ('CreateDevice', 'CreateDeviceEx'):
+            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'):
             print r'    if (pPresentationParameters->Windowed) {'
@@ -99,7 +106,7 @@ retrace::dumpState(std::ostream &os)
             print r'    }'
 
         # notify frame has been completed
-        if method.name == 'Present':
+        if method.name in ('Present', 'PresentEx'):
             print r'    retrace::frameComplete(call);'
             print r'    hDestWindowOverride = NULL;'
 
@@ -114,41 +121,64 @@ retrace::dumpState(std::ostream &os)
         # 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'    }'
+            print r'    Sleep(500);'
 
         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 '    _maps[_this] = _pbData;'
+            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 '    }'
 
 
-if __name__ == '__main__':
-    print r'''
-#include <string.h>
-
-#include <iostream>
+def main():
+    print r'#include <string.h>'
+    print
+    print r'#include <iostream>'
+    print
+    print r'#include "d3dretrace.hpp"'
+    print
 
-#include "d3d9imports.hpp"
-#include "d3d9size.hpp"
-#include "d3dretrace.hpp"
-#include "d3d9state.hpp"
-
-'''
+    moduleName = sys.argv[1]
+    support = int(sys.argv[2])
 
     api = API()
-    api.addModule(d3d9)
+    
+    if support:
+        if moduleName == 'd3d9':
+            from specs.d3d9 import d3d9
+            print r'#include "d3d9imports.hpp"'
+            print r'#include "d3d9size.hpp"'
+            api.addModule(d3d9)
+            print
+            print '''static d3dretrace::D3DDumper<IDirect3DDevice9> d3d9Dumper;'''
+            print
+        elif moduleName == 'd3d8':
+            from specs.d3d8 import d3d8
+            print r'#include "d3d8imports.hpp"'
+            print r'#include "d3d8size.hpp"'
+            api.addModule(d3d8)
+            print
+            print '''static d3dretrace::D3DDumper<IDirect3DDevice8> d3d8Dumper;'''
+            print
+        else:
+            assert False
+
     retracer = D3DRetracer()
+    retracer.table_name = 'd3dretrace::%s_callbacks' % moduleName
     retracer.retraceApi(api)
+
+
+if __name__ == '__main__':
+    main()