mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 18:40:13 +01:00
mesa: Add MESA_SHADER_CAPTURE_PATH for writing .shader_test files.
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). v11: Fix crash when variable is unset introduced in v10. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
parent
092ec3920f
commit
c417c0c9c3
3 changed files with 77 additions and 0 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue