GLES3: complex exprs, side effects, short circuits
authorKai Ninomiya <kainino@chromium.org>
Sat, 27 Jan 2018 03:25:26 +0000 (19:25 -0800)
committerKai Ninomiya <kainino@chromium.org>
Tue, 30 Jan 2018 21:30:10 +0000 (21:30 +0000)
Some of these 8 tests (the 4 that rely on short circuiting) fail on
Nexus6P/7.0 (they were fixed in 8.0 and pass on Pixel2016/8.1):
  https://crbug.com/695685
This is a port from WebGL:
  https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance2/glsl3/array-in-complex-expression.html
  https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance2/glsl3/short-circuiting-in-loop-condition.html
All of those tests are ported just for completeness.

New tests:
  dEQP-GLES3.functional.shaders.arrays.complex_expression.and_short_circuits_vertex
  dEQP-GLES3.functional.shaders.arrays.complex_expression.and_short_circuits_fragment
  dEQP-GLES3.functional.shaders.arrays.complex_expression.or_short_circuits_vertex
  dEQP-GLES3.functional.shaders.arrays.complex_expression.or_short_circuits_fragment
  dEQP-GLES3.functional.shaders.arrays.complex_expression.ternary_only_evaluates_one_operand_vertex
  dEQP-GLES3.functional.shaders.arrays.complex_expression.ternary_only_evaluates_one_operand_fragment
  dEQP-GLES3.functional.shaders.arrays.complex_expression.sequence_side_effects_affecting_compared_array_content_vertex
  dEQP-GLES3.functional.shaders.arrays.complex_expression.sequence_side_effects_affecting_compared_array_content_fragment
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_while_vertex
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_while_fragment
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_for_vertex
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_for_fragment
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_dowhile_vertex
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_dowhile_fragment
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_while_sequence_vertex
  dEQP-GLES3.functional.shaders.loops.custom.short_circuit_in_while_sequence_fragment
Components: AOSP

Change-Id: Ifa5590f91a8b16e1e2ab5ea8531f0d783c61cda4

android/cts/master/gles3-master.txt
data/gles3/shaders/arrays.test
data/gles3/shaders/loops.test

index ee1081c..c4c4dec 100644 (file)
@@ -4449,6 +4449,14 @@ dEQP-GLES3.functional.shaders.arrays.invalid.constructor_c_style3_vertex
 dEQP-GLES3.functional.shaders.arrays.invalid.constructor_c_style3_fragment
 dEQP-GLES3.functional.shaders.arrays.invalid.constructor_c_style4_vertex
 dEQP-GLES3.functional.shaders.arrays.invalid.constructor_c_style4_fragment
+dEQP-GLES3.functional.shaders.arrays.complex_expression.and_short_circuits_vertex
+dEQP-GLES3.functional.shaders.arrays.complex_expression.and_short_circuits_fragment
+dEQP-GLES3.functional.shaders.arrays.complex_expression.or_short_circuits_vertex
+dEQP-GLES3.functional.shaders.arrays.complex_expression.or_short_circuits_fragment
+dEQP-GLES3.functional.shaders.arrays.complex_expression.ternary_only_evaluates_one_operand_vertex
+dEQP-GLES3.functional.shaders.arrays.complex_expression.ternary_only_evaluates_one_operand_fragment
+dEQP-GLES3.functional.shaders.arrays.complex_expression.sequence_side_effects_affecting_compared_array_content_vertex
+dEQP-GLES3.functional.shaders.arrays.complex_expression.sequence_side_effects_affecting_compared_array_content_fragment
 dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_16_vertex
 dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_16_fragment
 dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_32_vertex
@@ -6371,6 +6379,14 @@ dEQP-GLES3.functional.shaders.loops.do_while_dynamic_iterations.nested_tricky_da
 dEQP-GLES3.functional.shaders.loops.do_while_dynamic_iterations.nested_tricky_dataflow_2_vertex
 dEQP-GLES3.functional.shaders.loops.do_while_dynamic_iterations.nested_tricky_dataflow_2_fragment
 dEQP-GLES3.functional.shaders.loops.custom.continue_in_fragment_for_loop
+dEQP-GLES3.functional.shaders.loops.short_circuit.while_vertex
+dEQP-GLES3.functional.shaders.loops.short_circuit.while_fragment
+dEQP-GLES3.functional.shaders.loops.short_circuit.for_vertex
+dEQP-GLES3.functional.shaders.loops.short_circuit.for_fragment
+dEQP-GLES3.functional.shaders.loops.short_circuit.do_while_vertex
+dEQP-GLES3.functional.shaders.loops.short_circuit.do_while_fragment
+dEQP-GLES3.functional.shaders.loops.short_circuit.while_sequence_vertex
+dEQP-GLES3.functional.shaders.loops.short_circuit.while_sequence_fragment
 dEQP-GLES3.functional.shaders.operator.unary_operator.plus.lowp_float_vertex
 dEQP-GLES3.functional.shaders.operator.unary_operator.plus.lowp_float_fragment
 dEQP-GLES3.functional.shaders.operator.unary_operator.plus.mediump_float_vertex
index 2144a11..4a9c5fe 100644 (file)
@@ -1996,3 +1996,134 @@ group invalid "Invalid Functions"
        end
 
 end # invalid
