[Piglit] [PATCH 2/2] Test that "continue" works in a switch statement within a do-while loop.

Paul Berry stereotype441 at gmail.com
Fri Jan 31 13:12:10 PST 2014


---
 ...l-fs-continue-in-switch-in-do-while.shader_test | 94 +++++++++++++++++++++
 ...l-vs-continue-in-switch-in-do-while.shader_test | 95 ++++++++++++++++++++++
 2 files changed, 189 insertions(+)
 create mode 100644 tests/shaders/glsl-fs-continue-in-switch-in-do-while.shader_test
 create mode 100644 tests/shaders/glsl-vs-continue-in-switch-in-do-while.shader_test

diff --git a/tests/shaders/glsl-fs-continue-in-switch-in-do-while.shader_test b/tests/shaders/glsl-fs-continue-in-switch-in-do-while.shader_test
new file mode 100644
index 0000000..58dc50d
--- /dev/null
+++ b/tests/shaders/glsl-fs-continue-in-switch-in-do-while.shader_test
@@ -0,0 +1,94 @@
+# From the GLSL 4.40 spec, section 6.4 (Jumps):
+#
+#     The continue jump is used only in loops. It skips the remainder
+#     of the body of the inner most loop of which it is inside. For
+#     while and do-while loops, this jump is to the next evaluation of
+#     the loop condition-expression from which the loop continues as
+#     previously defined.
+#
+# One way that do-while loops might be implemented is to convert them
+# to infinite loops that terminate in a conditional break (this is
+# what Mesa does).  In such an implementation, an easy way to
+# implement the proper behaviour of "continue" in a do-while loop is
+# to replicate the conditional break at the site of the "continue".
+# For example, this code:
+#
+#     do {
+#       ...
+#       if (...) {
+#         ...
+#         continue;
+#       }
+#       ...
+#     } while (condition);
+#
+# would get translated to:
+#
+#     loop {
+#       ...
+#       if (...) {
+#         ...
+#         if (!condition)
+#           break;
+#         continue;
+#       }
+#       ...
+#       if (!condition)
+#         break;
+#     }
+#
+# However, we must be careful in making this transformation if the
+# "continue" occurs inside a switch statement, since "break" inside a
+# switch statement normally exits the switch statement, not the
+# surrounding loop.
+#
+# This test verifies that "continue" behaves properly when invoked
+# inside a switch statement which is itself inside a do-while loop.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+void main()
+{
+  gl_Position = gl_Vertex;
+}
+
+[fragment shader]
+#version 130
+void main()
+{
+  int w = 0;
+  int x = 0;
+  int y = 0;
+  int z = 0;
+  do {             // 1st iteration   2nd iteration
+    ++w;           // w <- 1          w <- 2
+    switch (w) {   // Jump to case 1  Jump to case 2
+      case 1:
+        ++x;       // x <- 1
+        break;     // Jump to ++z
+      case 2:
+        continue;  //                 Jump to (w < 2)
+      case 3:
+        ++y;       // (this case is never executed)
+        break;
+    }
+    ++z;           // z <- 1          skipped
+  } while (w < 2); // true            false
+
+  // The loop should execute for two iterations, so w should be 2.  X
+  // should be incremented on the first iteration only, so it should
+  // be 1.  Y should never be incremented (since w never reaches 3),
+  // so it should be 0.  The "continue" should skip ++z on the second
+  // iteration, so z should be 1.
+  if (w == 2 && x == 1 && y == 0 && z == 1)
+    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+  else
+    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/shaders/glsl-vs-continue-in-switch-in-do-while.shader_test b/tests/shaders/glsl-vs-continue-in-switch-in-do-while.shader_test
new file mode 100644
index 0000000..88fcfb9
--- /dev/null
+++ b/tests/shaders/glsl-vs-continue-in-switch-in-do-while.shader_test
@@ -0,0 +1,95 @@
+# From the GLSL 4.40 spec, section 6.4 (Jumps):
+#
+#     The continue jump is used only in loops. It skips the remainder
+#     of the body of the inner most loop of which it is inside. For
+#     while and do-while loops, this jump is to the next evaluation of
+#     the loop condition-expression from which the loop continues as
+#     previously defined.
+#
+# One way that do-while loops might be implemented is to convert them
+# to infinite loops that terminate in a conditional break (this is
+# what Mesa does).  In such an implementation, an easy way to
+# implement the proper behaviour of "continue" in a do-while loop is
+# to replicate the conditional break at the site of the "continue".
+# For example, this code:
+#
+#     do {
+#       ...
+#       if (...) {
+#         ...
+#         continue;
+#       }
+#       ...
+#     } while (condition);
+#
+# would get translated to:
+#
+#     loop {
+#       ...
+#       if (...) {
+#         ...
+#         if (!condition)
+#           break;
+#         continue;
+#       }
+#       ...
+#       if (!condition)
+#         break;
+#     }
+#
+# However, we must be careful in making this transformation if the
+# "continue" occurs inside a switch statement, since "break" inside a
+# switch statement normally exits the switch statement, not the
+# surrounding loop.
+#
+# This test verifies that "continue" behaves properly when invoked
+# inside a switch statement which is itself inside a do-while loop.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+void main()
+{
+  gl_Position = gl_Vertex;
+  int w = 0;
+  int x = 0;
+  int y = 0;
+  int z = 0;
+  do {             // 1st iteration   2nd iteration
+    ++w;           // w <- 1          w <- 2
+    switch (w) {   // Jump to case 1  Jump to case 2
+      case 1:
+        ++x;       // x <- 1
+        break;     // Jump to ++z
+      case 2:
+        continue;  //                 Jump to (w < 2)
+      case 3:
+        ++y;       // (this case is never executed)
+        break;
+    }
+    ++z;           // z <- 1          skipped
+  } while (w < 2); // true            false
+
+  // The loop should execute for two iterations, so w should be 2.  X
+  // should be incremented on the first iteration only, so it should
+  // be 1.  Y should never be incremented (since w never reaches 3),
+  // so it should be 0.  The "continue" should skip ++z on the second
+  // iteration, so z should be 1.
+  if (w == 2 && x == 1 && y == 0 && z == 1)
+    gl_FrontColor = vec4(0.0, 1.0, 0.0, 1.0);
+  else
+    gl_FrontColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[fragment shader]
+#version 130
+void main()
+{
+  gl_FragColor = gl_Color;
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
-- 
1.8.5.3



More information about the Piglit mailing list