summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-08-11 06:12:53 -0700
committerKenneth Graunke <[email protected]>2016-08-11 23:56:53 -0700
commitf9f462936ad903f93829404ce99a2580ea21b725 (patch)
tree3186297d349b283c78333d92f448c18b10adc54a
parent0ed316360f6879d6e5179330d30e075e29f029e1 (diff)
glsl: Fix invariant matching in GLSL 4.30 and GLSL ES 1.00.
Old languages (GLSL <= 4.20 and GLSL ES 1.00) require "invariant" to be specified on both inputs and outputs, and match when linking. New languages only allow outputs to be qualified as "invariant" and remove the "invariant must match" restriction when linking varyings (because no input can have that qualifier). Commit 426a50e2089b12d33f5c075aa5622f64076914a3 introduced the new behavior for ES 3.00. It also removed the "must match" restriction for ES 1.00 shaders, which I believe is incorrect. This patch adds that back, as well as making 4.30+ follow the new rules. Thanks to Qiankun Miao for noticing this discrepancy. Fixes a WebGL 2.0 conformance test when run in Chromium: https://www.khronos.org/registry/webgl/sdk/tests/deqp/data/gles3/shaders/qualification_order.html?webglVersion=2 Cc: [email protected] Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96971 Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
-rw-r--r--src/compiler/glsl/glsl_parser.yy4
-rw-r--r--src/compiler/glsl/link_varyings.cpp20
2 files changed, 22 insertions, 2 deletions
diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy
index 4ab9e145001..4f4a83cd8d0 100644
--- a/src/compiler/glsl/glsl_parser.yy
+++ b/src/compiler/glsl/glsl_parser.yy
@@ -1774,8 +1774,10 @@ type_qualifier:
* variables. As only outputs can be declared as invariant, an invariant
* output from one shader stage will still match an input of a subsequent
* stage without the input being declared as invariant."
+ *
+ * On the desktop side, this text first appears in GLSL 4.30.
*/
- if (state->es_shader && state->language_version >= 300 && $$.flags.q.in)
+ if (state->is_version(430, 300) && $$.flags.q.in)
_mesa_glsl_error(&@1, state, "invariant qualifiers cannot be used with shader inputs");
}
| interpolation_qualifier type_qualifier
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index b4799d297dc..1bce3e00207 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -308,7 +308,25 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
return;
}
- if (!prog->IsES && input->data.invariant != output->data.invariant) {
+ /* The GLSL 4.30 and GLSL ES 3.00 specifications say:
+ *
+ * "As only outputs need be declared with invariant, an output from
+ * one shader stage will still match an input of a subsequent stage
+ * without the input being declared as invariant."
+ *
+ * while GLSL 4.20 says:
+ *
+ * "For variables leaving one shader and coming into another shader,
+ * the invariant keyword has to be used in both shaders, or a link
+ * error will result."
+ *
+ * and GLSL ES 1.00 section 4.6.4 "Invariance and Linking" says:
+ *
+ * "The invariance of varyings that are declared in both the vertex
+ * and fragment shaders must match."
+ */
+ if (input->data.invariant != output->data.invariant &&
+ prog->Version < (prog->IsES ? 300 : 430)) {
linker_error(prog,
"%s shader output `%s' %s invariant qualifier, "
"but %s shader input %s invariant qualifier\n",