]> git.cworth.org Git - apitrace/commitdiff
trim: Add support for trimming out unused shaders.
authorCarl Worth <cworth@cworth.org>
Tue, 14 Aug 2012 22:20:56 +0000 (15:20 -0700)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 22 Nov 2012 08:03:10 +0000 (08:03 +0000)
The provide/consume analysis framework is finally starting to show
dividends. This is a fairly significant amount of new functionality
for "apitrace trim" yet it requires relatively little new code.

cli/cli_trim.cpp

index 1c32bce0a6b6c41bc084cd204b6ada97e56bbcb4..abcae0a0b34ec10ea7dc546838e43b74636a2e44 100644 (file)
@@ -149,6 +149,7 @@ class TraceAnalyzer {
 
     /* Maps for tracking OpenGL state. */
     std::map<GLenum, unsigned> texture_map;
+    std::map<GLint, GLuint> location_program_map;
 
     /* The final set of calls required. This consists of calls added
      * explicitly with the require() method as well as all calls
@@ -452,6 +453,189 @@ class TraceAnalyzer {
             return;
         }
 
+        if (strcmp(name, "glCreateShader") == 0 ||
+            strcmp(name, "glCreateShaderObjectARB") == 0) {
+
+            GLuint shader;
+            std::stringstream ss;
+
+            shader = call->ret->toUInt();
+
+            ss << "shader-" << shader;
+
+            provide(ss.str(), call->no);
+
+            return;
+        }
+
+        if (strcmp(name, "glShaderSource") == 0 ||
+            strcmp(name, "glShaderSourceARB") == 0 ||
+            strcmp(name, "glCompileShader") == 0 ||
+            strcmp(name, "glCompileShaderARB") == 0 ||
+            strcmp(name, "glGetShaderiv") == 0 ||
+            strcmp(name, "glGetShaderInfoLog") == 0) {
+
+            GLuint shader;
+            std::stringstream ss;
+
+            shader = call->arg(0).toUInt();
+
+            ss << "shader-" << shader;
+
+            provide(ss.str(), call->no);
+
+            return;
+        }
+
+        if (strcmp(name, "glCreateProgram") == 0 ||
+            strcmp(name, "glCreateProgramObjectARB") == 0) {
+
+            GLuint program;
+            std::stringstream ss;
+
+            program = call->ret->toUInt();
+
+            ss << "program-" << program;
+
+            provide(ss.str(), call->no);
+
+            return;
+        }
+
+        if (strcmp(name, "glAttachShader") == 0 ||
+            strcmp(name, "glAttachObjectARB") == 0) {
+
+            GLuint program, shader;
+            std::stringstream ss_program, ss_shader;
+
+            program = call->arg(0).toUInt();
+            shader = call->arg(1).toUInt();
+
+            ss_program << "program-" << program;
+            ss_shader << "shader-" << shader;
+
+            link(ss_program.str(), ss_shader.str());
+            provide(ss_program.str(), call->no);
+
+            return;
+        }
+
+        if (strcmp(name, "glDetachShader") == 0 ||
+            strcmp(name, "glDetachObjectARB") == 0) {
+
+            GLuint program, shader;
+            std::stringstream ss_program, ss_shader;
+
+            program = call->arg(0).toUInt();
+            shader = call->arg(1).toUInt();
+
+            ss_program << "program-" << program;
+            ss_shader << "shader-" << shader;
+
+            unlink(ss_program.str(), ss_shader.str());
+
+            return;
+        }
+
+        if (strcmp(name, "glUseProgram") == 0 ||
+            strcmp(name, "glUseProgramObjectARB") == 0) {
+
+            GLuint program;
+
+            program = call->arg(0).toUInt();
+
+            unlinkAll("render-program-state");
+
+            if (program == 0) {
+                unlink("render-state", "render-program-state");
+                provide("state", call->no);
+            } else {
+                std::stringstream ss;
+
+                ss << "program-" << program;
+
+                link("render-state", "render-program-state");
+                link("render-program-state", ss.str());
+
+                provide(ss.str(), call->no);
+            }
+
+            return;
+        }
+
+        if (strcmp(name, "glGetUniformLocation") == 0 ||
+            strcmp(name, "glGetUniformLocationARB") == 0 ||
+            strcmp(name, "glGetFragDataLocation") == 0 ||
+            strcmp(name, "glGetFragDataLocationEXT") == 0 ||
+            strcmp(name, "glGetSubroutineUniformLocation") == 0 ||
+            strcmp(name, "glGetProgramResourceLocation") == 0 ||
+            strcmp(name, "glGetProgramResourceLocationIndex") == 0 ||
+            strcmp(name, "glGetVaryingLocationNV") == 0) {
+
+            GLuint program;
+            GLint location;
+            std::stringstream ss;
+
+            program = call->arg(0).toUInt();
+            location = call->ret->toSInt();
+
+            location_program_map[location] = program;
+
+            ss << "program-" << program;
+
+            provide(ss.str(), call->no);
+
+            return;
+        }
+
+        /* For any call that accepts 'location' as its first argument,
+         * perform a lookup in our location->program map and add a
+         * dependence on the program we find there. */
+        if (call->sig->num_args > 0 &&
+            strcmp(call->sig->arg_names[0], "location") == 0) {
+
+            GLuint program;
+            GLint location;
+            std::stringstream ss;
+
+            location = call->arg(0).toSInt();
+
+            program = location_program_map[location];
+
+            ss << "program-" << program;
+
+            provide(ss.str(), call->no);
+
+            return;
+        }
+
+        /* FIXME: We cut a huge swath by assuming that any unhandled
+         * call that has a first argument named "program" should not
+         * be included in the trimmed output unless the program of
+         * that number is also included.
+         *
+         * This heuristic is correct for many cases, but we should
+         * actually carefully verify if this includes some calls
+         * inappropriately, or if it misses some.
+         */
+        if (strcmp(name, "glLinkProgram") == 0 ||
+            strcmp(name, "glLinkProgramARB") == 0 ||
+            (call->sig->num_args > 0 &&
+             (strcmp(call->sig->arg_names[0], "program") == 0 ||
+              strcmp(call->sig->arg_names[0], "programObj") == 0))) {
+
+            GLuint program;
+            std::stringstream ss;
+
+            program = call->arg(0).toUInt();
+
+            ss << "program-" << program;
+
+            provide(ss.str(), call->no);
+
+            return;
+        }
+
         /* Handle all rendering operations, (even though only glEnd is
          * flagged as a rendering operation we treat everything from
          * glBegin through glEnd as a rendering operation). */