+
+# https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance2/glsl3/array-in-complex-expression.html
+group complex_expression "Arrays in complex expressions"
+
+       case and_short_circuits
+               version 300 es
+               values
+               {
+                       output int g = -1;
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       ${DECLARATIONS}
+
+                       int[2] plus() {
+                               ++g;
+                               return int[2](g, g);
+                       }
+
+                       bool minus() {
+                               --g;
+                               return false;
+                       }
+
+                       void main() {
+                               ${SETUP}
+                               g = 0;
+                               int a[2] = int[2](0, 0);
+                               // The plus() call must not be evaluated, since && short-circuits
+                               minus() && (a == plus());
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+       case or_short_circuits
+               version 300 es
+               values
+               {
+                       output int g = -1;
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       ${DECLARATIONS}
+
+                       int[2] plus() {
+                               ++g;
+                               return int[2](g, g);
+                       }
+
+                       bool minus() {
+                               --g;
+                               return false;
+                       }
+
+                       void main() {
+                               ${SETUP}
+                               g = 0;
+                               int a[2] = int[2](0, 0);
+                               // The function call must not be evaluated, since && short-circuits
+                               minus() && (a == plus());
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+       case ternary_only_evaluates_one_operand
+               version 300 es
+               values
+               {
+                       output int g = 0;
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       ${DECLARATIONS}
+
+                       int[2] plus() {
+                               ++g;
+                               return int[2](g, g);
+                       }
+
+                       void main() {
+                               ${SETUP}
+                               g = 0;
+                               int a[2] = int[2](0, 0);
+                               // The function call must not be evaluated, since the condition is true.
+                               (g == 0) ? true : (a == plus());
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+       case sequence_side_effects_affecting_compared_array_content
+               version 300 es
+               values
+               {
+                       output bool success = true;
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       ${DECLARATIONS}
+
+                       int[2] func(int param) {
+                               return int[2](param, param);
+                       }
+
+                       void main() {
+                               ${SETUP}
+                               int a[2];
+                               for (int i = 0; i < 2; ++i) {
+                                       a[i] = 1;
+                               }
+                               int j = 0;
+                               // Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
+                               // The function call that returns the array needs to be evaluated after ++j
+                               // for the expression to return the correct value (true).
+                               success = ((++j), (a == func(j)));
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+end # complex_expression
index a8f1e4d..619179b 100644 (file)
@@ -27,3 +27,151 @@ group custom "Custom loop tests"
        end
 
 end # custom
+
+# https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance2/glsl3/short-circuiting-in-loop-condition.html
+group short_circuit "Short-circuiting operator in a loop using a function call with side effects"
+
+       case while
+               version 300 es
+               values
+               {
+                       input bool in0 = [ false | true ];
+                       output int sideEffectCounter = [ 0 | 10 ];
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       precision mediump int;
+
+                       ${DECLARATIONS}
+
+                       bool foo() {
+                               ++sideEffectCounter;
+                               return true;
+                       }
+
+                       void main()
+                       {
+                               ${SETUP}
+                               sideEffectCounter = 0;
+                               int iterations = 0;
+                               while (in0 && foo()) {
+                                       ++iterations;
+                                       if (iterations >= 10) {
+                                               break;
+                                       }
+                               }
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+       case for
+               version 300 es
+               values
+               {
+                       input bool in0 = [ false | true ];
+                       output int sideEffectCounter = [ 0 | 10 ];
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       precision mediump int;
+
+                       ${DECLARATIONS}
+
+                       bool foo() {
+                               ++sideEffectCounter;
+                               return true;
+                       }
+
+                       void main()
+                       {
+                               ${SETUP}
+                               sideEffectCounter = 0;
+                               for (int iterations = 0; true; in0 && foo()) {
+                                       ++iterations;
+                                       if (iterations > 10) {
+                                               break;
+                                       }
+                               }
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+       case do_while
+               version 300 es
+               values
+               {
+                       input bool in0 = [ false | true ];
+                       output int sideEffectCounter = [ 0 | 10 ];
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       precision mediump int;
+
+                       ${DECLARATIONS}
+
+                       bool foo() {
+                               ++sideEffectCounter;
+                               return true;
+                       }
+
+                       void main()
+                       {
+                               ${SETUP}
+                               sideEffectCounter = 0;
+                               int iterations = 0;
+                               do {
+                                       ++iterations;
+                                       if (iterations > 10) {
+                                               break;
+                                       }
+                               } while (in0 && foo());
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+       case while_sequence
+               version 300 es
+               values
+               {
+                       input bool in0 = [ false | true ];
+                       output int sideEffectCounter = [ 0 | 10 ];
+               }
+
+               both ""
+                       #version 300 es
+                       precision mediump float;
+                       precision mediump int;
+
+                       ${DECLARATIONS}
+
+                       bool foo() {
+                               ++sideEffectCounter;
+                               return true;
+                       }
+
+                       void main()
+                       {
+                               ${SETUP}
+                               sideEffectCounter = 0;
+                               int iterations = 0;
+                               while ((in0, in0 && foo())) {
+                                       ++iterations;
+                                       if (iterations >= 10) {
+                                               break;
+                                       }
+                               }
+                               ${OUTPUT}
+                       }
+               ""
+       end
+
+end # short_circuit