[Mesa-dev] [PATCH] mesa: Add MESA_SHADER_CAPTURE_PATH for writing .shader_test files.

Kenneth Graunke kenneth at whitecape.org
Wed Jun 1 08:14:59 UTC 2016


This writes linked shader programs to .shader_test files to
$MESA_SHADER_CAPTURE_PATH in the format used by shader-db
(http://cgit.freedesktop.org/mesa/shader-db).

It supports both GLSL shaders and ARB programs.  All stages that
are linked together are written in a single .shader_test file.

This eliminates the need for shader-db's split-to-files.py, as Mesa
produces the desired format directly.  It's much more reliable than
parsing stdout/stderr, as those may contain extraneous messages, or
simply be closed by the application and unavailable.

We have many similar features already, but this is a bit different:
- MESA_GLSL=dump writes to stdout, not files.
- MESA_GLSL=log writes each stage to separate files (rather than
  all linked shaders in one file), at draw time (not link time),
  with uniform data and state flag info.
- Tapani's shader replacement mechanism (MESA_SHADER_DUMP_PATH and
  MESA_SHADER_READ_PATH) also uses separate files per shader stage,
  but allows reading in files to replace an app's shader code.

v2:  Dump ARB programs too, not just GLSL.
v3:  Don't dump bogus 0.shader_test file.
v4:  Add "GL_ARB_separate_shader_objects" to the [require] block.
v5:  Print "GLSL 4.00" instead of "GLSL 4.0" in the [require] block.
v6:  Don't hardcode /tmp/mesa.
v7:  Fix memoization of getenv().
v8:  Also print "SSO ENABLED" (suggested by Timothy).
v9:  Also handle ES shaders (suggested by Ilia).
v10: Guard against MESA_SHADER_CAPTURE_PATH being too long; add
     _mesa_warning calls on error handling (suggested by Ben).

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/main/arbprogram.c | 22 ++++++++++++++++++++
 src/mesa/main/mtypes.h     |  1 -
 src/mesa/main/shaderapi.c  | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/shaderapi.h  |  3 +++
 4 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c
index 3f7acda..c0786d4 100644
--- a/src/mesa/main/arbprogram.c
+++ b/src/mesa/main/arbprogram.c
@@ -36,6 +36,7 @@
 #include "main/macros.h"
 #include "main/mtypes.h"
 #include "main/arbprogram.h"
+#include "main/shaderapi.h"
 #include "program/arbprogparse.h"
 #include "program/program.h"
 #include "program/prog_print.h"
@@ -378,6 +379,27 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
       }
       fflush(stderr);
    }
+
+   /* Capture vp-*.shader_test/fp-*.shader_test files. */
+   const char *capture_path = _mesa_get_shader_capture_path();
+   if (capture_path != NULL) {
+      FILE *file;
+      char filename[PATH_MAX];
+      const char *shader_type =
+         target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";
+
+      _mesa_snprintf(filename, sizeof(filename), "%s/%cp-%u.shader_test",
+                     capture_path, shader_type[0], base->Id);
+      file = fopen(filename, "w");
+      if (file) {
+         fprintf(file,
+                 "[require]\nGL_ARB_%s_program\n\n[%s program]\n%s\n",
+                 shader_type, shader_type, (const char *) string);
+         fclose(file);
+      } else {
+         _mesa_warning(ctx, "Failed to open %s", filename);
+      }
+   }
 }
 
 
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 2233526..2d06755 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2882,7 +2882,6 @@ struct gl_shader_program
 #define GLSL_REPORT_ERRORS 0x100  /**< Print compilation errors */
 #define GLSL_DUMP_ON_ERROR 0x200 /**< Dump shaders to stderr on compile error */
 
-
 /**
  * Context state for GLSL vertex/fragment shaders.
  * Extended to support pipeline object
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 167e06f..e52d5bf 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -96,6 +96,28 @@ _mesa_get_shader_flags(void)
    return flags;
 }
 
+/**
+ * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH").
+ */
+const char *
+_mesa_get_shader_capture_path(void)
+{
+   static bool read_env_var = false;
+   static const char *path = NULL;
+
+   if (!read_env_var) {
+      path = getenv("MESA_SHADER_CAPTURE_PATH");
+      read_env_var = true;
+      if (strlen(path) > PATH_MAX - strlen("/fp-4294967295.shader_test")) {
+         GET_CURRENT_CONTEXT(ctx);
+         _mesa_warning(ctx, "MESA_SHADER_CAPTURE_PATH too long; ignoring "
+                            "request to capture shaders");
+         path = NULL;
+      }
+   }
+
+   return path;
+}
 
 /**
  * Initialize context's shader state.
@@ -1046,6 +1068,35 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
 
    _mesa_glsl_link_shader(ctx, shProg);
 
+   /* Capture .shader_test files. */
+   const char *capture_path = _mesa_get_shader_capture_path();
+   if (shProg->Name != 0 && capture_path != NULL) {
+      FILE *file;
+      char filename[PATH_MAX];
+
+      _mesa_snprintf(filename, sizeof(filename), "%s/%u.shader_test",
+                     capture_path, shProg->Name);
+
+      file = fopen(filename, "w");
+      if (file) {
+         fprintf(file, "[require]\nGLSL%s >= %u.%02u\n",
+                 shProg->IsES ? " ES" : "",
+                 shProg->Version / 100, shProg->Version % 100);
+         if (shProg->SeparateShader)
+            fprintf(file, "GL_ARB_separate_shader_objects\nSSO ENABLED\n");
+         fprintf(file, "\n");
+
+         for (unsigned i = 0; i < shProg->NumShaders; i++) {
+            fprintf(file, "[%s shader]\n%s\n",
+                    _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
+                    shProg->Shaders[i]->Source);
+         }
+         fclose(file);
+      } else {
+         _mesa_warning(ctx, "Failed to open %s", filename);
+      }
+   }
+
    if (shProg->LinkStatus == GL_FALSE &&
        (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
       _mesa_debug(ctx, "Error linking program %u:\n%s\n",
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index d2d7f16..09b9525 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -43,6 +43,9 @@ struct gl_shader_program;
 extern GLbitfield
 _mesa_get_shader_flags(void);
 
+extern const char *
+_mesa_get_shader_capture_path(void);
+
 extern void
 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
                   GLsizei *length, const GLchar *src);
-- 
2.8.3



More information about the mesa-dev mailing list