On Fri, Jan 31, 2014 at 1:12 PM, Paul Berry <stereotype...@gmail.com> wrote: > --- > ...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 >
Nice tests. I'm really happy to see that they fail without causing GPU hangs on unpatched Mesa. Both are Reviewed-by: Matt Turner <matts...@gmail.com> _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit