]> git.cworth.org Git - apitrace/commitdiff
trim: Conservatively make shader programs depend on textures
authorCarl Worth <cworth@cworth.org>
Fri, 17 Aug 2012 15:09:19 +0000 (08:09 -0700)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 22 Nov 2012 08:03:25 +0000 (08:03 +0000)
Some shader programs sample textures, so if the shader is included in
the trimmed output the texture needs to be included as well.

We don't have support inside of "apitrace trim" to parse GLSL to find
names of samplers to find these dependencies. Instead, we provide here
a simple heuristic:

In order to sample a texture, the OpenGL program must associate the
name of a texture unit with a location in the shader by calling
glUniform1i (or glUniform1iv). So we can notice whenever texture-unit
names are being passed and create a dependency from the shader to all
texture targets for that unit.

This is conservative on two fronts:

  1. The value being passed to glUniformi might only be coincidentally
     the same as a texture-unit name and be actually unrelated to
     texture sampling.

  2. The shader likely doesn't depend on all texture targets, but
     again we can't know which without looking inside the shader, so
     we associate all of them.

cli/cli_trim.cpp

index 0b6a8e82df8c96b8bf624793bd8a6f2dc0dbc399..45934e0b166840b29653d0460177ad8f292cf75b 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.";
@@ -609,6 +610,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;
         }