diff options
author | Tapani Pälli <tapani.palli@intel.com> | 2017-10-24 15:06:37 +0300 |
---|---|---|
committer | Tapani Pälli <tapani.palli@intel.com> | 2017-11-03 13:18:11 +0200 |
commit | d6a24da8cf10a0fc726552f46f1eb340f1b1ba99 (patch) | |
tree | 99ac0a565351361fa6a8af4bf146535e75d64a52 | |
parent | 57372c5a42969afe6c7afd6a0389a92e3e1a5178 (diff) |
AndroidIA: glsl runtime modification infrastructure WIPreplacement
This infrastructure can be used for debugging shaders or
implementing features/optimizations for known app issues.
Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
-rw-r--r-- | src/mesa/main/glsl_modifications.c | 11 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.c | 127 |
2 files changed, 138 insertions, 0 deletions
diff --git a/src/mesa/main/glsl_modifications.c b/src/mesa/main/glsl_modifications.c new file mode 100644 index 00000000000..8da356992b9 --- /dev/null +++ b/src/mesa/main/glsl_modifications.c @@ -0,0 +1,11 @@ + + { + "7b7cb322a1f2d2aadfe7299c8ccf336a2f48dd37", + { + { + INSERT, + 63, + " if (motion.xy == vec2(0.5) || texel.a == 0.0) { gl_FragColor = texel; return; }", + }, + }, + }, diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 72824355838..b6f5322c49e 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -1856,6 +1856,131 @@ read_shader(const gl_shader_stage stage, const char *source) #endif /* ENABLE_SHADER_CACHE */ /** + * REPLACE, replace or remove + * INSERT, insert before line + */ +enum { + REPLACE = 0, + INSERT +}; + +/** + * Shader modifications. + */ +struct mod { + uint8_t type; + uint32_t line; + const char *data; +}; + +struct mod_db { + const char *sha; + const struct mod list[64]; +} db[] = { +#include "glsl_modifications.c" +}; + +static int mod_cmp(const void *a, const void *b) +{ + const struct mod_db *sa = (const struct mod_db *) a; + const struct mod_db *sb = (const struct mod_db *) b; + + return strcmp(sa->sha, sb->sha); +} + +static int scmp(const void *a, const void *b) +{ + const char *sa = (const char *) a; + const struct mod_db *sb = (const struct mod_db *) b; + + return strcmp(sa, sb->sha); +} + +/** + * Implementation of small line based parser that can + * insert/replace/delete lines from given shader source. + * + */ +static char * +modifications(const char *source) +{ + char sha_str[64]; + unsigned char sha[20]; + _mesa_sha1_compute(source, strlen(source), sha); + _mesa_sha1_format(sha_str, sha); + + /* no newlines, not compatible */ + if (!strchr(source, '\n')) + return (char*)source; + + /* TODO - move one time init to context initialization */ + static bool init = false; + if (!init) { + qsort(db, ARRAY_SIZE(db), sizeof(struct mod_db), mod_cmp); + init = true; + } + + const struct mod *modifications = NULL; + + /* check if any modifications available */ + struct mod_db *dbp = + bsearch(sha_str, db, ARRAY_SIZE(db), sizeof(struct mod_db), scmp); + + if (dbp) + modifications = dbp->list; + + /* no modifications, return source as is */ + if (!modifications) + return (char*) source; + + char *str = ralloc_asprintf(NULL, ""); + + /* move cursor through shader lines */ + unsigned line = 1; + const char *cur = source; + while (strchr(cur, '\n')) { + const char *end = strchr(cur, '\n'); + + char *current = (char*) malloc ((end - cur) + 1); + + strncpy(current, cur, end - cur); + current[end - cur] = '\0'; + + bool match = false; + + /* iterate list of modifications for this shader */ + const struct mod *list = modifications; + while (list->line) { + if (list->line == line) { + match = true; + ralloc_asprintf_append(&str, "%s\n", list->data); + + if (list->type != REPLACE) + ralloc_asprintf_append(&str, "%s\n", current); + } + list++; + } + + if (!match) + ralloc_asprintf_append(&str, "%s\n", current); + + free(current); + + cur = end + 1; + line++; + } + + /* free original source and return changed one */ + free((char*)source); + + char *result = strdup(str); + ralloc_free(str); + + return (char *) result; +} + + +/** * Called via glShaderSource() and glShaderSourceARB() API functions. * Basically, concatenate the source code strings into one long string * and pass it to _mesa_shader_source(). @@ -1943,6 +2068,8 @@ shader_source(struct gl_context *ctx, GLuint shaderObj, GLsizei count, } #endif /* ENABLE_SHADER_CACHE */ + source = modifications(source); + set_shader_source(sh, source); free(offsets); |