From 81bda5afcccf41002128b2095442fe838d395969 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 17 Aug 2012 08:09:19 -0700 Subject: [PATCH] trim: Conservatively make shader programs depend on textures 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 | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cli/cli_trim.cpp b/cli/cli_trim.cpp index 0b6a8e8..45934e0 100644 --- a/cli/cli_trim.cpp +++ b/cli/cli_trim.cpp @@ -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; } -- 2.43.0