summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2010-07-16 15:51:50 -0700
committerIan Romanick <[email protected]>2010-07-19 14:50:43 -0700
commit25f51d3b9b8c36c41cd23d2797b6a06f6e27ff86 (patch)
treeb2af2b9e217ba74b212d28a8edc94c9979990a08
parentb64e979971e764ec1df8800d31c755298e618ba0 (diff)
linker: Track and validate GLSL versions used in shaders
-rw-r--r--src/glsl/linker.cpp21
-rw-r--r--src/glsl/main.cpp1
-rw-r--r--src/mesa/main/mtypes.h4
-rw-r--r--src/mesa/shader/ir_to_mesa.cpp1
4 files changed, 27 insertions, 0 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 06aa24e66f5..4933686b5e9 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -66,12 +66,14 @@
#include <cstdlib>
#include <cstdio>
#include <cstdarg>
+#include <climits>
extern "C" {
#include <talloc.h>
}
#include "main/mtypes.h"
+#include "main/macros.h"
#include "glsl_symbol_table.h"
#include "ir.h"
#include "program.h"
@@ -1107,7 +1109,12 @@ link_shaders(struct gl_shader_program *prog)
calloc(2 * prog->NumShaders, sizeof(struct gl_shader *));
frag_shader_list = &vert_shader_list[prog->NumShaders];
+ unsigned min_version = UINT_MAX;
+ unsigned max_version = 0;
for (unsigned i = 0; i < prog->NumShaders; i++) {
+ min_version = MIN2(min_version, prog->Shaders[i]->Version);
+ max_version = MAX2(max_version, prog->Shaders[i]->Version);
+
switch (prog->Shaders[i]->Type) {
case GL_VERTEX_SHADER:
vert_shader_list[num_vert_shaders] = prog->Shaders[i];
@@ -1124,6 +1131,20 @@ link_shaders(struct gl_shader_program *prog)
}
}
+ /* Previous to GLSL version 1.30, different compilation units could mix and
+ * match shading language versions. With GLSL 1.30 and later, the versions
+ * of all shaders must match.
+ */
+ assert(min_version >= 110);
+ assert(max_version <= 130);
+ if ((max_version >= 130) && (min_version != max_version)) {
+ linker_error_printf(prog, "all shaders must use same shading "
+ "language version\n");
+ goto done;
+ }
+
+ prog->Version = max_version;
+
/* FINISHME: Implement intra-stage linking. */
prog->_NumLinkedShaders = 0;
if (num_vert_shaders > 0) {
diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp
index 8b0bccdcb71..e27d9c1d855 100644
--- a/src/glsl/main.cpp
+++ b/src/glsl/main.cpp
@@ -207,6 +207,7 @@ compile_shader(struct gl_shader *shader)
shader->symbols = state->symbols;
shader->CompileStatus = !state->error;
+ shader->Version = state->language_version;
if (shader->InfoLog)
talloc_free(shader->InfoLog);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index be9eaaa875c..729c2eaf0fd 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1967,6 +1967,8 @@ struct gl_shader
GLchar *InfoLog;
struct gl_sl_pragmas Pragmas;
+ unsigned Version; /**< GLSL version used for linking */
+
struct exec_list *ir;
struct glsl_symbol_table *symbols;
};
@@ -2006,6 +2008,8 @@ struct gl_shader_program
GLboolean _Used; /**< Ever used for drawing? */
GLchar *InfoLog;
+ unsigned Version; /**< GLSL version used for linking */
+
/**
* Per-stage shaders resulting from the first stage of linking.
*/
diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp
index 58320c92174..557f5d319d2 100644
--- a/src/mesa/shader/ir_to_mesa.cpp
+++ b/src/mesa/shader/ir_to_mesa.cpp
@@ -2234,6 +2234,7 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
shader->CompileStatus = !state->error;
shader->InfoLog = state->info_log;
+ shader->Version = state->language_version;
/* Retain any live IR, but trash the rest. */
foreach_list(node, shader->ir) {