<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 1 February 2014 01:24, Pohjolainen, Topi <span dir="ltr"><<a href="mailto:topi.pohjolainen@intel.com" target="_blank">topi.pohjolainen@intel.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Fri, Jan 31, 2014 at 01:12:09PM -0800, Paul Berry wrote:<br>
> ---<br>
>  .../glsl-fs-continue-inside-do-while.shader_test   | 51 +++++++++++++++++++++<br>
>  .../glsl-vs-continue-inside-do-while.shader_test   | 52 ++++++++++++++++++++++<br>
>  2 files changed, 103 insertions(+)<br>
>  create mode 100644 tests/shaders/glsl-fs-continue-inside-do-while.shader_test<br>
>  create mode 100644 tests/shaders/glsl-vs-continue-inside-do-while.shader_test<br>
><br>
> diff --git a/tests/shaders/glsl-fs-continue-inside-do-while.shader_test b/tests/shaders/glsl-fs-continue-inside-do-while.shader_test<br>
> new file mode 100644<br>
> index 0000000..9f5e491<br>
> --- /dev/null<br>
> +++ b/tests/shaders/glsl-fs-continue-inside-do-while.shader_test<br>
> @@ -0,0 +1,51 @@<br>
> +# From the GLSL 4.40 spec, section 6.4 (Jumps):<br>
> +#<br>
> +#     The continue jump is used only in loops. It skips the remainder<br>
> +#     of the body of the inner most loop of which it is inside. For<br>
> +#     while and do-while loops, this jump is to the next evaluation of<br>
> +#     the loop condition-expression from which the loop continues as<br>
> +#     previously defined.<br>
> +#<br>
> +# As of 1/31/2014 (commit db8b6fb), Mesa handles "continue" inside a<br>
> +# do-while loop incorrectly; instead of jumping to the loop<br>
> +# condition-expression, it jumps to the top of the loop.  This is<br>
> +# particularly problematic because it can lead to infinite loops.<br>
> +#<br>
> +# This test verifies correct behaviour of "continue" inside do-while<br>
> +# loops without risking an infinite loop.<br>
> +<br>
> +[require]<br>
> +GLSL >= 1.10<br>
> +<br>
> +[vertex shader]<br>
> +void main()<br>
> +{<br>
> +  gl_Position = gl_Vertex;<br>
> +}<br>
> +<br>
> +[fragment shader]<br>
> +void main()<br>
> +{<br>
> +  int x = 0;<br>
> +  int y = 0;<br>
> +  do {             // 1st iteration  2nd iteration  3rd iteration<br>
> +    ++x;           // x <- 1         x <- 2         x <- 3<br>
> +    if (x >= 4)    // false          false          false<br>
> +      break;<br>
<br>
</div></div>This guarding is for the infinite looping case of the broken mesa to terminate<br>
after finite amount of iterations, right? Without this extra check the following<br>
continue would always jump to the top of the loop (as you explained) causing the<br>
final guarding "while (x < 3)" to be infinitely skipped.<br>
If this is the case, would it make sense to add a small comment for the future<br>
when the problem in mesa not present anymore and somebody might wonder why the<br>
extra guarding is needed?<br></blockquote><div><br></div><div>I already have a comment hinting at this ("This test verifies correct behaviour of 'continue' inside do-while loops without risking an infinite loop").  I'll expand the comment so that it's clearer.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Still need to add that this is one the best documented tests that I've seen.<br>
Thanks Paul, makes really nice reading!<br></blockquote><div><br></div><div>Thanks!  Can I consider that a "Reviewed-by"?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><div class="h5"><br>
> +    if (x >= 2)    // false          true           true<br>
> +      continue;<br>
> +    ++y;           // y=1            skipped        skipped<br>
> +  } while (x < 3); // true           true           false<br>
> +<br>
> +  // The "continue" should skip ++y on all iterations but the first,<br>
> +  // so y should now be 1.  The "continue" should not skip (x < 3)<br>
> +  // ever, so the loop should terminate when x == 3 (not 4).<br>
> +  if (x == 3 && y == 1)<br>
> +    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);<br>
> +  else<br>
> +    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);<br>
> +}<br>
> +<br>
> +[test]<br>
> +draw rect -1 -1 2 2<br>
> +probe all rgba 0.0 1.0 0.0 1.0<br>
> diff --git a/tests/shaders/glsl-vs-continue-inside-do-while.shader_test b/tests/shaders/glsl-vs-continue-inside-do-while.shader_test<br>
> new file mode 100644<br>
> index 0000000..aa6d3e6<br>
> --- /dev/null<br>
> +++ b/tests/shaders/glsl-vs-continue-inside-do-while.shader_test<br>
> @@ -0,0 +1,52 @@<br>
> +# From the GLSL 4.40 spec, section 6.4 (Jumps):<br>
> +#<br>
> +#     The continue jump is used only in loops. It skips the remainder<br>
> +#     of the body of the inner most loop of which it is inside. For<br>
> +#     while and do-while loops, this jump is to the next evaluation of<br>
> +#     the loop condition-expression from which the loop continues as<br>
> +#     previously defined.<br>
> +#<br>
> +# As of 1/31/2014 (commit db8b6fb), Mesa handles "continue" inside a<br>
> +# do-while loop incorrectly; instead of jumping to the loop<br>
> +# condition-expression, it jumps to the top of the loop.  This is<br>
> +# particularly problematic because it can lead to infinite loops.<br>
> +#<br>
> +# This test verifies correct behaviour of "continue" inside do-while<br>
> +# loops without risking an infinite loop.<br>
> +<br>
> +[require]<br>
> +GLSL >= 1.10<br>
> +<br>
> +[vertex shader]<br>
> +void main()<br>
> +{<br>
> +  gl_Position = gl_Vertex;<br>
> +  int x = 0;<br>
> +  int y = 0;<br>
> +  do {             // 1st iteration  2nd iteration  3rd iteration<br>
> +    ++x;           // x <- 1         x <- 2         x <- 3<br>
> +    if (x >= 4)    // false          false          false<br>
> +      break;<br>
> +    if (x >= 2)    // false          true           true<br>
> +      continue;<br>
> +    ++y;           // y=1            skipped        skipped<br>
> +  } while (x < 3); // true           true           false<br>
> +<br>
> +  // The "continue" should skip ++y on all iterations but the first,<br>
> +  // so y should now be 1.  The "continue" should not skip (x < 3)<br>
> +  // ever, so the loop should terminate when x == 3 (not 4).<br>
> +  if (x == 3 && y == 1)<br>
> +    gl_FrontColor = vec4(0.0, 1.0, 0.0, 1.0);<br>
> +  else<br>
> +    gl_FrontColor = vec4(1.0, 0.0, 0.0, 1.0);<br>
> +}<br>
> +<br>
> +[fragment shader]<br>
> +void main()<br>
> +{<br>
> +  gl_FragColor = gl_Color;<br>
> +}<br>
> +<br>
> +[test]<br>
> +draw rect -1 -1 2 2<br>
> +probe all rgba 0.0 1.0 0.0 1.0<br>
> --<br>
> 1.8.5.3<br>
><br>
</div></div>> _______________________________________________<br>
> Piglit mailing list<br>
> <a href="mailto:Piglit@lists.freedesktop.org">Piglit@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/piglit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/piglit</a><br>
</blockquote></div><br></div></div>