[Mesa-dev] [PATCH 2/6] mesa: Track whether shaders have been recompiled since the last link.
Kenneth Graunke
kenneth at whitecape.org
Wed May 14 17:28:13 PDT 2014
OpenGL allows you to call ShaderSource and CompileShader on existing
shaders which are already attached to programs that have been linked.
I want to be able to accurately track when programs need relinking,
and unfortunately this is one of those cases.
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
src/glsl/linker.cpp | 7 +++++++
src/mesa/main/mtypes.h | 2 ++
src/mesa/main/shaderapi.c | 28 ++++++++++++++++++++++++++++
src/mesa/main/shaderapi.h | 3 +++
4 files changed, 40 insertions(+)
I loathe this code. I'd say there has to be a better way, but I sure
couldn't think of one.
This is necessary to make Piglit's glsl-reload-source continue passing
after my early-return-from-LinkProgram patch, later in the series.
I don't know why OpenGL made this a feature.
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index a43d230..49eb2d4 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2618,6 +2618,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
/* FINISHME: Assign fragment shader output locations. */
done:
+ if (prog->LinkStatus) {
+ ralloc_free(prog->ShaderEpochs);
+ prog->ShaderEpochs = ralloc_array(prog, unsigned, prog->NumShaders);
+ for (unsigned i = 0; i < prog->NumShaders; i++)
+ prog->ShaderEpochs[i] = prog->Shaders[i]->CompileEpoch;
+ }
+
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
free(shader_list[i]);
if (prog->_LinkedShaders[i] == NULL)
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 741f936..df7715b 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2379,6 +2379,7 @@ struct gl_shader
GLint RefCount; /**< Reference count */
GLboolean DeletePending;
GLboolean CompileStatus;
+ unsigned CompileEpoch; /**< Incremented each time the shader is recompiled */
const GLchar *Source; /**< Source code string */
GLuint SourceChecksum; /**< for debug/logging purposes */
struct gl_program *Program; /**< Post-compile assembly code */
@@ -2615,6 +2616,7 @@ struct gl_shader_program
GLuint NumShaders; /**< number of attached shaders */
struct gl_shader **Shaders; /**< List of attached the shaders */
+ unsigned *ShaderEpochs; /**< List of CompileEpochs for attached shaders. */
/**
* User-defined attribute bindings
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 59d30ff..3a4a2a9 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -827,6 +827,8 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
if (!sh)
return;
+ ++sh->CompileEpoch;
+
options = &ctx->ShaderCompilerOptions[sh->Stage];
/* set default pragma state for shader */
@@ -887,6 +889,32 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
}
}
+/**
+ * Updates shProg->NeedsRelink if any of the attached shaders have been
+ * recompiled since the last LinkProgram call.
+ *
+ * This will break if the shaders are recompiled exactly 2^32 times between
+ * LinkProgram calls, but only an extremely targeted test would hit that.
+ */
+void
+_mesa_check_for_recompiled_shaders(struct gl_shader_program *shProg)
+{
+ unsigned i;
+
+ /* If the program isn't linked, we have no existing LinkedShaders to
+ * compare to. If it's already marked as needing a relink, there's
+ * no need to bother checking.
+ */
+ if (!shProg->LinkStatus || shProg->NeedsRelink)
+ return;
+
+ for (i = 0; i < shProg->NumShaders; i++) {
+ if (shProg->Shaders[i]->CompileEpoch != shProg->ShaderEpochs[i]) {
+ shProg->NeedsRelink = true;
+ return;
+ }
+ }
+}
/**
* Link a program's shaders.
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index 17b05b3..4a7be5c 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -60,6 +60,9 @@ _mesa_count_active_attribs(struct gl_shader_program *shProg);
extern size_t
_mesa_longest_attribute_name_length(struct gl_shader_program *shProg);
+extern void
+_mesa_check_for_recompiled_shaders(struct gl_shader_program *shProg);
+
extern void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB, GLhandleARB);
--
1.9.2
More information about the mesa-dev
mailing list