summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2017-10-24 15:06:37 +0300
committerTapani Pälli <tapani.palli@intel.com>2017-11-03 13:18:11 +0200
commitd6a24da8cf10a0fc726552f46f1eb340f1b1ba99 (patch)
tree99ac0a565351361fa6a8af4bf146535e75d64a52
parent57372c5a42969afe6c7afd6a0389a92e3e1a5178 (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.c11
-rw-r--r--src/mesa/main/shaderapi.c127
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);