xref: /aosp_15_r20/external/angle/src/tests/compiler_tests/AtomicCounter_test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2017 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 // AtomicCounter_test.cpp:
7 //   Tests for validating ESSL 3.10 section 4.4.6.
8 //
9 
10 #include "gtest/gtest.h"
11 
12 #include "GLSLANG/ShaderLang.h"
13 #include "angle_gl.h"
14 #include "gtest/gtest.h"
15 #include "tests/test_utils/ShaderCompileTreeTest.h"
16 
17 using namespace sh;
18 
19 class AtomicCounterTest : public ShaderCompileTreeTest
20 {
21   public:
AtomicCounterTest()22     AtomicCounterTest() {}
23 
24   protected:
getShaderType() const25     ::GLenum getShaderType() const override { return GL_VERTEX_SHADER; }
getShaderSpec() const26     ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
initResources(ShBuiltInResources * resources)27     void initResources(ShBuiltInResources *resources) override
28     {
29         resources->MaxAtomicCounterBindings = 8;
30     }
31 };
32 
33 // Test that layout qualifiers described in ESSL 3.10 section 4.4.6 can be successfully compiled,
34 // and the values of offset are properly assigned to counter variables.
TEST_F(AtomicCounterTest,BasicAtomicCounterDeclaration)35 TEST_F(AtomicCounterTest, BasicAtomicCounterDeclaration)
36 {
37     const std::string &source =
38         "#version 310 es\n"
39         "layout(binding = 2, offset = 4) uniform atomic_uint a;\n"
40         "layout(binding = 2) uniform atomic_uint b;\n"
41         "layout(binding = 2, offset = 12) uniform atomic_uint c, d;\n"
42         "layout(binding = 1, offset = 4) uniform atomic_uint e;\n"
43         "void main()\n"
44         "{\n"
45         "}\n";
46     if (!compile(source))
47     {
48         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
49     }
50 
51     std::vector<sh::ShaderVariable> counters = getUniforms();
52 
53     EXPECT_EQ(std::string("a"), counters[0].name);
54     EXPECT_EQ(2, counters[0].binding);
55     EXPECT_EQ(4, counters[0].offset);
56 
57     EXPECT_EQ(std::string("b"), counters[1].name);
58     EXPECT_EQ(2, counters[1].binding);
59     EXPECT_EQ(8, counters[1].offset);
60 
61     EXPECT_EQ(std::string("c"), counters[2].name);
62     EXPECT_EQ(2, counters[2].binding);
63     EXPECT_EQ(12, counters[2].offset);
64 
65     EXPECT_EQ(std::string("d"), counters[3].name);
66     EXPECT_EQ(2, counters[3].binding);
67     EXPECT_EQ(16, counters[3].offset);
68 
69     EXPECT_EQ(std::string("e"), counters[4].name);
70     EXPECT_EQ(1, counters[4].binding);
71     EXPECT_EQ(4, counters[4].offset);
72 }
73 
74 // Test that ESSL 3.00 doesn't support atomic_uint.
TEST_F(AtomicCounterTest,InvalidShaderVersion)75 TEST_F(AtomicCounterTest, InvalidShaderVersion)
76 {
77     const std::string &source =
78         "#version 300 es\n"
79         "layout(binding = 2, offset = 4) uniform atomic_uint a;\n"
80         "void main()\n"
81         "{\n"
82         "}\n";
83     if (compile(source))
84     {
85         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
86     }
87 }
88 
89 // Test that any qualifier other than uniform leads to compile-time error.
TEST_F(AtomicCounterTest,InvalidQualifier)90 TEST_F(AtomicCounterTest, InvalidQualifier)
91 {
92     const std::string &source =
93         "#version 310 es\n"
94         "layout(binding = 2, offset = 4) in atomic_uint a;\n"
95         "void main()\n"
96         "{\n"
97         "}\n";
98     if (compile(source))
99     {
100         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
101     }
102 }
103 
104 // Test that uniform must be specified for declaration.
TEST_F(AtomicCounterTest,UniformMustSpecifiedForDeclaration)105 TEST_F(AtomicCounterTest, UniformMustSpecifiedForDeclaration)
106 {
107     const std::string &source =
108         "#version 310 es\n"
109         "atomic_uint a;\n"
110         "void main()\n"
111         "{\n"
112         "}\n";
113     if (compile(source))
114     {
115         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
116     }
117 }
118 
119 // Test that offset overlapping leads to compile-time error(ESSL 3.10 section 4.4.6).
TEST_F(AtomicCounterTest,BindingOffsetOverlapping)120 TEST_F(AtomicCounterTest, BindingOffsetOverlapping)
121 {
122     const std::string &source =
123         "#version 310 es\n"
124         "layout(binding = 2, offset = 4) uniform atomic_uint a;\n"
125         "layout(binding = 2, offset = 6) uniform atomic_uint b;\n"
126         "void main()\n"
127         "{\n"
128         "}\n";
129     if (compile(source))
130     {
131         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
132     }
133 }
134 
135 // Test offset inheritance for multiple variables in one same declaration.
TEST_F(AtomicCounterTest,MultipleVariablesDeclaration)136 TEST_F(AtomicCounterTest, MultipleVariablesDeclaration)
137 {
138     const std::string &source =
139         "#version 310 es\n"
140         "layout(binding = 2, offset = 4) uniform atomic_uint a, b;\n"
141         "layout(binding = 2, offset = 8) uniform atomic_uint c;\n"
142         "void main()\n"
143         "{\n"
144         "}\n";
145     if (compile(source))
146     {
147         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
148     }
149 }
150 
151 // Test that subsequent declarations inherit the globally specified offset.
TEST_F(AtomicCounterTest,GlobalBindingOffsetOverlapping)152 TEST_F(AtomicCounterTest, GlobalBindingOffsetOverlapping)
153 {
154     const std::string &source =
155         "#version 310 es\n"
156         "layout(binding = 2, offset = 4) uniform atomic_uint;\n"
157         "layout(binding = 2) uniform atomic_uint b;\n"
158         "layout(binding = 2, offset = 4) uniform atomic_uint c;\n"
159         "void main()\n"
160         "{\n"
161         "}\n";
162     if (compile(source))
163     {
164         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
165     }
166 }
167 
168 // The spec only demands offset unique and non-overlapping. So this should be allowed.
TEST_F(AtomicCounterTest,DeclarationSequenceWithDecrementalOffsetsSpecified)169 TEST_F(AtomicCounterTest, DeclarationSequenceWithDecrementalOffsetsSpecified)
170 {
171     const std::string &source =
172         "#version 310 es\n"
173         "layout(binding = 2, offset = 4) uniform atomic_uint a;\n"
174         "layout(binding = 2, offset = 0) uniform atomic_uint b;\n"
175         "void main()\n"
176         "{\n"
177         "}\n";
178     if (!compile(source))
179     {
180         FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
181     }
182 }
183 
184 // Test that image format qualifiers are not allowed for atomic counters.
TEST_F(AtomicCounterTest,ImageFormatMustNotSpecified)185 TEST_F(AtomicCounterTest, ImageFormatMustNotSpecified)
186 {
187     const std::string &source =
188         "#version 310 es\n"
189         "layout(binding = 2, offset = 4, rgba32f) uniform atomic_uint a;\n"
190         "void main()\n"
191         "{\n"
192         "}\n";
193     if (compile(source))
194     {
195         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
196     }
197 }
198 
199 // Test that global layout qualifiers must not use 'offset'.
TEST_F(AtomicCounterTest,OffsetMustNotSpecifiedForGlobalLayoutQualifier)200 TEST_F(AtomicCounterTest, OffsetMustNotSpecifiedForGlobalLayoutQualifier)
201 {
202     const std::string &source =
203         "#version 310 es\n"
204         "layout(offset = 4) in;\n"
205         "void main()\n"
206         "{\n"
207         "}\n";
208     if (compile(source))
209     {
210         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
211     }
212 }
213 
214 // Test that offset overlapping leads to compile-time error (ESSL 3.10 section 4.4.6).
215 // Note that there is some vagueness in the spec when it comes to this test.
TEST_F(AtomicCounterTest,BindingOffsetOverlappingForArrays)216 TEST_F(AtomicCounterTest, BindingOffsetOverlappingForArrays)
217 {
218     const std::string &source =
219         "#version 310 es\n"
220         "layout(binding = 2, offset = 4) uniform atomic_uint[2] a;\n"
221         "layout(binding = 2, offset = 8) uniform atomic_uint b;\n"
222         "void main()\n"
223         "{\n"
224         "}\n";
225     if (compile(source))
226     {
227         FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
228     }
229 }
230