]> git.cworth.org Git - apitrace/blobdiff - cli/cli_trim.cpp
trim: Add support for display lists.
[apitrace] / cli / cli_trim.cpp
index 4cfe18f8fb769943fb1fcdd548a96363831a3935..6820b0072bd09fde4aabc94196d779cd06b846e7 100644 (file)
@@ -42,6 +42,7 @@
 #include "trace_parser.hpp"
 #include "trace_writer.hpp"
 
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
 #define STRNCMP_LITERAL(var, literal) strncmp((var), (literal), sizeof (literal) -1)
 
 static const char *synopsis = "Create a new trace by trimming an existing trace.";
@@ -172,7 +173,9 @@ class TraceAnalyzer {
     bool transformFeedbackActive;
     bool framebufferObjectActive;
     bool insideBeginEnd;
+    GLuint insideNewEndList;
     GLuint activeProgram;
+    GLenum activeTextureUnit;
 
     /* Rendering often has no side effects, but it can in some cases,
      * (such as when transform feedback is active, or when rendering
@@ -302,6 +305,11 @@ class TraceAnalyzer {
             return;
         }
 
+        if (strcmp(name, "glActiveTexture") == 0) {
+            activeTextureUnit = static_cast<GLenum>(call->arg(0).toSInt());
+            return;
+        }
+
         if (strcmp(name, "glBindTexture") == 0) {
             GLenum target;
             GLuint texture;
@@ -338,6 +346,12 @@ class TraceAnalyzer {
             }
             return;
         }
+
+        if (strcmp(name, "glNewList") == 0) {
+            GLuint list = call->arg(0).toUInt();
+
+            insideNewEndList = list;
+        }
     }
 
     void stateTrackPostCall(trace::Call *call) {
@@ -364,12 +378,32 @@ class TraceAnalyzer {
             resources.erase("framebuffer");
             return;
         }
+
+        if (strcmp(name, "glEndList") == 0) {
+            insideNewEndList = 0;
+        }
     }
 
     void recordSideEffects(trace::Call *call) {
 
         const char *name = call->name();
 
+        /* Handle display lists before any other processing. */
+
+        /* FIXME: If we encode the list of commands that are executed
+         * immediately (as opposed to those that are compiled into a
+         * display list) then we could generate a "display-list-X"
+         * resource just as we do for "texture-X" resources and only
+         * emit it in the trace if a glCallList(X) is emitted. For
+         * now, simply punt and include anything within glNewList and
+         * glEndList in the trim output. This guarantees that display
+         * lists will work, but does not trim out unused display
+         * lists. */
+        if (insideNewEndList != 0) {
+            provide("state", call->no);
+            return;
+        }
+
         /* If call is flagged as no side effects, then we are done here. */
         if (call->flags & trace::CALL_FLAG_NO_SIDE_EFFECTS) {
             return;
@@ -404,7 +438,7 @@ class TraceAnalyzer {
             target = static_cast<GLenum>(call->arg(0).toSInt());
             texture = call->arg(1).toUInt();
 
-            ss_target << "texture-target-" << target;
+            ss_target << "texture-unit-" << activeTextureUnit << "-target-" << target;
             ss_texture << "texture-" << texture;
 
             resources.erase(ss_target.str());
@@ -432,7 +466,7 @@ class TraceAnalyzer {
 
             GLenum target = static_cast<GLenum>(call->arg(0).toSInt());
 
-            ss_target << "texture-target-" << target;
+            ss_target << "texture-unit-" << activeTextureUnit << "-target-" << target;
             ss_texture << "texture-" << texture_map[target];
 
             /* The texture resource depends on this call and any calls
@@ -459,7 +493,11 @@ class TraceAnalyzer {
                 cap == GL_TEXTURE_3D ||
                 cap == GL_TEXTURE_CUBE_MAP)
             {
-                linkf("render-state", "texture-target-", cap);
+                std::stringstream ss;
+
+                ss << "texture-unit-" << activeTextureUnit << "-target-" << cap;
+
+                link("render-state", ss.str());
             }
 
             provide("state", call->no);
@@ -476,7 +514,11 @@ class TraceAnalyzer {
                 cap == GL_TEXTURE_3D ||
                 cap == GL_TEXTURE_CUBE_MAP)
             {
-                unlinkf("render-state", "texture-target-", cap);
+                std::stringstream ss;
+
+                ss << "texture-unit-" << activeTextureUnit << "-target-" << cap;
+
+                unlink("render-state", ss.str());
             }
 
             provide("state", call->no);
@@ -595,6 +637,41 @@ class TraceAnalyzer {
             strcmp(call->sig->arg_names[0], "location") == 0) {
 
             providef("program-", activeProgram, call->no);
+
+            /* We can't easily tell if this uniform is being used to
+             * associate a sampler in the shader with a texture
+             * unit. The conservative option is to assume that it is
+             * and create a link from the active program to any bound
+             * textures for the given unit number.
+             *
+             * FIXME: We should be doing the same thing for calls to
+             * glUniform1iv. */
+            if (strcmp(name, "glUniform1i") == 0 ||
+                strcmp(name, "glUniform1iARB") == 0) {
+
+                GLint max_unit = MAX(GL_MAX_TEXTURE_COORDS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+
+                GLint unit = call->arg(1).toSInt();
+                std::stringstream ss_program;
+                std::stringstream ss_texture;
+
+                if (unit < max_unit) {
+
+                    ss_program << "program-" << activeProgram;
+
+                    ss_texture << "texture-unit-" << GL_TEXTURE0 + unit << "-target-";
+
+                    /* We don't know what target(s) might get bound to
+                     * this texture unit, so conservatively link to
+                     * all. Only bound textures will actually get inserted
+                     * into the output call stream. */
+                    linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_1D);
+                    linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_2D);
+                    linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_3D);
+                    linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_CUBE_MAP);
+                }
+            }
+
             return;
         }
 
@@ -667,7 +744,9 @@ class TraceAnalyzer {
 public:
     TraceAnalyzer(): transformFeedbackActive(false),
                      framebufferObjectActive(false),
-                     insideBeginEnd(false)
+                     insideBeginEnd(false),
+                     insideNewEndList(0),
+                     activeTextureUnit(GL_TEXTURE0)
     {}
 
     ~TraceAnalyzer() {}