]> git.cworth.org Git - apitrace/commitdiff
replay: Support applications mixing glCreateProgramObjectARB and glUseProgram
authorCarl Worth <cworth@cworth.org>
Tue, 28 Aug 2012 18:45:52 +0000 (11:45 -0700)
committerCarl Worth <cworth@cworth.org>
Sat, 16 Feb 2013 02:24:31 +0000 (18:24 -0800)
As is known to happen with OpenGL, there are many more than one ways
to do the same thing. In this case, one can create a program
(glCreateProgram) or a program object (glCreateProgramObjectARB) along
with many similar pairs of functions.

In fact, a single application might even mix these two approaches,
(for example, calling glCreateProgramObjectARB and then calling
glUseProgram rather than glUseProgramObjectARB).

Historically, glretrace could fail with such mixed usage. The calls
into the ObjectARB function would go through _handleARB_map while the
other calls would go through _program_map, so after mixed calls the
desired object would not be found in the referenced map.

Making mixed usage work requires merging both _program_map and
_shader_map together with _handleARB map. This is correct for any
OpenGL implementation which supports the GL_ARB_shader_objects
extension, since there is no way to implement this extension correctly
without having shaders and programs in the same namespace.

However, we carefully maintain separate _shader_map and _program_map
for an OpenGL implementation not supporting GL_ARB_shader_objects. In
this case, it's not possible for an application to mix usage (since
none of the ObjectARB functions are guaranteed to exist). And it's
also possible for the implementation to provide separate namespaces
for shaders and programs, so they each need their own map.

retrace/glretrace.hpp
retrace/glretrace_main.cpp
retrace/retrace.py

index 95a6d7596df230e8dd059194c493bbf58055cad3..7441b56938e22481e0110b181b74b7de81a55c98 100644 (file)
@@ -60,7 +60,7 @@ struct Context {
 
 extern bool insideList;
 extern bool insideGlBeginEnd;
-
+extern bool supportsARBShaderObjects;
 
 Context *
 getCurrentContext(void);
index d0298fcb74e76e4dc8f99d6ab103ab8f65e5b0e5..f369b33b7316c0f2c7ce7181268ba2c8736bbcaa 100755 (executable)
@@ -42,6 +42,7 @@ namespace glretrace {
 
 bool insideList = false;
 bool insideGlBeginEnd = false;
+bool supportsARBShaderObjects = false;
 
 enum {
     GPU_START = 0,
@@ -246,6 +247,7 @@ initContext() {
     supportsElapsed     = currentContext->hasExtension("GL_EXT_timer_query") || supportsTimestamp;
     supportsOcclusion   = currentContext->hasExtension("GL_ARB_occlusion_query");
     supportsDebugOutput = currentContext->hasExtension("GL_ARB_debug_output");
+    supportsARBShaderObjects = currentContext->hasExtension("GL_ARB_shader_objects");
 
     /* Check for timer query support */
     if (retrace::profilingGpuTimes) {
index cd5ef1d2136770f21c5097f0480c6c8b661059d7..d09d72aa2ca46aff0c10380463b51cfcb455c1c7 100644 (file)
@@ -166,7 +166,14 @@ class ValueDeserializer(stdapi.Visitor, stdapi.ExpanderMixin):
         print '    if (retrace::verbosity >= 2) {'
         print '        std::cout << "%s " << size_t(%s) << " <- " << size_t(%s) << "\\n";' % (handle.name, lvalue, new_lvalue)
         print '    }'
-        print '    %s = %s;' % (lvalue, new_lvalue)
+        if (new_lvalue.startswith('_program_map') or new_lvalue.startswith('_shader_map')):
+            print 'if (glretrace::supportsARBShaderObjects) {'
+            print '    %s = _handleARB_map[%s];' % (lvalue, lvalue)
+            print '} else {'
+            print '    %s = %s;' % (lvalue, new_lvalue)
+            print '}'
+        else:
+            print '    %s = %s;' % (lvalue, new_lvalue)
     
     def visitBlob(self, blob, lvalue, rvalue):
         print '    %s = static_cast<%s>((%s).toPointer());' % (lvalue, blob, rvalue)
@@ -279,8 +286,15 @@ class SwizzledValueRegistrator(stdapi.Visitor, stdapi.ExpanderMixin):
         OpaqueValueDeserializer().visit(handle.type, '_origResult', rvalue);
         if handle.range is None:
             rvalue = "_origResult"
-            entry = lookupHandle(handle, rvalue) 
-            print "    %s = %s;" % (entry, lvalue)
+            entry = lookupHandle(handle, rvalue)
+            if (entry.startswith('_program_map') or entry.startswith('_shader_map')):
+                print 'if (glretrace::supportsARBShaderObjects) {'
+                print '    _handleARB_map[%s] = %s;' % (rvalue, lvalue)
+                print '} else {'
+                print '    %s = %s;' % (entry, lvalue)
+                print '}'
+            else:
+                print "    %s = %s;" % (entry, lvalue)
             print '    if (retrace::verbosity >= 2) {'
             print '        std::cout << "{handle.name} " << {rvalue} << " -> " << {lvalue} << "\\n";'.format(**locals())
             print '    }'