1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // QualificationOrderESSL31_test.cpp:
7 // OpenGL ES 3.1 removes the strict order of qualifiers imposed by the grammar.
8 // This file contains tests for invalid order and usage of qualifiers in GLSL ES 3.10.
9
10 #include "gtest/gtest.h"
11
12 #include "GLSLANG/ShaderLang.h"
13 #include "angle_gl.h"
14 #include "tests/test_utils/ShaderCompileTreeTest.h"
15 #include "tests/test_utils/compiler_test.h"
16
17 using namespace sh;
18
19 class QualificationVertexShaderTestESSL31 : public ShaderCompileTreeTest
20 {
21 public:
QualificationVertexShaderTestESSL31()22 QualificationVertexShaderTestESSL31() {}
23
24 protected:
getShaderType() const25 ::GLenum getShaderType() const override { return GL_VERTEX_SHADER; }
getShaderSpec() const26 ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
27
findSymbolInAST(const ImmutableString & symbolName)28 const TIntermSymbol *findSymbolInAST(const ImmutableString &symbolName)
29 {
30 return FindSymbolNode(mASTRoot, symbolName);
31 }
32 };
33
34 // GLSL ES 3.10 has relaxed checks on qualifier order. Any order is correct.
TEST_F(QualificationVertexShaderTestESSL31,CentroidOut)35 TEST_F(QualificationVertexShaderTestESSL31, CentroidOut)
36 {
37 const std::string &shaderString =
38 "#version 310 es\n"
39 "precision lowp float;\n"
40 "out centroid float something;\n"
41 "void main(){\n"
42 " something = 1.0;\n"
43 "}\n";
44 if (!compile(shaderString))
45 {
46 FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
47 }
48 else
49 {
50 const TIntermSymbol *node = findSymbolInAST(ImmutableString("something"));
51 ASSERT_NE(nullptr, node);
52
53 const TType &type = node->getType();
54 EXPECT_EQ(EvqCentroidOut, type.getQualifier());
55 }
56 }
57
58 // GLSL ES 3.10 has relaxed checks on qualifier order. Any order is correct.
TEST_F(QualificationVertexShaderTestESSL31,AllQualifiersMixed)59 TEST_F(QualificationVertexShaderTestESSL31, AllQualifiersMixed)
60 {
61 const std::string &shaderString =
62 "#version 310 es\n"
63 "precision lowp float;\n"
64 "highp out invariant centroid flat vec4 something;\n"
65 "void main(){\n"
66 "}\n";
67 if (!compile(shaderString))
68 {
69 FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
70 }
71 else
72 {
73 const TIntermSymbol *node = findSymbolInAST(ImmutableString("something"));
74 ASSERT_NE(nullptr, node);
75
76 const TType &type = node->getType();
77 EXPECT_TRUE(type.isInvariant());
78 EXPECT_EQ(EvqFlatOut, type.getQualifier());
79 EXPECT_EQ(EbpHigh, type.getPrecision());
80 }
81 }
82
83 // GLSL ES 3.10 allows multiple layout qualifiers to be specified.
TEST_F(QualificationVertexShaderTestESSL31,MultipleLayouts)84 TEST_F(QualificationVertexShaderTestESSL31, MultipleLayouts)
85 {
86 const std::string &shaderString =
87 "#version 310 es\n"
88 "precision lowp float;\n"
89 "in layout(location=1) layout(location=2) vec4 something;\n"
90 "void main(){\n"
91 "}\n";
92 if (!compile(shaderString))
93 {
94 FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
95 }
96 else
97 {
98 const TIntermSymbol *node = findSymbolInAST(ImmutableString("something"));
99 ASSERT_NE(nullptr, node);
100
101 const TType &type = node->getType();
102 EXPECT_EQ(EvqVertexIn, type.getQualifier());
103 EXPECT_EQ(2, type.getLayoutQualifier().location);
104 }
105 }
106
107 // The test checks layout qualifier overriding when multiple layouts are specified.
TEST_F(QualificationVertexShaderTestESSL31,MultipleLayoutsInterfaceBlock)108 TEST_F(QualificationVertexShaderTestESSL31, MultipleLayoutsInterfaceBlock)
109 {
110 const std::string &shaderString =
111 "#version 310 es\n"
112 "precision lowp float;\n"
113 "out float someValue;\n"
114 "layout(shared) layout(std140) layout(column_major) uniform MyInterface\n"
115 "{ vec4 something; } MyInterfaceName;\n"
116 "void main(){\n"
117 " someValue = MyInterfaceName.something.r;\n"
118 "}\n";
119 if (!compile(shaderString))
120 {
121 FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
122 }
123 else
124 {
125 const TIntermSymbol *node = findSymbolInAST(ImmutableString("MyInterfaceName"));
126 ASSERT_NE(nullptr, node);
127
128 const TType &type = node->getType();
129 TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
130 EXPECT_EQ(EbsStd140, layoutQualifier.blockStorage);
131 EXPECT_EQ(EmpColumnMajor, layoutQualifier.matrixPacking);
132 }
133 }
134
135 // The test checks layout qualifier overriding when multiple layouts are specified.
TEST_F(QualificationVertexShaderTestESSL31,MultipleLayoutsInterfaceBlock2)136 TEST_F(QualificationVertexShaderTestESSL31, MultipleLayoutsInterfaceBlock2)
137 {
138 const std::string &shaderString =
139 "#version 310 es\n"
140 "precision lowp float;\n"
141 "out float someValue;\n"
142 "layout(row_major) layout(std140) layout(shared) uniform MyInterface\n"
143 "{ vec4 something; } MyInterfaceName;\n"
144 "void main(){\n"
145 " someValue = MyInterfaceName.something.r;\n"
146 "}\n";
147 if (!compile(shaderString))
148 {
149 FAIL() << "Shader compilation failed, expecting success" << mInfoLog;
150 }
151 else
152 {
153 const TIntermSymbol *node = findSymbolInAST(ImmutableString("MyInterfaceName"));
154 ASSERT_NE(nullptr, node);
155
156 const TType &type = node->getType();
157 TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
158 EXPECT_EQ(EbsShared, layoutQualifier.blockStorage);
159 EXPECT_EQ(EmpRowMajor, layoutQualifier.matrixPacking);
160 }
161 }
162