summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/arbprogram.c22
-rw-r--r--src/mesa/main/shaderapi.c52
-rw-r--r--src/mesa/main/shaderapi.h3
3 files changed, 77 insertions, 0 deletions
diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c
index 3f7acda9f32..c0786d4230d 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/shaderapi.c b/src/mesa/main/shaderapi.c
index 167e06f3d4f..eb6b1f5a7e8 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -96,6 +96,29 @@ _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 (path &&
+ 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 +1069,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 d2d7f16ec7c..09b9525e402 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);