linker: Track and validate GLSL versions used in shaders
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 16 Jul 2010 22:51:50 +0000 (15:51 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 19 Jul 2010 21:50:43 +0000 (14:50 -0700)
src/glsl/linker.cpp
src/glsl/main.cpp
src/mesa/main/mtypes.h
src/mesa/shader/ir_to_mesa.cpp

index 06aa24e66f5b742aaf08226ea2022faf2fb30bf2..4933686b5e9bac8d847c46023067eb192c79ce73 100644 (file)
 #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) {
index 8b0bccdcb717739d818b0204b6bbb82119bbcde4..e27d9c1d85515501985cb15ac064239ef73c37b7 100644 (file)
@@ -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);
index be9eaaa875c2bdc6d6463c690f6f8c4f41925f6a..729c2eaf0fdd0fa47ed273f4ad5a82678171e849 100644 (file)
@@ -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.
     */
index 58320c921744aff21ea4d2c06cc6fe89c73696aa..557f5d319d2068f0b3e5f79fbc0c88a53cf633a8 100644 (file)
@@ -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) {