Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/compiler_tests/BufferVariables_test.cpp
1693 views
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
// BufferVariables_test.cpp:
7
// Tests for buffer variables in GLSL ES 3.10 section 4.3.7.
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
#include "tests/test_utils/compiler_test.h"
17
18
using namespace sh;
19
20
class BufferVariablesTest : public ShaderCompileTreeTest
21
{
22
public:
23
BufferVariablesTest() {}
24
25
protected:
26
::GLenum getShaderType() const override { return GL_VERTEX_SHADER; }
27
ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
28
void initResources(ShBuiltInResources *resources) override
29
{
30
resources->MaxShaderStorageBufferBindings = 8;
31
}
32
};
33
34
class BufferVariablesMatchTest : public MatchOutputCodeTest
35
{
36
public:
37
BufferVariablesMatchTest() : MatchOutputCodeTest(GL_VERTEX_SHADER, 0, SH_ESSL_OUTPUT)
38
{
39
getResources()->MaxShaderStorageBufferBindings = 8;
40
}
41
};
42
43
// Test that the buffer qualifier described in GLSL ES 3.10 section 4.3.7 can be successfully
44
// compiled.
45
TEST_F(BufferVariablesTest, BasicShaderStorageBlockDeclaration)
46
{
47
const std::string &source =
48
"#version 310 es\n"
49
"layout(binding = 3) buffer buf {\n"
50
" int b1;\n"
51
" buffer int b2;\n"
52
"};\n"
53
"void main()\n"
54
"{\n"
55
"}\n";
56
if (!compile(source))
57
{
58
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
59
}
60
}
61
62
// Test that shader storage block layout qualifiers can be declared for global scope.
63
TEST_F(BufferVariablesTest, LayoutQualifiersDeclaredInGlobal)
64
{
65
const std::string &source =
66
"#version 310 es\n"
67
"layout(shared, column_major) buffer;\n"
68
"void main()\n"
69
"{\n"
70
"}\n";
71
if (!compile(source))
72
{
73
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
74
}
75
}
76
77
// Test that shader storage block can be used with one or more memory qualifiers.
78
TEST_F(BufferVariablesTest, ShaderStorageBlockWithMemoryQualifier)
79
{
80
const std::string &source =
81
"#version 310 es\n"
82
"layout(binding = 3) writeonly buffer buf {\n"
83
" int b1;\n"
84
" buffer int b2;\n"
85
"};\n"
86
"void main()\n"
87
"{\n"
88
"}\n";
89
if (!compile(source))
90
{
91
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
92
}
93
}
94
95
// Test that buffer variables can be used with one or more memory qualifiers.
96
TEST_F(BufferVariablesTest, BufferVariablesWithMemoryQualifier)
97
{
98
const std::string &source =
99
"#version 310 es\n"
100
"layout(binding = 3) buffer buf {\n"
101
" writeonly int b1;\n"
102
" writeonly buffer int b2;\n"
103
"};\n"
104
"void main()\n"
105
"{\n"
106
"}\n";
107
if (!compile(source))
108
{
109
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
110
}
111
}
112
113
// Test that it is a compile-time error to declare buffer variables at global scope (outside a
114
// block).
115
TEST_F(BufferVariablesTest, DeclareBufferVariableAtGlobal)
116
{
117
const std::string &source =
118
"#version 310 es\n"
119
"layout(binding = 3) buffer int a;\n"
120
"void main()\n"
121
"{\n"
122
"}\n";
123
if (compile(source))
124
{
125
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
126
}
127
}
128
129
// Test that the buffer variable can't be opaque type.
130
TEST_F(BufferVariablesTest, BufferVariableWithOpaqueType)
131
{
132
const std::string &source =
133
"#version 310 es\n"
134
"layout(binding = 3) buffer buf {\n"
135
" int b1;\n"
136
" atomic_uint b2;\n"
137
"};\n"
138
"void main()\n"
139
"{\n"
140
"}\n";
141
if (compile(source))
142
{
143
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
144
}
145
}
146
147
// Test that the uniform variable can't be in shader storage block.
148
TEST_F(BufferVariablesTest, UniformVariableInShaderStorageBlock)
149
{
150
const std::string &source =
151
"#version 310 es\n"
152
"layout(binding = 3) buffer buf {\n"
153
" uniform int a;\n"
154
"};\n"
155
"void main()\n"
156
"{\n"
157
"}\n";
158
if (compile(source))
159
{
160
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
161
}
162
}
163
164
// Test that buffer qualifier is not supported in verson lower than GLSL ES 3.10.
165
TEST_F(BufferVariablesTest, BufferQualifierInESSL3)
166
{
167
const std::string &source =
168
"#version 300 es\n"
169
"layout(binding = 3) buffer buf {\n"
170
" int b1;\n"
171
" buffer int b2;\n"
172
"};\n"
173
"void main()\n"
174
"{\n"
175
"}\n";
176
if (compile(source))
177
{
178
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
179
}
180
}
181
182
// Test that can't assign to a readonly buffer variable.
183
TEST_F(BufferVariablesTest, AssignToReadonlyBufferVariable)
184
{
185
const std::string &source =
186
"#version 310 es\n"
187
"layout(binding = 3) buffer buf {\n"
188
" readonly int b1;\n"
189
"};\n"
190
"void main()\n"
191
"{\n"
192
" b1 = 5;\n"
193
"}\n";
194
if (compile(source))
195
{
196
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
197
}
198
}
199
200
// Test that can't assign to a buffer variable declared within shader storage block with readonly.
201
TEST_F(BufferVariablesTest, AssignToBufferVariableWithinReadonlyBlock)
202
{
203
const std::string &source =
204
"#version 310 es\n"
205
"layout(binding = 3) readonly buffer buf {\n"
206
" int b1;\n"
207
"};\n"
208
"void main()\n"
209
"{\n"
210
" b1 = 5;\n"
211
"}\n";
212
if (compile(source))
213
{
214
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
215
}
216
}
217
218
// Test that can't assign to a readonly buffer variable through an instance name.
219
TEST_F(BufferVariablesTest, AssignToReadonlyBufferVariableByInstanceName)
220
{
221
const std::string &source =
222
R"(#version 310 es
223
layout(binding = 3) buffer buf {
224
readonly float f;
225
} instanceBuffer;
226
void main()
227
{
228
instanceBuffer.f += 0.2;
229
})";
230
if (compile(source))
231
{
232
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
233
}
234
}
235
236
// Test that can't assign to a readonly struct buffer variable.
237
TEST_F(BufferVariablesTest, AssignToReadonlyStructBufferVariable)
238
{
239
const std::string &source =
240
R"(#version 310 es
241
struct S {
242
float f;
243
};
244
layout(binding = 3) buffer buf {
245
readonly S s;
246
};
247
void main()
248
{
249
s.f += 0.2;
250
})";
251
if (compile(source))
252
{
253
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
254
}
255
}
256
257
// Test that can't assign to a readonly struct buffer variable through an instance name.
258
TEST_F(BufferVariablesTest, AssignToReadonlyStructBufferVariableByInstanceName)
259
{
260
const std::string &source =
261
R"(#version 310 es
262
struct S {
263
float f;
264
};
265
layout(binding = 3) buffer buf {
266
readonly S s;
267
} instanceBuffer;
268
void main()
269
{
270
instanceBuffer.s.f += 0.2;
271
})";
272
if (compile(source))
273
{
274
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
275
}
276
}
277
278
// Test that a readonly and writeonly buffer variable should neither read or write.
279
TEST_F(BufferVariablesTest, AccessReadonlyWriteonlyBufferVariable)
280
{
281
const std::string &source =
282
"#version 310 es\n"
283
"layout(binding = 3) buffer buf {\n"
284
" readonly writeonly int b1;\n"
285
"};\n"
286
"void main()\n"
287
"{\n"
288
" b1 = 5;\n"
289
" int test = b1;\n"
290
"}\n";
291
if (compile(source))
292
{
293
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
294
}
295
}
296
297
// Test that accessing a writeonly buffer variable should be error.
298
TEST_F(BufferVariablesTest, AccessWriteonlyBufferVariable)
299
{
300
const std::string &source =
301
"#version 310 es\n"
302
"layout(binding = 3) buffer buf {\n"
303
" writeonly int b1;\n"
304
"};\n"
305
"void main()\n"
306
"{\n"
307
" int test = b1;\n"
308
"}\n";
309
if (compile(source))
310
{
311
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
312
}
313
}
314
315
// Test that accessing a buffer variable through an instance name is ok.
316
TEST_F(BufferVariablesTest, AccessReadonlyBufferVariableByInstanceName)
317
{
318
const std::string &source =
319
"#version 310 es\n"
320
"layout(binding = 3) buffer buf {\n"
321
" readonly float f;\n"
322
"} instanceBuffer;\n"
323
"void main()\n"
324
"{\n"
325
" gl_Position.x = instanceBuffer.f;\n"
326
"}\n";
327
if (!compile(source))
328
{
329
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
330
}
331
}
332
333
// Test that accessing a buffer variable through an instance name inherits the writeonly qualifier
334
// and generates errors.
335
TEST_F(BufferVariablesTest, AccessWriteonlyBufferVariableByInstanceName)
336
{
337
const std::string &source =
338
"#version 310 es\n"
339
"layout(binding = 3) writeonly buffer buf {\n"
340
" float f;\n"
341
"} instanceBuffer;\n"
342
"void main()\n"
343
"{\n"
344
" float test = instanceBuffer.f;\n"
345
"}\n";
346
if (compile(source))
347
{
348
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
349
}
350
}
351
352
// Test that writeonly buffer variable as the argument of a unary operator should be error.
353
TEST_F(BufferVariablesTest, UnaryOperatorWithWriteonlyBufferVariable)
354
{
355
const std::string &source =
356
"#version 310 es\n"
357
"layout(binding = 3) buffer buf {\n"
358
" writeonly int b1;\n"
359
"};\n"
360
"void main()\n"
361
"{\n"
362
" ++b1;\n"
363
"}\n";
364
if (compile(source))
365
{
366
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
367
}
368
}
369
370
// Test that writeonly buffer variable on the left-hand side of compound assignment should be error.
371
TEST_F(BufferVariablesTest, CompoundAssignmentToWriteonlyBufferVariable)
372
{
373
const std::string &source =
374
"#version 310 es\n"
375
"layout(binding = 3) buffer buf {\n"
376
" writeonly int b1;\n"
377
"};\n"
378
"void main()\n"
379
"{\n"
380
" b1 += 5;\n"
381
"}\n";
382
if (compile(source))
383
{
384
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
385
}
386
}
387
388
// Test that writeonly buffer variable as ternary op argument should be error.
389
TEST_F(BufferVariablesTest, TernarySelectionWithWriteonlyBufferVariable)
390
{
391
const std::string &source =
392
"#version 310 es\n"
393
"layout(binding = 3) buffer buf {\n"
394
" writeonly bool b1;\n"
395
"};\n"
396
"void main()\n"
397
"{\n"
398
" int test = b1 ? 1 : 0;\n"
399
"}\n";
400
if (compile(source))
401
{
402
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
403
}
404
}
405
406
// Test that writeonly buffer variable as array constructor argument should be error.
407
TEST_F(BufferVariablesTest, ArrayConstructorWithWriteonlyBufferVariable)
408
{
409
const std::string &source =
410
"#version 310 es\n"
411
"layout(binding = 3) buffer buf {\n"
412
" writeonly float f;\n"
413
"};\n"
414
"void main()\n"
415
"{\n"
416
" float a[3] = float[3](f, f, f);\n"
417
"}\n";
418
if (compile(source))
419
{
420
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
421
}
422
}
423
424
// Test that writeonly buffer variable as structure constructor argument should be error.
425
TEST_F(BufferVariablesTest, StructureConstructorWithWriteonlyBufferVariable)
426
{
427
const std::string &source =
428
"#version 310 es\n"
429
"struct S {\n"
430
" int a;\n"
431
"};\n"
432
"struct T {\n"
433
" S b;\n"
434
"};\n"
435
"layout(binding = 3) buffer buf {\n"
436
" writeonly S c;\n"
437
"};\n"
438
"void main()\n"
439
"{\n"
440
" T t = T(c);\n"
441
"}\n";
442
if (compile(source))
443
{
444
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
445
}
446
}
447
448
// Test that writeonly buffer variable as built-in function argument should be error.
449
TEST_F(BufferVariablesTest, BuildInFunctionWithWriteonlyBufferVariable)
450
{
451
const std::string &source =
452
"#version 310 es\n"
453
"layout(binding = 3) buffer buf {\n"
454
" writeonly int a;\n"
455
"};\n"
456
"void main()\n"
457
"{\n"
458
" int test = min(a, 1);\n"
459
"}\n";
460
if (compile(source))
461
{
462
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
463
}
464
}
465
466
// Test that readonly buffer variable as user-defined function in argument should be ok.
467
TEST_F(BufferVariablesTest, UserDefinedFunctionWithReadonlyBufferVariableInArgument)
468
{
469
const std::string &source =
470
"#version 310 es\n"
471
"layout(binding = 3) buffer buf {\n"
472
" readonly float f;\n"
473
"};\n"
474
"void foo(float a) {}\n"
475
"void main()\n"
476
"{\n"
477
" foo(f);\n"
478
"}\n";
479
if (!compile(source))
480
{
481
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
482
}
483
}
484
485
// Test that writeonly buffer variable as user-defined function in argument should be error.
486
TEST_F(BufferVariablesTest, UserDefinedFunctionWithWriteonlyBufferVariableInArgument)
487
{
488
const std::string &source =
489
"#version 310 es\n"
490
"layout(binding = 3) buffer buf {\n"
491
" writeonly float f;\n"
492
"};\n"
493
"void foo(float a) {}\n"
494
"void main()\n"
495
"{\n"
496
" foo(f);\n"
497
"}\n";
498
if (compile(source))
499
{
500
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
501
}
502
}
503
504
// Test that writeonly buffer variable as user-defined function out argument should be ok.
505
TEST_F(BufferVariablesTest, UserDefinedFunctionWithWriteonlyBufferVariableOutArgument)
506
{
507
const std::string &source =
508
"#version 310 es\n"
509
"layout(binding = 3) buffer buf {\n"
510
" writeonly float f;\n"
511
"};\n"
512
"void foo(out float a) {}\n"
513
"void main()\n"
514
"{\n"
515
" foo(f);\n"
516
"}\n";
517
if (!compile(source))
518
{
519
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
520
}
521
}
522
523
// Test that readonly buffer variable as user-defined function out argument should be error.
524
TEST_F(BufferVariablesTest, UserDefinedFunctionWithReadonlyBufferVariableOutArgument)
525
{
526
const std::string &source =
527
"#version 310 es\n"
528
"layout(binding = 3) buffer buf {\n"
529
" readonly float f;\n"
530
"};\n"
531
"void foo(out float a) {}\n"
532
"void main()\n"
533
"{\n"
534
" foo(f);\n"
535
"}\n";
536
if (compile(source))
537
{
538
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
539
}
540
}
541
542
// Test that buffer qualifier can't modify a function parameter.
543
TEST_F(BufferVariablesTest, BufferQualifierOnFunctionParameter)
544
{
545
const std::string &source =
546
"#version 310 es\n"
547
"void foo(buffer float a) {}\n"
548
"void main()\n"
549
"{\n"
550
"}\n";
551
if (compile(source))
552
{
553
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
554
}
555
}
556
557
// Test that std430 qualifier is supported for shader storage blocks.
558
TEST_F(BufferVariablesTest, ShaderStorageBlockWithStd430)
559
{
560
const std::string &source =
561
"#version 310 es\n"
562
"layout(std430) buffer buf {\n"
563
" int b1;\n"
564
" int b2;\n"
565
"};\n"
566
"void main()\n"
567
"{\n"
568
"}\n";
569
if (!compile(source))
570
{
571
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
572
}
573
}
574
575
// Test that using std430 qualifier on a uniform block will fail to compile.
576
TEST_F(BufferVariablesTest, UniformBlockWithStd430)
577
{
578
const std::string &source =
579
"#version 310 es\n"
580
"layout(std430) uniform buf {\n"
581
" int b1;\n"
582
" int b2;\n"
583
"};\n"
584
"void main()\n"
585
"{\n"
586
"}\n";
587
if (compile(source))
588
{
589
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
590
}
591
}
592
593
// Test that indexing a runtime-sized array with a positive index compiles.
594
TEST_F(BufferVariablesTest, IndexRuntimeSizedArray)
595
{
596
const std::string &source =
597
R"(#version 310 es
598
599
layout(std430) buffer buf
600
{
601
int arr[];
602
};
603
604
void main()
605
{
606
arr[100];
607
})";
608
if (!compile(source))
609
{
610
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
611
}
612
}
613
614
// Test that indexing a runtime-sized array with a negative constant index does not compile.
615
TEST_F(BufferVariablesTest, IndexRuntimeSizedArrayWithNegativeIndex)
616
{
617
const std::string &source =
618
R"(#version 310 es
619
620
layout(std430) buffer buf
621
{
622
int arr[];
623
};
624
625
void main()
626
{
627
arr[-1];
628
})";
629
if (compile(source))
630
{
631
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
632
}
633
}
634
635
// Test that only the last member of a buffer can be runtime-sized.
636
TEST_F(BufferVariablesTest, RuntimeSizedVariableInNotLastInBuffer)
637
{
638
const std::string &source =
639
R"(#version 310 es
640
641
layout(std430) buffer buf
642
{
643
int arr[];
644
int i;
645
};
646
647
void main()
648
{
649
})";
650
if (compile(source))
651
{
652
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
653
}
654
}
655
656
// Test that memory qualifiers are output.
657
TEST_F(BufferVariablesMatchTest, MemoryQualifiers)
658
{
659
const std::string &source =
660
R"(#version 310 es
661
662
layout(std430) coherent buffer buf
663
{
664
int defaultCoherent;
665
coherent ivec2 specifiedCoherent;
666
volatile ivec3 specifiedVolatile;
667
restrict ivec4 specifiedRestrict;
668
readonly float specifiedReadOnly;
669
writeonly vec2 specifiedWriteOnly;
670
volatile readonly vec3 specifiedMultiple;
671
};
672
673
void main()
674
{
675
})";
676
compile(source);
677
ASSERT_TRUE(foundInESSLCode("coherent highp int"));
678
ASSERT_TRUE(foundInESSLCode("coherent highp ivec2"));
679
ASSERT_TRUE(foundInESSLCode("coherent volatile highp ivec3"));
680
ASSERT_TRUE(foundInESSLCode("coherent restrict highp ivec4"));
681
ASSERT_TRUE(foundInESSLCode("readonly coherent highp float"));
682
ASSERT_TRUE(foundInESSLCode("writeonly coherent highp vec2"));
683
ASSERT_TRUE(foundInESSLCode("readonly coherent volatile highp vec3"));
684
}
685
686