mesa/shaderapi: add an optional shader override mechanism
MESA_SHADER_READ_PATH is handy but it's not usable in all cases. This commit allows to implement an alternative mechanism without assuming too much about how it's done, nor where/how the shaders are stored. When this is enabled MESA_SHADER_DUMP_PATH, MESA_SHADER_CAPTURE_PATH and MESA_GLSL env var handling is disabled. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11621>
This commit is contained in:
@@ -2006,6 +2006,12 @@ else
|
|||||||
dep_lmsensors = null_dep
|
dep_lmsensors = null_dep
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
_shader_replacement = get_option('custom-shader-replacement')
|
||||||
|
if _shader_replacement == ''
|
||||||
|
else
|
||||||
|
pre_args += '-DCUSTOM_SHADER_REPLACEMENT'
|
||||||
|
endif
|
||||||
|
|
||||||
with_perfetto = get_option('perfetto')
|
with_perfetto = get_option('perfetto')
|
||||||
with_datasources = get_option('datasources')
|
with_datasources = get_option('datasources')
|
||||||
with_any_datasource = with_datasources.length() != 0
|
with_any_datasource = with_datasources.length() != 0
|
||||||
|
@@ -502,3 +502,9 @@ option(
|
|||||||
choices : ['auto', 'panfrost', 'intel', 'freedreno'],
|
choices : ['auto', 'panfrost', 'intel', 'freedreno'],
|
||||||
description: 'List of Perfetto datasources to build. If this is set to `auto`, datasources that can not be build are skipped. Default: [`auto`]'
|
description: 'List of Perfetto datasources to build. If this is set to `auto`, datasources that can not be build are skipped. Default: [`auto`]'
|
||||||
)
|
)
|
||||||
|
option(
|
||||||
|
'custom-shader-replacement',
|
||||||
|
type : 'string',
|
||||||
|
value : '',
|
||||||
|
description : 'Enable a custom shader replacement mechanism. Note that enabling this option requires adding/generating a shader_replacement.h file that can be included (see shaderapi.c).'
|
||||||
|
)
|
||||||
|
@@ -64,8 +64,47 @@
|
|||||||
#include "util/crc32.h"
|
#include "util/crc32.h"
|
||||||
#include "util/os_file.h"
|
#include "util/os_file.h"
|
||||||
#include "util/simple_list.h"
|
#include "util/simple_list.h"
|
||||||
|
#include "util/u_process.h"
|
||||||
#include "util/u_string.h"
|
#include "util/u_string.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_SHADER_CACHE
|
||||||
|
#if CUSTOM_SHADER_REPLACEMENT
|
||||||
|
#include "shader_replacement.h"
|
||||||
|
/* shader_replacement.h must declare a variable like this:
|
||||||
|
|
||||||
|
struct _shader_replacement {
|
||||||
|
// process name. If null, only sha1 is used to match
|
||||||
|
const char *app;
|
||||||
|
// original glsl shader sha1
|
||||||
|
const char *sha1;
|
||||||
|
// shader stage
|
||||||
|
gl_shader_stage stage;
|
||||||
|
... any other information ...
|
||||||
|
};
|
||||||
|
struct _shader_replacement shader_replacements[...];
|
||||||
|
|
||||||
|
And a method to load a given replacement and return the new
|
||||||
|
glsl source:
|
||||||
|
|
||||||
|
char* load_shader_replacement(struct _shader_replacement *repl);
|
||||||
|
|
||||||
|
shader_replacement.h can be generated at build time, or copied
|
||||||
|
from an external folder, or any other method.
|
||||||
|
*/
|
||||||
|
#else
|
||||||
|
struct _shader_replacement {
|
||||||
|
const char *app;
|
||||||
|
const char *sha1;
|
||||||
|
gl_shader_stage stage;
|
||||||
|
};
|
||||||
|
struct _shader_replacement shader_replacements[0];
|
||||||
|
static char* load_shader_replacement(struct _shader_replacement *repl)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return mask of GLSL_x flags by examining the MESA_GLSL env var.
|
* Return mask of GLSL_x flags by examining the MESA_GLSL env var.
|
||||||
*/
|
*/
|
||||||
@@ -78,10 +117,12 @@ _mesa_get_shader_flags(void)
|
|||||||
if (env) {
|
if (env) {
|
||||||
if (strstr(env, "dump_on_error"))
|
if (strstr(env, "dump_on_error"))
|
||||||
flags |= GLSL_DUMP_ON_ERROR;
|
flags |= GLSL_DUMP_ON_ERROR;
|
||||||
|
#ifndef CUSTOM_SHADER_REPLACEMENT
|
||||||
else if (strstr(env, "dump"))
|
else if (strstr(env, "dump"))
|
||||||
flags |= GLSL_DUMP;
|
flags |= GLSL_DUMP;
|
||||||
if (strstr(env, "log"))
|
if (strstr(env, "log"))
|
||||||
flags |= GLSL_LOG;
|
flags |= GLSL_LOG;
|
||||||
|
#endif
|
||||||
if (strstr(env, "cache_fb"))
|
if (strstr(env, "cache_fb"))
|
||||||
flags |= GLSL_CACHE_FALLBACK;
|
flags |= GLSL_CACHE_FALLBACK;
|
||||||
if (strstr(env, "cache_info"))
|
if (strstr(env, "cache_info"))
|
||||||
@@ -1342,6 +1383,7 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CUSTOM_SHADER_REPLACEMENT
|
||||||
/* Capture .shader_test files. */
|
/* Capture .shader_test files. */
|
||||||
const char *capture_path = _mesa_get_shader_capture_path();
|
const char *capture_path = _mesa_get_shader_capture_path();
|
||||||
if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
|
if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
|
||||||
@@ -1386,6 +1428,7 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg,
|
|||||||
|
|
||||||
ralloc_free(filename);
|
ralloc_free(filename);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (shProg->data->LinkStatus == LINKING_FAILURE &&
|
if (shProg->data->LinkStatus == LINKING_FAILURE &&
|
||||||
(ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
|
(ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
|
||||||
@@ -1953,6 +1996,7 @@ construct_name(const gl_shader_stage stage, const char *sha,
|
|||||||
void
|
void
|
||||||
_mesa_dump_shader_source(const gl_shader_stage stage, const char *source)
|
_mesa_dump_shader_source(const gl_shader_stage stage, const char *source)
|
||||||
{
|
{
|
||||||
|
#ifndef CUSTOM_SHADER_REPLACEMENT
|
||||||
static bool path_exists = true;
|
static bool path_exists = true;
|
||||||
char *dump_path;
|
char *dump_path;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -1980,6 +2024,7 @@ _mesa_dump_shader_source(const gl_shader_stage stage, const char *source)
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
ralloc_free(name);
|
ralloc_free(name);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1996,6 +2041,24 @@ _mesa_read_shader_source(const gl_shader_stage stage, const char *source)
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
char sha[64];
|
char sha[64];
|
||||||
|
|
||||||
|
generate_sha1(source, sha);
|
||||||
|
|
||||||
|
const char *process_name =
|
||||||
|
ARRAY_SIZE(shader_replacements) ? util_get_process_name() : NULL;
|
||||||
|
for (size_t i = 0; i < ARRAY_SIZE(shader_replacements); i++) {
|
||||||
|
if (stage != shader_replacements[i].stage)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (shader_replacements[i].app &&
|
||||||
|
strcmp(process_name, shader_replacements[i].app) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (memcmp(sha, shader_replacements[i].sha1, 40) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return load_shader_replacement(&shader_replacements[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (!path_exists)
|
if (!path_exists)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -2005,8 +2068,7 @@ _mesa_read_shader_source(const gl_shader_stage stage, const char *source)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *name = construct_name(stage, generate_sha1(source, sha),
|
char *name = construct_name(stage, sha, source, read_path);
|
||||||
source, read_path);
|
|
||||||
f = fopen(name, "r");
|
f = fopen(name, "r");
|
||||||
ralloc_free(name);
|
ralloc_free(name);
|
||||||
if (!f)
|
if (!f)
|
||||||
|
@@ -962,6 +962,7 @@ _mesa_print_parameter_list(const struct gl_program_parameter_list *list)
|
|||||||
void
|
void
|
||||||
_mesa_write_shader_to_file(const struct gl_shader *shader)
|
_mesa_write_shader_to_file(const struct gl_shader *shader)
|
||||||
{
|
{
|
||||||
|
#ifndef CUSTOM_SHADER_REPLACEMENT
|
||||||
const char *type = "????";
|
const char *type = "????";
|
||||||
char filename[100];
|
char filename[100];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -1012,6 +1013,7 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user