[PATCH] glretrace: Add a new --stub-fs to stub out fragment shaders

Carl Worth cworth at cworth.org
Thu Aug 2 15:39:03 PDT 2012


With this option, all fragment shaders will be replaced with a stub
shader that simply draws solid magenta. This can be useful for
measuring the time spent in all other portions of the pipeline.
---

 José Fonseca <jose.r.fonseca at gmail.com> writes:
 > I don't object this, but it's not easy to do GLSL shader manipulation
 > reliably (without human intervention), without at least a GLSL
 > pre-processor and tokenizer.

 What difficulties do you envision here? This patch was easy to write
 and seems to work well, (no parsing of GLSL needed).

 I suppose that if you wanted to do modification of a shader, without
 outright replacement, then yes, that would be quite a bit trickier.

 (Eric, give this patch a try and see what you think. Next I'll write
 the script to make two runs with and without --stub-fs, then combine
 the results, do the subtraction, and print a sorted list of individual
 fragment and vertex shaders.)

 > But at the end of the day, ARB_timer_query is just too cumbersome for
 > accurate profiling, and we should have another extension that provides
 > fined grained measurements. I think that Intel is well positioned to
 > design and prototype such extension.

 I don't think we need any new extension. There are already a couple of
 exsting extensions to make available more detailed information than
 ARB_timer_query. The ones I am thinking of are AMD_performance_monitor
 and GL_INTEL_performance_queries. Of these, AMD_performance_monitor is
 more interesting to me. Most significantly, it there exists public
 documentation for the specification:

	http://www.opengl.org/registry/specs/AMD/performance_monitor.txt

 And it looks to me like it would give us all the information we really
 need.

 So, yes, this is something that we do want to implement in our driver.

 retrace/glretrace.hpp      |    3 ++-
 retrace/glretrace.py       |   32 ++++++++++++++++++++++++++++++++
 retrace/glretrace_main.cpp |    2 +-
 retrace/retrace.hpp        |    5 +++++
 retrace/retrace_main.cpp   |    4 +++-
 5 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/retrace/glretrace.hpp b/retrace/glretrace.hpp
index fea187c..95756a2 100644
--- a/retrace/glretrace.hpp
+++ b/retrace/glretrace.hpp
@@ -29,12 +29,13 @@
 #include "glws.hpp"
 #include "retrace.hpp"
 
+#include <set>
 
 namespace glretrace {
 
 
 extern bool insideGlBeginEnd;
-
+extern std::set<unsigned> fragmentShaders;
 
 extern glws::Drawable *currentDrawable;
 extern glws::Context *currentContext;
diff --git a/retrace/glretrace.py b/retrace/glretrace.py
index 08fc6a0..186282c 100644
--- a/retrace/glretrace.py
+++ b/retrace/glretrace.py
@@ -289,10 +289,41 @@ class GlRetracer(Retracer):
             print r'    if (pipeline) {'
             print r'        _pipelineHasBeenBound = true;'
             print r'    }'
+
+        # We use the original shader ID values in the fragmentShader
+        # set for convenience.
+        if (function.name in ('glCreateShader', 'glCreateShaderObjectARB')):
+            print r'    if (static_cast<GLenum>((call.arg(0)).toSInt()) == GL_FRAGMENT_SHADER) {'
+            print r'        glretrace::fragmentShaders.insert((*call.ret).toUInt());'
+            print r'    }'
+
+        if (function.name in ('glDeleteShader', 'glDeleteObjectARB')):
+            print r'    glretrace::fragmentShaders.erase((call.arg(0)).toUInt());'
+
+        if function.name in ('glShaderSource', 'glShaderSourceARB'):
+            print r'    if (retrace::stubFragmentShaders && glretrace::fragmentShaders.find((call.arg(0)).toUInt()) != glretrace::fragmentShaders.end()) {'
+            print r'        count = 1;'
+            print r'        string[0] = "#version 120\n\n"'
+            print r'                    "void main()\n"'
+            print r'                    "{\n"'
+            print r'                    "     /* Magenta! */\n"'
+            print r'                    "    gl_FragColor = vec4(1, 0, 1, 1);\n"'
+            print r'                    "}";'
+            print r'        length[0] = strlen(string[0]);'
+            print r'    }'
         
         if function.name == 'glCreateShaderProgramv':
             # When dumping state, break down glCreateShaderProgramv so that the
             # shader source can be recovered.
+            print r'    if (retrace::stubFragmentShaders && type == GL_FRAGMENT_SHADER) {'
+            print r'        count = 1;'
+            print r'        strings[0] = "#version 120\n\n"'
+            print r'                     "void main()\n"'
+            print r'                     "{\n"'
+            print r'                     "     /* Magenta! */\n"'
+            print r'                     "    gl_FragColor = vec4(1, 0, 1, 1);\n"'
+            print r'                     "}";'
+            print r'    }'
             print r'    if (retrace::dumpingState) {'
             print r'        GLuint _shader = glCreateShader(type);'
             print r'        if (_shader) {'
@@ -477,6 +508,7 @@ class GlRetracer(Retracer):
 if __name__ == '__main__':
     print r'''
 #include <string.h>
+#include <set>
 
 #include "glproc.hpp"
 #include "glretrace.hpp"
diff --git a/retrace/glretrace_main.cpp b/retrace/glretrace_main.cpp
index a434d4b..88ec1bf 100644
--- a/retrace/glretrace_main.cpp
+++ b/retrace/glretrace_main.cpp
@@ -35,7 +35,7 @@
 namespace glretrace {
 
 bool insideGlBeginEnd = false;
-
+std::set<unsigned> fragmentShaders;
 
 void
 checkGlError(trace::Call &call) {
diff --git a/retrace/retrace.hpp b/retrace/retrace.hpp
index 0ee0e55..be49156 100644
--- a/retrace/retrace.hpp
+++ b/retrace/retrace.hpp
@@ -152,6 +152,11 @@ extern bool profiling;
  */
 extern bool dumpingState;
 
+/**
+ * Stubbing out fragment shaders (to measure vertex shader contribution)
+ */
+extern bool stubFragmentShaders;
+
 
 extern bool doubleBuffer;
 extern bool coreProfile;
diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
index 093ab17..086ef42 100644
--- a/retrace/retrace_main.cpp
+++ b/retrace/retrace_main.cpp
@@ -55,7 +55,7 @@ int verbosity = 0;
 bool debug = true;
 bool profiling = false;
 bool dumpingState = false;
-
+bool stubFragmentShaders = false;
 
 bool doubleBuffer = true;
 bool coreProfile = false;
@@ -319,6 +319,8 @@ int main(int argc, char **argv)
             retrace::debug = false;
             retrace::profiling = true;
             retrace::verbosity = -1;
+        } else if (!strcmp(arg, "--stub-fs")) {
+            retrace::stubFragmentShaders = true;
         } else if (!strcmp(arg, "-c")) {
             comparePrefix = argv[++i];
             if (compareFrequency.empty()) {
-- 
1.7.10

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/apitrace/attachments/20120802/85c00cc6/attachment.pgp>


More information about the apitrace mailing list