blob: 16c06e8c17d08c3eeb6ea3f60fa1b898bd638079 [file] [log] [blame]
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// QualificationOrder_test.cpp:
// OpenGL ES 3.1 removes the strict order of qualifiers imposed by the grammar.
// This file contains tests for invalid order and usage of qualifiers.
#include "tests/test_utils/ShaderCompileTreeTest.h"
using namespace sh;
class QualificationOrderFragmentShaderTest : public ShaderCompileTreeTest
{
public:
QualificationOrderFragmentShaderTest() {}
protected:
void initResources(ShBuiltInResources *resources) override
{
resources->MaxDrawBuffers = (getShaderSpec() == SH_GLES2_SPEC) ? 1 : 8;
}
::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
};
class QualificationOrderVertexShaderTest : public QualificationOrderFragmentShaderTest
{
public:
QualificationOrderVertexShaderTest() {}
protected:
::GLenum getShaderType() const override { return GL_VERTEX_SHADER; }
};
// Repeating centroid qualifier is invalid.
TEST_F(QualificationOrderFragmentShaderTest, RepeatingCentroid)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"flat centroid centroid in float myValue;\n"
"void main() {\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Repeating uniform storage qualifiers is invalid.
TEST_F(QualificationOrderFragmentShaderTest, RepeatingUniforms)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"uniform uniform float myValue;\n"
"void main() {\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Repeating varying storage qualifiers is invalid.
TEST_F(QualificationOrderFragmentShaderTest, RepeatingVaryings)
{
const std::string &shaderString =
"precision mediump float;\n"
"varying varying vec4 myColor;\n"
"void main() {\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Layout qualifier should be before the storage qualifiers.
TEST_F(QualificationOrderFragmentShaderTest, WrongOrderQualifiers)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"out layout(location=1) vec4 myColor;\n"
"void main() {\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Centroid out is the correct order. Out centroid is incorrect.
TEST_F(QualificationOrderVertexShaderTest, WrongOrderCentroidOut)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 uv;\n"
"out centroid vec4 position;\n"
"void main() {\n"
"position = uv;\n"
"gl_Position = uv;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Centroid in is the correct order. In centroid is incorrect.
TEST_F(QualificationOrderFragmentShaderTest, WrongOrderCentroidIn)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in centroid vec4 colorIN;\n"
"out vec4 colorOUT;\n"
"void main() {\n"
"colorOUT = colorIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Type cannot be before the storage qualifier.
TEST_F(QualificationOrderFragmentShaderTest, WrongOrderTypeStorage)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"centroid in vec4 colorIN;\n"
"vec4 out colorOUT;\n"
"void main() {\n"
"colorOUT = colorIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have two conflicting storage qualifiers.
TEST_F(QualificationOrderFragmentShaderTest, RepeatingDifferentStorageQualifiers)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"centroid in vec4 colorIN;\n"
"uniform out vec4 colorOUT;\n"
"void main() {\n"
"colorOUT = colorIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have two different layout qualifiers.
TEST_F(QualificationOrderFragmentShaderTest, RepeatingLayoutQualifiers)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 colorIN;\n"
"layout(location=0) layout(location=0) out vec4 colorOUT;\n"
"void main() {\n"
"colorOUT = colorIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have repeating invariant qualifiers.
TEST_F(QualificationOrderFragmentShaderTest, RepeatingInvariantQualifiers)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 colorIN;\n"
"invariant invariant out vec4 colorOUT;\n"
"void main() {\n"
"colorOUT = colorIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have repeating storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest, RepeatingAttributes)
{
const std::string &shaderString =
"precision mediump float;\n"
"attribute attribute vec4 positionIN;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Wrong order for invariant varying. It should be 'invariant varying', not 'varying invariant'.
TEST_F(QualificationOrderVertexShaderTest, VaryingInvariantWrongOrder)
{
const std::string &shaderString =
"precision mediump float;\n"
"attribute vec4 positionIN;\n"
"varying invariant vec4 dataOUT;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have repeating storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest, AttributeVaryingMix)
{
const std::string &shaderString =
"precision mediump float;\n"
"attribute varying vec4 positionIN;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have repeating storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest, VaryingAttributeMix)
{
const std::string &shaderString =
"precision mediump float;\n"
"varying attribute vec4 positionIN;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have repeating interpolation qualifiers.
TEST_F(QualificationOrderVertexShaderTest, RepeatingInterpolationQualifiers)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 positionIN;\n"
"flat flat out vec4 dataOUT;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Wrong order for the interpolation and storage qualifier. The correct order is interpolation
// qualifier and then storage qualifier.
TEST_F(QualificationOrderVertexShaderTest, WrongOrderInterpolationStorageQualifiers)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 positionIN;\n"
"out flat vec4 dataOUT;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// The correct order is invariant, interpolation, storage.
TEST_F(QualificationOrderVertexShaderTest, WrongOrderInvariantInterpolationStorageQualifiers)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 positionIN;\n"
"flat invariant out vec4 dataOUT;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// The invariant qualifer has to be before the storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest, WrongOrderInvariantNotFirst)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 positionIN;\n"
"centroid out invariant vec4 dataOUT;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// The precision qualifier is after the storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest, WrongOrderPrecision)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in vec4 positionIN;\n"
"highp centroid out vec4 dataOUT;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have multiple declarations of the 'in' storage qualifier.
TEST_F(QualificationOrderVertexShaderTest, RepeatingInQualifier)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"in in vec4 positionIN;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// A variable cannot have multiple declarations of the 'attribute' storage qualifier.
TEST_F(QualificationOrderVertexShaderTest, RepeatingAttributeQualifier)
{
const std::string &shaderString =
"precision mediump float;\n"
"attribute attribute vec4 positionIN;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Vertex input cannot be qualified with invariant.
TEST_F(QualificationOrderVertexShaderTest, InvariantVertexInput)
{
const std::string &shaderString =
"precision mediump float;\n"
"invariant attribute vec4 positionIN;\n"
"void main() {\n"
"gl_Position = positionIN;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Cannot have a function parameter with the invariant qualifier.
TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersInvariant)
{
const std::string &shaderString =
"precision lowp float;\n"
"varying float value;\n"
"float foo0 (invariant in float x) {\n"
" return 2.0*x;\n"
"}\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(foo0(value));\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
}
}
// Cannot have a function parameter with the attribute qualifier.
TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersAttribute)
{
const std::string &shaderString =
"precision lowp float;\n"
"varying float value;\n"
"float foo0 (attribute float x) {\n"
" return 2.0*x;\n"
"}\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(foo0(value));\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
}
}
// Cannot have a function parameter with the varying qualifier.
TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersVarying)
{
const std::string &shaderString =
"precision lowp float;\n"
"varying float value;\n"
"float foo0 (varying float x) {\n"
" return 2.0*x;\n"
"}\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(foo0(value));\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
}
}
// Cannot have a function parameter with the layout qualifier
TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersLayout)
{
const std::string &shaderString =
"#version 300 es\n"
"precision lowp float;\n"
"in float value;\n"
"float foo0 (layout(location = 3) in float x) {\n"
" return 2.0*x;\n"
"}\n"
"out vec4 colorOUT;\n"
"void main()\n"
"{\n"
" colorOUT = vec4(foo0(value));\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
}
}
// Cannot have a function parameter with the centroid qualifier
TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersCentroidIn)
{
const std::string &shaderString =
"#version 300 es\n"
"precision lowp float;\n"
"in float value;\n"
"float foo0 (centroid in float x) {\n"
" return 2.0*x;\n"
"}\n"
"out vec4 colorOUT;\n"
"void main()\n"
"{\n"
" colorOUT = vec4(foo0(value));\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
}
}
// Cannot have a function parameter with the flat qualifier
TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersFlatIn)
{
const std::string &shaderString =
"#version 300 es\n"
"precision lowp float;\n"
"in float value;\n"
"float foo0 (flat in float x) {\n"
" return 2.0*x;\n"
"}\n"
"out vec4 colorOUT;\n"
"void main()\n"
"{\n"
" colorOUT = vec4(foo0(value));\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
}
}
// Output layout location qualifier can't appear more than once within a declaration.
// GLSL ES 3.00.6 section 4.3.8.2 Output Layout Qualifiers.
TEST_F(QualificationOrderFragmentShaderTest, TwoOutputLocations)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"layout(location=1, location=2) out vec4 myColor;\n"
"void main() {\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}