﻿<!--

/*
** Copyright (c) 2014 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/

-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL GLSL Conformance Tests</title>
<link rel="stylesheet" href="../../../resources/js-test-style.css" />
<link rel="stylesheet" href="../../../resources/glsl-feature-tests.css" />
<script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script id="vertexShaderLiteralLoopCondition" type="text/something-not-javascript">
attribute vec4 a_position;
void main()
{
    for (int i = 0; i < 5 + 5; i++) { }
    gl_Position = a_position;
}
</script>
<script id="fragmentShaderLiteralLoopCondition" type="text/something-not-javascript">
void main()
{
    for (int i = 0; i < 5 + 5; i++) { }
    gl_FragColor = vec4(1.0);
}
</script>
<script id="vertexShaderConstVarLoopCondition" type="text/something-not-javascript">
attribute vec4 a_position;
void main()
{
    // Explicitly constant variables can be part of a constant expression
    const int constVar = 5;
    for (int i = 0; i < 5 + constVar; i++) { }
    gl_Position = a_position;
}
</script>
<script id="fragmentShaderConstVarLoopCondition" type="text/something-not-javascript">
void main()
{
    // Explicitly constant variables can be part of a constant expression
    const int constVar = 5;
    for (int i = 0; i < constVar + 5; i++) { }
    gl_FragColor = vec4(1.0);
}
</script>
<script id="vertexShaderNonConstVarLoopCondition" type="text/something-not-javascript">
attribute vec4 a_position;
void main()
{
    // Despite assigning a constant and not modifying it, nonConstVar is not semantically a constant expression
    int nonConstVar = 10;
    for (int i = 0; i < nonConstVar; i++) { }
    gl_Position = a_position;
}
</script>
<script id="fragmentShaderNonConstVarLoopCondition" type="text/something-not-javascript">
void main()
{
    // Despite assigning a constant and not modifying it, nonConstVar is not semantically a constant expression
    int nonConstVar = 10;
    for (int i = 0; i < nonConstVar; i++) { }
    gl_FragColor = vec4(1.0);
}
</script>
<script>
"use strict";
var wtu = WebGLTestUtils;

var tests = [];
tests.push({
    vShaderSource: wtu.getScript("vertexShaderLiteralLoopCondition"),
    vShaderSuccess: true,
    fShaderSource: wtu.getScript("fragmentShaderLiteralLoopCondition"),
    fShaderSuccess: true,
    linkSuccess: true,
    passMsg: "Shaders with literals in the loop condition should compile and link.",
});
tests.push({
    vShaderSource: wtu.getScript("vertexShaderConstVarLoopCondition"),
    vShaderSuccess: true,
    fShaderSource: wtu.getScript("fragmentShaderConstVarLoopCondition"),
    fShaderSuccess: true,
    linkSuccess: true,
    passMsg: "Shaders with constant variables in the loop condition should compile and link.",
});
tests.push({
    vShaderSource: wtu.getScript("vertexShaderNonConstVarLoopCondition"),
    vShaderSuccess: false,
    fShaderSource: wtu.getScript("fragmentShaderLiteralLoopCondition"),
    fShaderSuccess: true,
    linkSuccess: false,
    passMsg: "Vertex shader with non-const variable in the loop condition should fail.",
});
tests.push({
    vShaderSource: wtu.getScript("vertexShaderLiteralLoopCondition"),
    vShaderSuccess: true,
    fShaderSource: wtu.getScript("fragmentShaderNonConstVarLoopCondition"),
    fShaderSuccess: false,
    linkSuccess: false,
    passMsg: "Fragment shader with non-const variable in the loop condition should fail.",
});

GLSLConformanceTester.runTests(tests);
var successfullyParsed = true;
</script>
</body>
</html>
