]> git.cworth.org Git - apitrace/blobdiff - retrace/glretrace.py
gltrace,glretrace: Properly handle PBOs with GL_EXT_direct_state_access.
[apitrace] / retrace / glretrace.py
index b7659ff1dd6bcd37e6268a3fa7b22c2c43a55527..92dcb0e322f17bea12d468ba63fb0e88bf402eda 100644 (file)
@@ -130,6 +130,8 @@ class GlRetracer(Retracer):
     # object.  See also the ARB_pixel_buffer_object specification.
     pack_function_names = set([
         'glGetCompressedTexImage',
+        'glGetCompressedTextureImageEXT',
+        'glGetCompressedMultiTexImageEXT',
         'glGetConvolutionFilter',
         'glGetHistogram',
         'glGetMinmax',
@@ -139,6 +141,8 @@ class GlRetracer(Retracer):
         'glGetPolygonStipple',
         'glGetSeparableFilter',
         'glGetTexImage',
+        'glGetTextureImageEXT',
+        'glGetMultiTexImageEXT',
         'glReadPixels',
         'glGetnCompressedTexImageARB',
         'glGetnConvolutionFilterARB',
@@ -250,13 +254,18 @@ class GlRetracer(Retracer):
             print '    glretrace::insideGlBeginEnd = false;'
 
         if function.name.startswith('gl') and not function.name.startswith('glX'):
-            print r'    if (retrace::debug && !glretrace::currentContext) {'
+            print r'    if (retrace::debug && !glretrace::getCurrentContext()) {'
             print r'        retrace::warning(call) << "no current context\n";'
             print r'    }'
 
         if function.name == 'memcpy':
             print '    if (!dest || !src || !n) return;'
 
+        # Skip glEnable/Disable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) as we don't
+        # faithfully set the CONTEXT_DEBUG_BIT_ARB flags on context creation.
+        if function.name in ('glEnable', 'glDisable'):
+            print '    if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) return;'
+
         # Destroy the buffer mapping
         if function.name in self.unmap_function_names:
             print r'        GLvoid *ptr = NULL;'
@@ -278,15 +287,87 @@ class GlRetracer(Retracer):
             print r'        } else {'
             print r'            retrace::warning(call) << "no current context\n";'
             print r'        }'
-        
-        Retracer.invokeFunction(self, function)
 
-        # Error checking
+        if function.name in ('glBindProgramPipeline', 'glBindProgramPipelineEXT'):
+            # Note if glBindProgramPipeline has ever been called
+            print r'    if (pipeline) {'
+            print r'        _pipelineHasBeenBound = true;'
+            print r'    }'
+
+        profileDraw = (
+            function.name in self.draw_array_function_names or
+            function.name in self.draw_elements_function_names or
+            function.name in self.draw_indirect_function_names or
+            function.name in self.misc_draw_function_names or
+            function.name == 'glBegin'
+        )
+
+        if function.name in ('glUseProgram', 'glUseProgramObjectARB'):
+            print r'    glretrace::Context *currentContext = glretrace::getCurrentContext();'
+            print r'    if (currentContext) {'
+            print r'        currentContext->activeProgram = call.arg(0).toUInt();'
+            print r'    }'
+
+        # Only profile if not inside a list as the queries get inserted into list
+        if function.name == 'glNewList':
+            print r'    glretrace::insideList = true;'
+
+        if function.name == 'glEndList':
+            print r'    glretrace::insideList = false;'
+
+        if function.name != 'glEnd':
+            print r'    if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {'
+            if profileDraw:
+                print r'        glretrace::beginProfile(call, true);'
+            else:
+                print r'        glretrace::beginProfile(call, false);'
+            print r'    }'
+
+        if function.name == 'glCreateShaderProgramv':
+            # When dumping state, break down glCreateShaderProgramv so that the
+            # shader source can be recovered.
+            print r'    if (retrace::dumpingState) {'
+            print r'        GLuint _shader = glCreateShader(type);'
+            print r'        if (_shader) {'
+            print r'            glShaderSource(_shader, count, strings, NULL);'
+            print r'            glCompileShader(_shader);'
+            print r'            const GLuint _program = glCreateProgram();'
+            print r'            if (_program) {'
+            print r'                GLint compiled = GL_FALSE;'
+            print r'                glGetShaderiv(_shader, GL_COMPILE_STATUS, &compiled);'
+            print r'                glProgramParameteri(_program, GL_PROGRAM_SEPARABLE, GL_TRUE);'
+            print r'                if (compiled) {'
+            print r'                    glAttachShader(_program, _shader);'
+            print r'                    glLinkProgram(_program);'
+            print r'                    //glDetachShader(_program, _shader);'
+            print r'                }'
+            print r'                //append-shader-info-log-to-program-info-log'
+            print r'            }'
+            print r'            //glDeleteShader(_shader);'
+            print r'            _result = _program;'
+            print r'        } else {'
+            print r'            _result = 0;'
+            print r'        }'
+            print r'    } else {'
+            Retracer.invokeFunction(self, function)
+            print r'    }'
+        else:
+            Retracer.invokeFunction(self, function)
+
         if function.name == "glBegin":
             print '    glretrace::insideGlBeginEnd = true;'
-        elif function.name.startswith('gl'):
+
+        print r'    if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {'
+        if profileDraw:
+            print r'        glretrace::endProfile(call, true);'
+        else:
+            print r'        glretrace::endProfile(call, false);'
+        print r'    }'
+
+        # Error checking
+        if function.name.startswith('gl'):
             # glGetError is not allowed inside glBegin/glEnd
-            print '    if (retrace::debug && !glretrace::insideGlBeginEnd) {'
+            print '    if (retrace::debug && !glretrace::insideGlBeginEnd && glretrace::getCurrentContext()) {'
             print '        glretrace::checkGlError(call);'
             if function.name in ('glProgramStringARB', 'glProgramStringNV'):
                 print r'        GLint error_position = -1;'
@@ -306,7 +387,9 @@ class GlRetracer(Retracer):
                 print r'             retrace::warning(call) << infoLog << "\n";'
                 print r'             delete [] infoLog;'
                 print r'        }'
-            if function.name == 'glLinkProgram':
+            if function.name in ('glLinkProgram', 'glCreateShaderProgramv', 'glCreateShaderProgramEXT'):
+                if function.name != 'glLinkProgram':
+                    print r'        GLuint program = _result;'
                 print r'        GLint link_status = 0;'
                 print r'        glGetProgramiv(program, GL_LINK_STATUS, &link_status);'
                 print r'        if (!link_status) {'
@@ -397,9 +480,25 @@ class GlRetracer(Retracer):
 
         if arg.type is glapi.GLlocation \
            and 'program' not in function.argNames():
+            # Determine the active program for uniforms swizzling
             print '    GLint program = -1;'
-            print '    glGetIntegerv(GL_CURRENT_PROGRAM, &program);'
-        
+            print '    if (glretrace::insideList) {'
+            print '        // glUseProgram & glUseProgramObjectARB are display-list-able'
+            print r'    glretrace::Context *currentContext = glretrace::getCurrentContext();'
+            print '        program = _program_map[currentContext->activeProgram];'
+            print '    } else {'
+            print '        GLint pipeline = 0;'
+            print '        if (_pipelineHasBeenBound) {'
+            print '            glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING, &pipeline);'
+            print '        }'
+            print '        if (pipeline) {'
+            print '            glGetProgramPipelineiv(pipeline, GL_ACTIVE_PROGRAM, &program);'
+            print '        } else {'
+            print '            glGetIntegerv(GL_CURRENT_PROGRAM, &program);'
+            print '        }'
+            print '    }'
+            print
+
         if arg.type is glapi.GLlocationARB \
            and 'programObj' not in function.argNames():
             print '    GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);'
@@ -431,8 +530,10 @@ if __name__ == '__main__':
 #include "glstate.hpp"
 
 
+static bool _pipelineHasBeenBound = false;
 '''
-    api = glapi.glapi
-    api.addApi(glesapi.glesapi)
+    api = stdapi.API()
+    api.addModule(glapi.glapi)
+    api.addModule(glesapi.glesapi)
     retracer = GlRetracer()
     retracer.retraceApi(api)