glsl: don't attempt to link empty program
authorTimothy Arceri <timothy.arceri@collabora.com>
Mon, 25 Jan 2016 10:56:18 +0000 (21:56 +1100)
committerTimothy Arceri <timothy.arceri@collabora.com>
Tue, 9 Feb 2016 11:44:02 +0000 (22:44 +1100)
Previously an empty program would go through the entire
link_shaders() function and we would have to be careful
not to cause a segfault.

In core profile also now set link_status to false by
generating an error, it was previously set to true.

From Section 7.3 (PROGRAM OBJECTS) of the OpenGL 4.5 spec:

   "Linking can fail for a variety of reasons as specified in the
   OpenGL Shading Language Specification, as well as any of the
   following reasons:

    - No shader objects are attached to program."

V2: Only generate an error in core profile and add spec quote (Ian)

V3: generate error in ES too, remove previous check which was only
applying the rule to GL 4.5/ES 3.1 and above. My understand is that
this spec change is clarifying previously undefined behaviour and
therefore should be applied retrospectively. The ES CTS tests for
this are in ES 2 I suspect it was passing because it would have
generated an error for not having both a vertex and fragment shader.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/compiler/glsl/linker.cpp

index f1ac53abb0a354f46bdd07c20eb54ace56f4f235..31efb57b035e2a293a6942cb860566ec96bbd9d7 100644 (file)
@@ -4106,15 +4106,34 @@ disable_varying_optimizations_for_sso(struct gl_shader_program *prog)
 void
 link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 {
+   prog->LinkStatus = true; /* All error paths will set this to false */
+   prog->Validated = false;
+   prog->_Used = false;
+
+   /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec says:
+    *
+    *     "Linking can fail for a variety of reasons as specified in the
+    *     OpenGL Shading Language Specification, as well as any of the
+    *     following reasons:
+    *
+    *     - No shader objects are attached to program."
+    *
+    * The Compatibility Profile specification does not list the error.  In
+    * Compatibility Profile missing shader stages are replaced by
+    * fixed-function.  This applies to the case where all stages are
+    * missing.
+    */
+   if (prog->NumShaders == 0) {
+      if (ctx->API != API_OPENGL_COMPAT)
+         linker_error(prog, "no shaders attached to the program\n");
+      return;
+   }
+
    tfeedback_decl *tfeedback_decls = NULL;
    unsigned num_tfeedback_decls = prog->TransformFeedback.NumVarying;
 
    void *mem_ctx = ralloc_context(NULL); // temporary linker context
 
-   prog->LinkStatus = true; /* All error paths will set this to false */
-   prog->Validated = false;
-   prog->_Used = false;
-
    prog->ARB_fragment_coord_conventions_enable = false;
 
    /* Separate the shaders into groups based on their type.
@@ -4163,25 +4182,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
    prog->Version = max_version;
    prog->IsES = is_es_prog;
 
-   /* From OpenGL 4.5 Core specification (7.3 Program Objects):
-    *     "Linking can fail for a variety of reasons as specified in the OpenGL
-    *     Shading Language Specification, as well as any of the following
-    *     reasons:
-    *
-    *     * No shader objects are attached to program.
-    *
-    *     ..."
-    *
-    *     Same rule applies for OpenGL ES >= 3.1.
-    */
-
-   if (prog->NumShaders == 0 &&
-       ((ctx->API == API_OPENGL_CORE && ctx->Version >= 45) ||
-        (ctx->API == API_OPENGLES2 && ctx->Version >= 31))) {
-      linker_error(prog, "No shader objects are attached to program.\n");
-      goto done;
-   }
-
    /* Some shaders have to be linked with some other shaders present.
     */
    if (num_shaders[MESA_SHADER_GEOMETRY] > 0 &&