GLES2: sequence operator (,) eval order and side effects
Ported from:
https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance/glsl/bugs/sequence-operator-evaluation-order.html
Which was added in:
https://github.com/KhronosGroup/WebGL/pull/981
https://github.com/KhronosGroup/WebGL/pull/1932
These tests were known to fail in on Pixel 2016 / Android 7.1.1.
New tests:
dEQP-GLES2.functional.shaders.operator.sequence.side_effects.affect_ternary
dEQP-GLES2.functional.shaders.operator.sequence.side_effects.affect_and
dEQP-GLES2.functional.shaders.operator.sequence.side_effects.affect_or
Components: AOSP
Change-Id: I7bbcaecc08279df6f30b6855cc99b19b402892c7
diff --git a/android/cts/master/gles2-master.txt b/android/cts/master/gles2-master.txt
index 483dfdd..6264211 100644
--- a/android/cts/master/gles2-master.txt
+++ b/android/cts/master/gles2-master.txt
@@ -5777,6 +5777,9 @@
dEQP-GLES2.functional.shaders.operator.sequence.side_effects.lowp_vec4_ivec4_bvec4_fragment
dEQP-GLES2.functional.shaders.operator.sequence.side_effects.mediump_vec4_ivec4_bvec4_fragment
dEQP-GLES2.functional.shaders.operator.sequence.side_effects.highp_vec4_ivec4_bvec4_fragment
+dEQP-GLES2.functional.shaders.operator.sequence.side_effects.affect_ternary
+dEQP-GLES2.functional.shaders.operator.sequence.side_effects.affect_and
+dEQP-GLES2.functional.shaders.operator.sequence.side_effects.affect_or
dEQP-GLES2.functional.shaders.matrix.add.const_lowp_mat2_float_vertex
dEQP-GLES2.functional.shaders.matrix.add.const_lowp_mat2_float_fragment
dEQP-GLES2.functional.shaders.matrix.add.const_lowp_mat2_mat2_vertex
diff --git a/modules/gles2/functional/es2fShaderOperatorTests.cpp b/modules/gles2/functional/es2fShaderOperatorTests.cpp
index efe933c..46ef98d 100644
--- a/modules/gles2/functional/es2fShaderOperatorTests.cpp
+++ b/modules/gles2/functional/es2fShaderOperatorTests.cpp
@@ -1523,6 +1523,90 @@
}
}
}
+
+ // Regression tests for sequence operator.
+ // http://khronos.org/registry/webgl/sdk/tests/conformance/glsl/bugs/sequence-operator-evaluation-order.html
+ {
+ class Case : public ShaderRenderCase
+ {
+ static void evalFunc(ShaderEvalContext& c) {
+ c.color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); // green
+ }
+
+ public:
+ Case(Context& context, const char* name, const char* description, const char* fragShaderSource)
+ : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, false, &evalFunc)
+ {
+ m_vertShaderSource =
+ "attribute vec4 a_position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = a_position;\n"
+ "}\n";
+ m_fragShaderSource = fragShaderSource;
+ }
+ };
+
+ // ESSL 1.00 section 5.9, about sequence operator:
+ // "All expressions are evaluated, in order, from left to right"
+ // Also use a ternary operator where the third operand has side effects to make sure
+ // only the second operand is evaluated.
+ sequenceSideEffGroup->addChild(new Case(m_context, "affect_ternary",
+ "Expression where first operand of a sequence operator has side effects which affect the second operand that is a ternary operator", (
+ "precision mediump float;\n"
+ "bool correct = true;\n"
+ "uniform float u_zero;\n"
+ "float wrong() {\n"
+ " correct = false;\n"
+ " return 0.0;\n"
+ "}\n"
+ "void main() {\n"
+ " float a = u_zero - 0.5; // Result should be -0.5.\n"
+ " float green = (a++, a > 0.0 ? 1.0 : wrong());\n"
+ " gl_FragColor = vec4(0.0, correct ? green : 0.0, 0.0, 1.0);\n"
+ "}\n"
+ )));
+
+ sequenceSideEffGroup->addChild(new Case(m_context, "affect_and",
+ "Expression where first operand of a sequence operator has side effects which affect the second operand that is an and operator", (
+ "precision mediump float;\n"
+ "uniform bool u_false;\n"
+ "bool sideEffectA = false;\n"
+ "bool funcA() {\n"
+ " sideEffectA = true;\n"
+ " return true;\n"
+ "}\n"
+ "bool sideEffectB = false;\n"
+ "bool funcB() {\n"
+ " sideEffectB = true;\n"
+ " return true;\n"
+ "}\n"
+ "void main() {\n"
+ " bool b = (funcA(), u_false == sideEffectA && funcB());\n"
+ " gl_FragColor = (!b && sideEffectA && !sideEffectB) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
+ "}\n"
+ )));
+
+ sequenceSideEffGroup->addChild(new Case(m_context, "affect_or",
+ "Expression where first operand of a sequence operator has side effects which affect the second operand that is an or operator", (
+ "precision mediump float;\n"
+ "uniform bool u_false;\n"
+ "bool sideEffectA = false;\n"
+ "bool funcA() {\n"
+ " sideEffectA = true;\n"
+ " return false;\n"
+ "}\n"
+ "bool sideEffectB = false;\n"
+ "bool funcB() {\n"
+ " sideEffectB = true;\n"
+ " return false;\n"
+ "}\n"
+ "void main() {\n"
+ " bool b = (funcA(), (u_false == !sideEffectA) || funcB());\n"
+ " gl_FragColor = (b && sideEffectA && !sideEffectB) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
+ "}\n"
+ )));
+ }
}
} // Functional