]> git.cworth.org Git - apitrace/blobdiff - gltrace.py
cli: Add a simple implementation of "apitrace dump-images"
[apitrace] / gltrace.py
index 86fbf085f8ec7e7333bc4ed121ff54504ce48a25..6fc456c82ae773cf587e6f702c35535d00fde464 100644 (file)
@@ -240,6 +240,15 @@ class GlTracer(Tracer):
         print 'static void __trace_user_arrays(GLuint maxindex);'
         print
 
+        # Buffer mappings
+        print '// whether glMapBufferRange(GL_MAP_WRITE_BIT) has ever been called'
+        print 'static bool __checkBufferMapRange = false;'
+        print
+        print '// whether glBufferParameteriAPPLE(GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE) has ever been called'
+        print 'static bool __checkBufferFlushingUnmapAPPLE = false;'
+        print
+        # Buffer mapping information, necessary for old Mesa 2.1 drivers which
+        # do not support glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS/GL_BUFFER_MAP_LENGTH)
         print 'struct buffer_mapping {'
         print '    void *map;'
         print '    GLint length;'
@@ -461,10 +470,69 @@ class GlTracer(Tracer):
             print '    }'
         
         # Emit a fake memcpy on buffer uploads
-        if function.name in ('glUnmapBuffer', 'glUnmapBufferARB', 'glUnmapBufferOES'):
-            print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
-            print '    if (mapping && mapping->write && !mapping->explicit_flush) {'
-            self.emit_memcpy('mapping->map', 'mapping->map', 'mapping->length')
+        if function.name == 'glBufferParameteriAPPLE':
+            print '    if (pname == GL_BUFFER_FLUSHING_UNMAP_APPLE && param == GL_FALSE) {'
+            print '        __checkBufferFlushingUnmapAPPLE = true;'
+            print '    }'
+        if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'):
+            if function.name.endswith('ARB'):
+                suffix = 'ARB'
+            else:
+                suffix = ''
+            print '    GLint access = 0;'
+            print '    __glGetBufferParameteriv%s(target, GL_BUFFER_ACCESS, &access);' % suffix
+            print '    if (access != GL_READ_ONLY) {'
+            print '        GLvoid *map = NULL;'
+            print '        __glGetBufferPointerv%s(target, GL_BUFFER_MAP_POINTER, &map);'  % suffix
+            print '        if (map) {'
+            print '            GLint length = -1;'
+            print '            bool flush = true;'
+            print '            if (__checkBufferMapRange) {'
+            print '                __glGetBufferParameteriv%s(target, GL_BUFFER_MAP_LENGTH, &length);' % suffix
+            print '                GLint access_flags = 0;'
+            print '                __glGetBufferParameteriv(target, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
+            print '                flush = flush && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT);'
+            print '                if (length == -1) {'
+            print '                    // Mesa drivers refuse GL_BUFFER_MAP_LENGTH without GL 3.0'
+            print '                    static bool warned = false;'
+            print '                    if (!warned) {'
+            print '                        os::log("apitrace: warning: glGetBufferParameteriv%s(GL_BUFFER_MAP_LENGTH) failed\\n");' % suffix
+            print '                        warned = true;'
+            print '                    }'
+            print '                    struct buffer_mapping *mapping = get_buffer_mapping(target);'
+            print '                    if (mapping) {'
+            print '                        length = mapping->length;'
+            print '                        flush = flush && !mapping->explicit_flush;'
+            print '                    } else {'
+            print '                        length = 0;'
+            print '                        flush = false;'
+            print '                    }'
+            print '                }'
+            print '            } else {'
+            print '                length = 0;'
+            print '                __glGetBufferParameteriv%s(target, GL_BUFFER_SIZE, &length);' % suffix
+            print '            }'
+            print '            if (__checkBufferFlushingUnmapAPPLE) {'
+            print '                GLint flushing_unmap = GL_TRUE;'
+            print '                __glGetBufferParameteriv%s(target, GL_BUFFER_FLUSHING_UNMAP_APPLE, &flushing_unmap);' % suffix
+            print '                flush = flush && flushing_unmap;'
+            print '            }'
+            print '            if (flush && length > 0) {'
+            self.emit_memcpy('map', 'map', 'length')
+            print '            }'
+            print '        }'
+            print '    }'
+        if function.name == 'glUnmapBufferOES':
+            print '    GLint access = 0;'
+            print '    __glGetBufferParameteriv(target, GL_BUFFER_ACCESS_OES, &access);'
+            print '    if (access == GL_WRITE_ONLY_OES) {'
+            print '        GLvoid *map = NULL;'
+            print '        __glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &map);'
+            print '        GLint size = 0;'
+            print '        __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);'
+            print '        if (map && size > 0) {'
+            self.emit_memcpy('map', 'map', 'size')
+            print '        }'
             print '    }'
         if function.name == 'glUnmapNamedBufferEXT':
             print '    GLint access_flags = 0;'
@@ -599,8 +667,8 @@ class GlTracer(Tracer):
     def wrapRet(self, function, instance):
         Tracer.wrapRet(self, function, instance)
 
-            
-        if function.name in ('glMapBuffer', 'glMapBufferARB', 'glMapBufferOES'):
+        # Keep track of buffer mappings
+        if function.name in ('glMapBuffer', 'glMapBufferARB'):
             print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
             print '    if (mapping) {'
             print '        mapping->map = %s;' % (instance)
@@ -609,8 +677,10 @@ class GlTracer(Tracer):
             print '        mapping->write = (access != GL_READ_ONLY);'
             print '        mapping->explicit_flush = false;'
             print '    }'
-
         if function.name == 'glMapBufferRange':
+            print '    if (access & GL_MAP_WRITE_BIT) {'
+            print '        __checkBufferMapRange = true;'
+            print '    }'
             print '    struct buffer_mapping *mapping = get_buffer_mapping(target);'
             print '    if (mapping) {'
             print '        mapping->map = %s;' % (instance)