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