Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/compiler_tests/GeometryShader_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
// GeometryShader_test.cpp:
7
// tests for compiling a Geometry Shader
8
//
9
10
#include "GLSLANG/ShaderLang.h"
11
#include "angle_gl.h"
12
#include "compiler/translator/BaseTypes.h"
13
#include "gtest/gtest.h"
14
#include "tests/test_utils/ShaderCompileTreeTest.h"
15
#include "tests/test_utils/compiler_test.h"
16
17
using namespace sh;
18
19
class GeometryShaderTest : public ShaderCompileTreeTest
20
{
21
public:
22
GeometryShaderTest() {}
23
24
protected:
25
void initResources(ShBuiltInResources *resources) override
26
{
27
resources->EXT_geometry_shader = 1;
28
}
29
30
::GLenum getShaderType() const override { return GL_GEOMETRY_SHADER_EXT; }
31
32
ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
33
34
bool compileGeometryShader(const std::string &statement1, const std::string &statement2)
35
{
36
std::ostringstream sstream;
37
sstream << kHeader << statement1 << statement2 << kEmptyBody;
38
return compile(sstream.str());
39
}
40
41
bool compileGeometryShader(const std::string &statement1,
42
const std::string &statement2,
43
const std::string &statement3,
44
const std::string &statement4)
45
{
46
std::ostringstream sstream;
47
sstream << kHeader << statement1 << statement2 << statement3 << statement4 << kEmptyBody;
48
return compile(sstream.str());
49
}
50
51
static std::string GetGeometryShaderLayout(const std::string &layoutType,
52
const std::string &primitive,
53
int invocations,
54
int maxVertices)
55
{
56
std::ostringstream sstream;
57
58
sstream << "layout (";
59
if (!primitive.empty())
60
{
61
sstream << primitive;
62
}
63
if (invocations > 0)
64
{
65
sstream << ", invocations = " << invocations;
66
}
67
if (maxVertices >= 0)
68
{
69
sstream << ", max_vertices = " << maxVertices;
70
}
71
sstream << ") " << layoutType << ";" << std::endl;
72
73
return sstream.str();
74
}
75
76
static std::string GetInputDeclaration(const std::string &var, int size)
77
{
78
std::ostringstream sstream;
79
80
sstream << "in ";
81
if (size < 0)
82
{
83
sstream << var << "[];\n";
84
}
85
else
86
{
87
sstream << var << "[" << size << "];\n";
88
}
89
90
return sstream.str();
91
}
92
93
const std::string kVersion = "#version 310 es\n";
94
const std::string kHeader =
95
"#version 310 es\n"
96
"#extension GL_EXT_geometry_shader : require\n";
97
const std::string kInputLayout = "layout (points) in;\n";
98
const std::string kOutputLayout = "layout (points, max_vertices = 1) out;\n";
99
100
const std::array<std::string, 4> kInterpolationQualifiers = {{"flat", "smooth", "centroid"}};
101
const std::map<std::string, int> kInputPrimitivesAndInputArraySizeMap = {
102
{"points", 1},
103
{"lines", 2},
104
{"lines_adjacency", 4},
105
{"triangles", 3},
106
{"triangles_adjacency", 6}};
107
108
const std::string kEmptyBody =
109
"void main()\n"
110
"{\n"
111
"}\n";
112
};
113
114
class GeometryShaderOutputCodeTest : public MatchOutputCodeTest
115
{
116
public:
117
GeometryShaderOutputCodeTest()
118
: MatchOutputCodeTest(GL_GEOMETRY_SHADER_EXT, SH_OBJECT_CODE, SH_ESSL_OUTPUT)
119
{
120
getResources()->EXT_geometry_shader = 1;
121
}
122
};
123
124
// Geometry Shaders are not supported in GLSL ES shaders version lower than 310.
125
TEST_F(GeometryShaderTest, Version300)
126
{
127
const std::string &shaderString =
128
R"(#version 300 es
129
void main()
130
{
131
})";
132
133
if (compile(shaderString))
134
{
135
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
136
}
137
}
138
139
// Geometry Shaders are not supported in GLSL ES shaders version 310 without extension
140
// EXT_geometry_shader enabled.
141
TEST_F(GeometryShaderTest, Version310WithoutExtension)
142
{
143
const std::string &shaderString =
144
R"(#version 310 es
145
void main()
146
{
147
})";
148
149
if (compile(shaderString))
150
{
151
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
152
}
153
}
154
155
// Geometry Shaders are not supported in GLSL ES shaders version 310 with extension
156
// EXT_geometry_shader disabled.
157
TEST_F(GeometryShaderTest, Version310ExtensionDisabled)
158
{
159
const std::string &shaderString =
160
R"(#version 310 es
161
#extension GL_EXT_geometry_shader : disable
162
void main()
163
{
164
})";
165
166
if (compile(shaderString))
167
{
168
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
169
}
170
}
171
172
// Geometry Shaders are supported in GLSL ES shaders version 310 with EXT_geometry_shader enabled.
173
TEST_F(GeometryShaderTest, Version310WithEXTExtension)
174
{
175
const std::string &shaderString =
176
R"(#version 310 es
177
#extension GL_EXT_geometry_shader : require
178
layout(points) in;
179
layout(points, max_vertices = 1) out;
180
void main()
181
{
182
})";
183
184
if (!compile(shaderString))
185
{
186
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
187
}
188
}
189
190
// Missing the declaration of input primitive in a geometry shader should be a link error instead of
191
// a compile error.
192
TEST_F(GeometryShaderTest, NoInputPrimitives)
193
{
194
const std::string &shaderString =
195
R"(#version 310 es
196
#extension GL_EXT_geometry_shader : require
197
layout(points, max_vertices = 1) out;
198
void main()
199
{
200
})";
201
202
if (!compile(shaderString))
203
{
204
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
205
}
206
}
207
208
// Geometry Shaders can only support 5 kinds of input primitives, which cannot be used as output
209
// primitives except 'points'.
210
// Skip testing "points" as it can be used as both input and output primitives.
211
TEST_F(GeometryShaderTest, ValidInputPrimitives)
212
{
213
const std::array<std::string, 4> kInputPrimitives = {
214
{"lines", "lines_adjacency", "triangles", "triangles_adjacency"}};
215
216
for (const std::string &inputPrimitive : kInputPrimitives)
217
{
218
if (!compileGeometryShader(GetGeometryShaderLayout("in", inputPrimitive, -1, -1),
219
kOutputLayout))
220
{
221
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
222
}
223
if (compileGeometryShader(kInputLayout,
224
GetGeometryShaderLayout("out", inputPrimitive, -1, 6)))
225
{
226
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
227
}
228
}
229
}
230
231
// Geometry Shaders allow duplicated declaration of input primitive, but all of them must be same.
232
TEST_F(GeometryShaderTest, RedeclareInputPrimitives)
233
{
234
const std::array<std::string, 5> kInputPrimitives = {
235
{"points", "lines", "lines_adjacency", "triangles", "triangles_adjacency"}};
236
237
for (GLuint i = 0; i < kInputPrimitives.size(); ++i)
238
{
239
const std::string &inputLayoutStr1 =
240
GetGeometryShaderLayout("in", kInputPrimitives[i], -1, -1);
241
if (!compileGeometryShader(inputLayoutStr1, inputLayoutStr1, kOutputLayout, ""))
242
{
243
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
244
}
245
246
for (GLuint j = i + 1; j < kInputPrimitives.size(); ++j)
247
{
248
const std::string &inputLayoutStr2 =
249
GetGeometryShaderLayout("in", kInputPrimitives[j], -1, -1);
250
if (compileGeometryShader(inputLayoutStr1, inputLayoutStr2, kOutputLayout, ""))
251
{
252
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
253
}
254
}
255
}
256
}
257
258
// Geometry Shaders don't allow declaring different input primitives in one layout.
259
TEST_F(GeometryShaderTest, DeclareDifferentInputPrimitivesInOneLayout)
260
{
261
const std::string &shaderString =
262
R"(#version 310 es
263
#extension GL_EXT_geometry_shader : require
264
layout (points, triangles) in;
265
layout (points, max_vertices = 1) out;
266
void main()
267
{
268
})";
269
270
if (compile(shaderString))
271
{
272
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
273
}
274
}
275
276
// Geometry Shaders don't allow 'invocations' < 1.
277
TEST_F(GeometryShaderTest, InvocationsLessThanOne)
278
{
279
const std::string &shaderString =
280
R"(#version 310 es
281
#extension GL_EXT_geometry_shader : require
282
layout (points, invocations = 0) in;
283
layout (points, max_vertices = 1) out;
284
void main()
285
{
286
})";
287
288
if (compile(shaderString))
289
{
290
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
291
}
292
}
293
294
// Geometry Shaders allow declaring 'invocations' == 1 together with input primitive declaration in
295
// one layout.
296
TEST_F(GeometryShaderTest, InvocationsEqualsOne)
297
{
298
const std::string &shaderString =
299
R"(#version 310 es
300
#extension GL_EXT_geometry_shader : require
301
layout (points, invocations = 1) in;
302
layout (points, max_vertices = 1) out;
303
void main()
304
{
305
})";
306
307
if (!compile(shaderString))
308
{
309
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
310
}
311
}
312
313
// Geometry Shaders allow declaring 'invocations' == 1 in an individual layout.
314
TEST_F(GeometryShaderTest, InvocationsEqualsOneInSeparatedLayout)
315
{
316
const std::string &shaderString =
317
R"(#version 310 es
318
#extension GL_EXT_geometry_shader : require
319
layout (points) in;
320
layout (invocations = 1) in;
321
layout (points, max_vertices = 1) out;
322
void main()
323
{
324
})";
325
326
if (!compile(shaderString))
327
{
328
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
329
}
330
}
331
332
// Geometry Shaders don't allow 'invocations' larger than the implementation-dependent maximum value
333
// (32 in this test).
334
TEST_F(GeometryShaderTest, TooLargeInvocations)
335
{
336
const std::string &shaderString =
337
R"(#version 310 es
338
#extension GL_EXT_geometry_shader : require
339
layout (points, invocations = 9989899) in;
340
layout (points, max_vertices = 1) out;
341
void main()
342
{
343
})";
344
345
if (compile(shaderString))
346
{
347
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
348
}
349
}
350
351
// Geometry Shaders allow 'invocations' declared together with input primitives in one layout.
352
TEST_F(GeometryShaderTest, InvocationsDeclaredWithInputPrimitives)
353
{
354
const std::string &shaderString =
355
R"(#version 310 es
356
#extension GL_EXT_geometry_shader : require
357
layout (points, invocations = 3) in;
358
layout (points, max_vertices = 1) out;
359
void main()
360
{
361
})";
362
363
if (!compile(shaderString))
364
{
365
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
366
}
367
}
368
369
// Geometry Shaders allow 'invocations' declared before input primitives in one input layout.
370
TEST_F(GeometryShaderTest, InvocationsBeforeInputPrimitives)
371
{
372
const std::string &shaderString =
373
R"(#version 310 es
374
#extension GL_EXT_geometry_shader : require
375
layout (invocations = 3, points) in;
376
layout (points, max_vertices = 1) out;
377
void main()
378
{
379
})";
380
381
if (!compile(shaderString))
382
{
383
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
384
}
385
}
386
387
// Geometry Shaders allow 'invocations' declared in an individual input layout.
388
TEST_F(GeometryShaderTest, InvocationsInIndividualLayout)
389
{
390
const std::string &shaderString =
391
R"(#version 310 es
392
#extension GL_EXT_geometry_shader : require
393
layout (points) in;
394
layout (invocations = 3) in;
395
layout (points, max_vertices = 1) out;
396
void main()
397
{
398
})";
399
400
if (!compile(shaderString))
401
{
402
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
403
}
404
}
405
406
// Geometry Shaders allow duplicated 'invocations' declarations.
407
TEST_F(GeometryShaderTest, DuplicatedInvocations)
408
{
409
const std::string &shaderString =
410
R"(#version 310 es
411
#extension GL_EXT_geometry_shader : require
412
layout (points, invocations = 3) in;
413
layout (invocations = 3) in;
414
layout (points, max_vertices = 1) out;
415
void main()
416
{
417
})";
418
419
if (!compile(shaderString))
420
{
421
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
422
}
423
}
424
425
// Geometry Shaders don't allow multiple different 'invocations' declarations in different
426
// layouts.
427
TEST_F(GeometryShaderTest, RedeclareDifferentInvocations)
428
{
429
const std::string &shaderString =
430
R"(#version 310 es
431
#extension GL_EXT_geometry_shader : require
432
layout (points, invocations = 3) in;
433
layout (invocations = 5) in;
434
layout (points, max_vertices = 1) out;
435
void main()
436
{
437
})";
438
439
if (compile(shaderString))
440
{
441
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
442
}
443
}
444
445
// Geometry Shaders don't allow multiple different 'invocations' declarations in different
446
// layouts.
447
TEST_F(GeometryShaderTest, RedeclareDifferentInvocationsAfterInvocationEqualsOne)
448
{
449
const std::string &shaderString =
450
R"(#version 310 es
451
#extension GL_EXT_geometry_shader : require
452
layout (points, invocations = 1) in;
453
layout (invocations = 5) in;
454
layout (points, max_vertices = 1) out;
455
void main()
456
{
457
})";
458
459
if (compile(shaderString))
460
{
461
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
462
}
463
}
464
465
// Geometry Shaders don't allow multiple different 'invocations' declarations in one layout.
466
TEST_F(GeometryShaderTest, RedeclareDifferentInvocationsInOneLayout)
467
{
468
const std::string &shaderString =
469
R"(#version 310 es
470
#extension GL_EXT_geometry_shader : require
471
layout (points, invocations = 3, invocations = 5) in;
472
layout (points, max_vertices = 1) out;
473
void main()
474
{
475
})";
476
477
if (compile(shaderString))
478
{
479
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
480
}
481
}
482
483
// Geometry Shaders don't allow 'invocations' in out layouts.
484
TEST_F(GeometryShaderTest, DeclareInvocationsInOutLayout)
485
{
486
const std::string &shaderString =
487
R"(#version 310 es
488
#extension GL_EXT_geometry_shader : require
489
layout (points) in;
490
layout (points, invocations = 3, max_vertices = 1) out;
491
void main()
492
{
493
})";
494
495
if (compile(shaderString))
496
{
497
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
498
}
499
}
500
501
// Geometry Shaders don't allow 'invocations' in layouts without 'in' qualifier.
502
TEST_F(GeometryShaderTest, DeclareInvocationsInLayoutNoQualifier)
503
{
504
const std::string &shaderString =
505
R"(#version 310 es
506
#extension GL_EXT_geometry_shader : require
507
layout (points) in;
508
layout (invocations = 3);
509
layout (points, max_vertices = 1) out;
510
void main()
511
{
512
})";
513
514
if (compile(shaderString))
515
{
516
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
517
}
518
}
519
520
// Geometry Shaders allow declaring output primitive before input primitive declaration.
521
TEST_F(GeometryShaderTest, DeclareOutputPrimitiveBeforeInputPrimitiveDeclare)
522
{
523
const std::string &shaderString =
524
R"(#version 310 es
525
#extension GL_EXT_geometry_shader : require
526
layout (points, max_vertices = 1) out;
527
layout (points) in;
528
void main()
529
{
530
})";
531
532
if (!compile(shaderString))
533
{
534
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
535
}
536
}
537
538
// Geometry Shaders allow declaring 'max_vertices' before output primitive in one output layout.
539
TEST_F(GeometryShaderTest, DeclareMaxVerticesBeforeOutputPrimitive)
540
{
541
const std::string &shaderString =
542
R"(#version 310 es
543
#extension GL_EXT_geometry_shader : require
544
layout (points) in;
545
layout (max_vertices = 1, points) out;
546
void main()
547
{
548
})";
549
550
if (!compile(shaderString))
551
{
552
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
553
}
554
}
555
556
// Missing the declaration of output primitive should be a link error instead of a compile error in
557
// a geometry shader.
558
TEST_F(GeometryShaderTest, NoOutputPrimitives)
559
{
560
const std::string &shaderString =
561
R"(#version 310 es
562
#extension GL_EXT_geometry_shader : require
563
layout (points) in;
564
layout (max_vertices = 1) out;
565
void main()
566
{
567
})";
568
569
if (!compile(shaderString))
570
{
571
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
572
}
573
}
574
575
// Geometry Shaders can only support 3 kinds of output primitives, which cannot be used as input
576
// primitives except 'points'.
577
// Skip testing "points" as it can be used as both input and output primitives.
578
TEST_F(GeometryShaderTest, ValidateOutputPrimitives)
579
{
580
const std::string outputPrimitives[] = {"line_strip", "triangle_strip"};
581
582
for (const std::string &outPrimitive : outputPrimitives)
583
{
584
if (!compileGeometryShader(kInputLayout,
585
GetGeometryShaderLayout("out", outPrimitive, -1, 6)))
586
{
587
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
588
}
589
590
if (compileGeometryShader(GetGeometryShaderLayout("in", outPrimitive, -1, -1),
591
kOutputLayout))
592
{
593
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
594
}
595
}
596
}
597
598
// Geometry Shaders allow duplicated output primitive declarations, but all of them must be same.
599
TEST_F(GeometryShaderTest, RedeclareOutputPrimitives)
600
{
601
const std::array<std::string, 3> outPrimitives = {{"points", "line_strip", "triangle_strip"}};
602
603
for (GLuint i = 0; i < outPrimitives.size(); i++)
604
{
605
constexpr int maxVertices = 1;
606
const std::string &outputLayoutStr1 =
607
GetGeometryShaderLayout("out", outPrimitives[i], -1, maxVertices);
608
const std::string &outputLayoutStr2 =
609
GetGeometryShaderLayout("out", outPrimitives[i], -1, -1);
610
if (!compileGeometryShader(kInputLayout, outputLayoutStr1, outputLayoutStr2, ""))
611
{
612
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
613
}
614
for (GLuint j = i + 1; j < outPrimitives.size(); j++)
615
{
616
const std::string &outputLayoutStr3 =
617
GetGeometryShaderLayout("out", outPrimitives[j], -1, -1);
618
if (compileGeometryShader(kInputLayout, outputLayoutStr1, outputLayoutStr3, ""))
619
{
620
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
621
}
622
}
623
}
624
}
625
626
// Geometry Shaders don't allow declaring different output primitives in one layout.
627
TEST_F(GeometryShaderTest, RedeclareDifferentOutputPrimitivesInOneLayout)
628
{
629
const std::string &shaderString =
630
R"(#version 310 es
631
#extension GL_EXT_geometry_shader : require
632
layout (points) in;
633
layout (points, max_vertices = 3, line_strip) out;
634
void main()
635
{
636
})";
637
638
if (compile(shaderString))
639
{
640
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
641
}
642
}
643
644
// Missing the declarations of output primitives and 'max_vertices' in a geometry shader should
645
// be a link error instead of a compile error.
646
TEST_F(GeometryShaderTest, NoOutLayouts)
647
{
648
const std::string &shaderString =
649
R"(#version 310 es
650
#extension GL_EXT_geometry_shader : require
651
layout (points) in;
652
void main()
653
{
654
})";
655
656
if (!compile(shaderString))
657
{
658
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
659
}
660
}
661
662
// Missing the declarations of 'max_vertices' in a geometry shader should be a link error
663
// instead of a compile error.
664
TEST_F(GeometryShaderTest, NoMaxVertices)
665
{
666
const std::string &shaderString =
667
R"(#version 310 es
668
#extension GL_EXT_geometry_shader : require
669
layout (points) in;
670
layout (points) out;
671
void main()
672
{
673
})";
674
675
if (!compile(shaderString))
676
{
677
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
678
}
679
}
680
681
// Geometry Shaders cannot declare a negative 'max_vertices'.
682
TEST_F(GeometryShaderTest, NegativeMaxVertices)
683
{
684
const std::string &shaderString =
685
R"(#version 310 es
686
#extension GL_EXT_geometry_shader : require
687
layout (points) in;
688
layout (points, max_vertices = -1) out;
689
void main()
690
{
691
})";
692
693
if (compile(shaderString))
694
{
695
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
696
}
697
}
698
699
// Geometry Shaders allow max_vertices == 0.
700
TEST_F(GeometryShaderTest, ZeroMaxVertices)
701
{
702
const std::string &shaderString =
703
R"(#version 310 es
704
#extension GL_EXT_geometry_shader : require
705
layout (points) in;
706
layout (points, max_vertices = 0) out;
707
void main()
708
{
709
})";
710
711
if (!compile(shaderString))
712
{
713
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
714
}
715
}
716
717
// Geometry Shaders cannot declare a 'max_vertices' that is greater than
718
// MAX_GEOMETRY_OUTPUT_VERTICES_EXT (256 in this test).
719
TEST_F(GeometryShaderTest, TooLargeMaxVertices)
720
{
721
const std::string &shaderString =
722
R"(#version 310 es
723
#extension GL_EXT_geometry_shader : require
724
layout (points) in;
725
layout (points, max_vertices = 257) out;
726
void main()
727
{
728
})";
729
730
if (compile(shaderString))
731
{
732
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
733
}
734
}
735
736
// Geometry Shaders can declare 'max_vertices' in an individual out layout.
737
TEST_F(GeometryShaderTest, MaxVerticesInIndividualLayout)
738
{
739
const std::string &shaderString =
740
R"(#version 310 es
741
#extension GL_EXT_geometry_shader : require
742
layout (points) in;
743
layout (points) out;
744
layout (max_vertices = 1) out;
745
void main()
746
{
747
})";
748
749
if (!compile(shaderString))
750
{
751
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
752
}
753
}
754
755
// Geometry Shaders allow duplicated 'max_vertices' declarations.
756
TEST_F(GeometryShaderTest, DuplicatedMaxVertices)
757
{
758
const std::string &shaderString =
759
R"(#version 310 es
760
#extension GL_EXT_geometry_shader : require
761
layout (points) in;
762
layout (points, max_vertices = 1) out;
763
layout (max_vertices = 1) out;
764
void main()
765
{
766
})";
767
768
if (!compile(shaderString))
769
{
770
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
771
}
772
}
773
774
// Geometry Shaders don't allow declaring different 'max_vertices'.
775
TEST_F(GeometryShaderTest, RedeclareDifferentMaxVertices)
776
{
777
const std::string &shaderString =
778
R"(#version 310 es
779
#extension GL_EXT_geometry_shader : require
780
layout (points) in;
781
layout (points, max_vertices = 1) out;
782
layout (max_vertices = 2) out;
783
void main()
784
{
785
})";
786
787
if (compile(shaderString))
788
{
789
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
790
}
791
}
792
793
// Geometry Shaders don't allow declaring different 'max_vertices'.
794
TEST_F(GeometryShaderTest, RedeclareDifferentMaxVerticesInOneLayout)
795
{
796
const std::string &shaderString =
797
R"(#version 310 es
798
#extension GL_EXT_geometry_shader : require
799
layout (points) in;
800
layout (points, max_vertices = 2, max_vertices = 1) out;
801
void main()
802
{
803
})";
804
805
if (compile(shaderString))
806
{
807
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
808
}
809
}
810
811
// Geometry Shaders don't allow 'location' declared with input/output primitives in one layout.
812
TEST_F(GeometryShaderTest, InvalidLocation)
813
{
814
const std::string &shaderString1 =
815
R"(#version 310 es
816
#extension GL_EXT_geometry_shader : require
817
layout (points, location = 1) in;
818
layout (points, max_vertices = 2) out;
819
void main()
820
{
821
})";
822
823
const std::string &shaderString2 =
824
R"(#version 310 es
825
#extension GL_EXT_geometry_shader : require
826
layout (points) in;
827
layout (invocations = 2, location = 1) in;
828
layout (points, max_vertices = 2) out;
829
void main()
830
{
831
})";
832
833
const std::string &shaderString3 =
834
R"(#version 310 es
835
#extension GL_EXT_geometry_shader : require
836
layout (points) in;
837
layout (points, location = 3, max_vertices = 2) out;
838
void main()
839
{
840
})";
841
842
const std::string &shaderString4 =
843
R"(#version 310 es
844
#extension GL_EXT_geometry_shader : require
845
layout (points) in;
846
layout (points) out;
847
layout (max_vertices = 2, location = 3) out;
848
void main()
849
{
850
})";
851
852
if (compile(shaderString1) || compile(shaderString2) || compile(shaderString3) ||
853
compile(shaderString4))
854
{
855
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
856
}
857
}
858
859
// Geometry Shaders don't allow invalid layout qualifier declarations.
860
TEST_F(GeometryShaderTest, InvalidLayoutQualifiers)
861
{
862
const std::string &shaderString1 =
863
R"(#version 310 es
864
#extension GL_EXT_geometry_shader : require
865
layout (points, abc) in;
866
layout (points, max_vertices = 2) out;
867
void main()
868
{
869
})";
870
871
const std::string &shaderString2 =
872
R"(#version 310 es
873
#extension GL_EXT_geometry_shader : require
874
layout (points) in;
875
layout (points, abc, max_vertices = 2) out;
876
void main()
877
{
878
})";
879
880
const std::string &shaderString3 =
881
R"(#version 310 es
882
#extension GL_EXT_geometry_shader : require
883
layout (points, xyz = 2) in;
884
layout (points, max_vertices = 2) out;
885
void main()
886
{
887
})";
888
889
const std::string &shaderString4 =
890
R"(#version 310 es
891
#extension GL_EXT_geometry_shader : require
892
layout (points) in;
893
layout (points) out;
894
layout (max_vertices = 2, xyz = 3) out;
895
void main()
896
{
897
})";
898
899
if (compile(shaderString1) || compile(shaderString2) || compile(shaderString3) ||
900
compile(shaderString4))
901
{
902
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
903
}
904
}
905
906
// Verify that indexing an array with a constant integer on gl_in is legal.
907
TEST_F(GeometryShaderTest, IndexGLInByConstantInteger)
908
{
909
const std::string &shaderString =
910
R"(#version 310 es
911
#extension GL_EXT_geometry_shader : require
912
layout (points) in;
913
layout (points, max_vertices = 2) out;
914
void main()
915
{
916
vec4 position;
917
position = gl_in[0].gl_Position;
918
})";
919
920
if (!compile(shaderString))
921
{
922
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
923
}
924
}
925
926
// Verify that indexing an array with an integer variable on gl_in is legal.
927
TEST_F(GeometryShaderTest, IndexGLInByVariable)
928
{
929
const std::string &shaderString =
930
R"(#version 310 es
931
#extension GL_EXT_geometry_shader : require
932
layout (lines) in;
933
layout (points, max_vertices = 2) out;
934
void main()
935
{
936
vec4 position;
937
for (int i = 0; i < 2; i++)
938
{
939
position = gl_in[i].gl_Position;
940
}
941
})";
942
943
if (!compile(shaderString))
944
{
945
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
946
}
947
}
948
949
// Verify that indexing an array on gl_in without input primitive declaration causes a compile
950
// error.
951
TEST_F(GeometryShaderTest, IndexGLInWithoutInputPrimitive)
952
{
953
const std::string &shaderString =
954
R"(#version 310 es
955
#extension GL_EXT_geometry_shader : require
956
layout (points, max_vertices = 2) out;
957
void main()
958
{
959
vec4 position = gl_in[0].gl_Position;
960
})";
961
962
if (compile(shaderString))
963
{
964
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
965
}
966
}
967
968
// Verify that using gl_in.length() without input primitive declaration causes a compile error.
969
TEST_F(GeometryShaderTest, UseGLInLengthWithoutInputPrimitive)
970
{
971
const std::string &shaderString =
972
R"(#version 310 es
973
#extension GL_EXT_geometry_shader : require
974
layout (points, max_vertices = 2) out;
975
void main()
976
{
977
int length = gl_in.length();
978
})";
979
980
if (compile(shaderString))
981
{
982
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
983
}
984
}
985
986
// Verify that using gl_in.length() with input primitive declaration can compile.
987
TEST_F(GeometryShaderTest, UseGLInLengthWithInputPrimitive)
988
{
989
const std::string &shaderString =
990
R"(#version 310 es
991
#extension GL_EXT_geometry_shader : require
992
layout (points) in;
993
layout (points, max_vertices = 2) out;
994
void main()
995
{
996
gl_Position = vec4(gl_in.length());
997
EmitVertex();
998
})";
999
1000
if (!compile(shaderString))
1001
{
1002
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1003
}
1004
}
1005
1006
// Verify that gl_in[].gl_Position cannot be l-value.
1007
TEST_F(GeometryShaderTest, AssignValueToGLIn)
1008
{
1009
const std::string &shaderString =
1010
R"(#version 310 es
1011
#extension GL_EXT_geometry_shader : require
1012
layout (points) in;
1013
layout (points, max_vertices = 2) out;
1014
void main()
1015
{
1016
gl_in[0].gl_Position = vec4(0, 0, 0, 1);
1017
})";
1018
if (compile(shaderString))
1019
{
1020
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1021
}
1022
}
1023
1024
// Verify Geometry Shader supports all required built-in variables.
1025
TEST_F(GeometryShaderTest, BuiltInVariables)
1026
{
1027
const std::string &shaderString =
1028
R"(#version 310 es
1029
#extension GL_EXT_geometry_shader : require
1030
layout (points, invocations = 2) in;
1031
layout (points, max_vertices = 2) out;
1032
void main()
1033
{
1034
gl_Position = gl_in[gl_InvocationID].gl_Position;
1035
int invocation = gl_InvocationID;
1036
gl_Layer = invocation;
1037
int primitiveIn = gl_PrimitiveIDIn;
1038
gl_PrimitiveID = primitiveIn;
1039
})";
1040
if (!compile(shaderString))
1041
{
1042
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1043
}
1044
}
1045
1046
// Verify that gl_PrimitiveIDIn cannot be l-value.
1047
TEST_F(GeometryShaderTest, AssignValueToGLPrimitiveIn)
1048
{
1049
const std::string &shaderString =
1050
R"(#version 310 es
1051
#extension GL_EXT_geometry_shader : require
1052
layout (points, invocations = 2) in;
1053
layout (points, max_vertices = 2) out;
1054
void main()
1055
{
1056
gl_PrimitiveIDIn = 1;
1057
})";
1058
if (compile(shaderString))
1059
{
1060
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1061
}
1062
}
1063
1064
// Verify that gl_InvocationID cannot be l-value.
1065
TEST_F(GeometryShaderTest, AssignValueToGLInvocations)
1066
{
1067
const std::string &shaderString =
1068
R"(#version 310 es
1069
#extension GL_EXT_geometry_shader : require
1070
layout (points, invocations = 2) in;
1071
layout (points, max_vertices = 2) out;
1072
void main()
1073
{
1074
gl_InvocationID = 1;
1075
})";
1076
if (compile(shaderString))
1077
{
1078
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1079
}
1080
}
1081
1082
// Verify that both EmitVertex() and EndPrimitive() are supported in Geometry Shader.
1083
TEST_F(GeometryShaderTest, GeometryShaderBuiltInFunctions)
1084
{
1085
const std::string &shaderString =
1086
R"(#version 310 es
1087
#extension GL_EXT_geometry_shader : require
1088
layout (points) in;
1089
layout (points, max_vertices = 2) out;
1090
void main()
1091
{
1092
gl_Position = gl_in[0].gl_Position;
1093
EmitVertex();
1094
EndPrimitive();
1095
})";
1096
1097
if (!compile(shaderString))
1098
{
1099
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1100
}
1101
}
1102
1103
// Verify that using EmitVertex() or EndPrimitive() without GL_EXT_geometry_shader declared causes a
1104
// compile error.
1105
TEST_F(GeometryShaderTest, GeometryShaderBuiltInFunctionsWithoutExtension)
1106
{
1107
const std::string &shaderString1 =
1108
R"(#version 310 es
1109
void main()
1110
{
1111
EmitVertex();
1112
})";
1113
1114
const std::string &shaderString2 =
1115
R"(#version 310 es
1116
void main()
1117
{
1118
EndPrimitive();
1119
})";
1120
1121
if (compile(shaderString1) || compile(shaderString2))
1122
{
1123
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1124
}
1125
}
1126
1127
// Verify that all required built-in constant values are supported in Geometry Shaders
1128
TEST_F(GeometryShaderTest, GeometryShaderBuiltInConstants)
1129
{
1130
const std::string &kShaderHeader =
1131
R"(#version 310 es
1132
#extension GL_EXT_geometry_shader : require
1133
layout (points) in;
1134
layout (points, max_vertices = 2) out;
1135
void main()
1136
{
1137
gl_Position.x = float()";
1138
1139
const std::array<std::string, 9> kGeometryShaderBuiltinConstants = {{
1140
"gl_MaxGeometryInputComponents",
1141
"gl_MaxGeometryOutputComponents",
1142
"gl_MaxGeometryImageUniforms",
1143
"gl_MaxGeometryTextureImageUnits",
1144
"gl_MaxGeometryOutputVertices",
1145
"gl_MaxGeometryTotalOutputComponents",
1146
"gl_MaxGeometryUniformComponents",
1147
"gl_MaxGeometryAtomicCounters",
1148
"gl_MaxGeometryAtomicCounterBuffers",
1149
}};
1150
1151
const std::string &kShaderTail =
1152
R"();
1153
EmitVertex();
1154
})";
1155
1156
for (const std::string &kGSBuiltinConstant : kGeometryShaderBuiltinConstants)
1157
{
1158
std::ostringstream ostream;
1159
ostream << kShaderHeader << kGSBuiltinConstant << kShaderTail;
1160
if (!compile(ostream.str()))
1161
{
1162
FAIL() << "Shader compilation failed, expecting success: \n" << mInfoLog;
1163
}
1164
}
1165
}
1166
1167
// Verify that using any Geometry Shader built-in constant values without GL_EXT_geometry_shader
1168
// declared causes a compile error.
1169
TEST_F(GeometryShaderTest, GeometryShaderBuiltInConstantsWithoutExtension)
1170
{
1171
const std::string &kShaderHeader =
1172
"#version 310 es\n"
1173
"void main()\n"
1174
"{\n"
1175
" int val = ";
1176
1177
const std::array<std::string, 9> kGeometryShaderBuiltinConstants = {{
1178
"gl_MaxGeometryInputComponents",
1179
"gl_MaxGeometryOutputComponents",
1180
"gl_MaxGeometryImageUniforms",
1181
"gl_MaxGeometryTextureImageUnits",
1182
"gl_MaxGeometryOutputVertices",
1183
"gl_MaxGeometryTotalOutputComponents",
1184
"gl_MaxGeometryUniformComponents",
1185
"gl_MaxGeometryAtomicCounters",
1186
"gl_MaxGeometryAtomicCounterBuffers",
1187
}};
1188
1189
const std::string &kShaderTail =
1190
";\n"
1191
"}\n";
1192
1193
for (const std::string &kGSBuiltinConstant : kGeometryShaderBuiltinConstants)
1194
{
1195
std::ostringstream ostream;
1196
ostream << kShaderHeader << kGSBuiltinConstant << kShaderTail;
1197
if (compile(ostream.str()))
1198
{
1199
FAIL() << "Shader compilation succeeded, expecting failure: \n" << mInfoLog;
1200
}
1201
}
1202
}
1203
1204
// Verify that Geometry Shaders cannot accept non-array inputs.
1205
TEST_F(GeometryShaderTest, NonArrayInput)
1206
{
1207
const std::string &shaderString =
1208
R"(#version 310 es
1209
#extension GL_EXT_geometry_shader : require
1210
layout (points) in;
1211
layout (points, max_vertices = 1) out;
1212
in vec4 texcoord;
1213
void main()
1214
{
1215
})";
1216
1217
if (compile(shaderString))
1218
{
1219
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1220
}
1221
}
1222
1223
// Verify that it is a compile error to declare an unsized Geometry Shader input before a valid
1224
// input primitive declaration.
1225
TEST_F(GeometryShaderTest, DeclareUnsizedInputBeforeInputPrimitive)
1226
{
1227
const std::string &shaderString1 =
1228
R"(#version 310 es
1229
#extension GL_EXT_geometry_shader : require
1230
in vec4 texcoord[];
1231
layout (points) in;
1232
layout (points, max_vertices = 1) out;
1233
void main()
1234
{
1235
vec4 coord = texcoord[0];
1236
int length = texcoord.length();
1237
})";
1238
1239
const std::string &shaderString2 =
1240
R"(#version 310 es
1241
#extension GL_EXT_geometry_shader : require
1242
in vec4 texcoord1[1];
1243
in vec4 texcoord2[];
1244
layout (points) in;
1245
layout (points, max_vertices = 1) out;
1246
void main()
1247
{
1248
vec4 coord = texcoord2[0];
1249
int length = texcoord2.length();
1250
})";
1251
1252
if (compile(shaderString1) || compile(shaderString2))
1253
{
1254
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1255
}
1256
}
1257
1258
// Verify that it is a compile error to declare an unsized Geometry Shader input without a valid
1259
// input primitive declaration.
1260
TEST_F(GeometryShaderTest, DeclareUnsizedInputWithoutInputPrimitive)
1261
{
1262
const std::string &shaderString1 =
1263
R"(#version 310 es
1264
#extension GL_EXT_geometry_shader : require
1265
layout (points, max_vertices = 1) out;
1266
in vec4 texcoord[];
1267
void main()
1268
{
1269
})";
1270
1271
const std::string &shaderString2 =
1272
R"(#version 310 es
1273
#extension GL_EXT_geometry_shader : require
1274
layout (points, max_vertices = 1) out;
1275
in vec4 texcoord1[1];
1276
in vec4 texcoord2[];
1277
void main()
1278
{
1279
})";
1280
1281
if (compile(shaderString1) || compile(shaderString2))
1282
{
1283
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1284
}
1285
}
1286
1287
// Verify that indexing an unsized Geometry Shader input which is declared after a
1288
// valid input primitive declaration can compile.
1289
TEST_F(GeometryShaderTest, IndexingUnsizedInputDeclaredAfterInputPrimitive)
1290
{
1291
const std::string &shaderString =
1292
R"(#version 310 es
1293
#extension GL_EXT_geometry_shader : require
1294
layout (points) in;
1295
layout (points, max_vertices = 1) out;
1296
in vec4 texcoord[], texcoord2[];
1297
in vec4[] texcoord3, texcoord4;
1298
void main()
1299
{
1300
gl_Position = texcoord[0] + texcoord2[0] + texcoord3[0] + texcoord4[0];
1301
EmitVertex();
1302
})";
1303
1304
if (!compile(shaderString))
1305
{
1306
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1307
}
1308
}
1309
1310
// Verify that calling length() function on an unsized Geometry Shader input which
1311
// is declared before a valid input primitive declaration can compile.
1312
TEST_F(GeometryShaderTest, CallingLengthOnUnsizedInputDeclaredAfterInputPrimitive)
1313
{
1314
const std::string &shaderString =
1315
R"(#version 310 es
1316
#extension GL_EXT_geometry_shader : require
1317
layout (points) in;
1318
layout (points, max_vertices = 1) out;
1319
in vec4 texcoord[];
1320
void main()
1321
{
1322
gl_Position = vec4(texcoord.length());
1323
EmitVertex();
1324
})";
1325
1326
if (!compile(shaderString))
1327
{
1328
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1329
}
1330
}
1331
1332
// Verify that assigning a value to the input of a geometry shader causes a compile error.
1333
TEST_F(GeometryShaderTest, AssignValueToInput)
1334
{
1335
const std::string &shaderString =
1336
R"(#version 310 es
1337
#extension GL_EXT_geometry_shader : require
1338
layout (points) in;
1339
layout (points, max_vertices = 1) out;
1340
in vec4 texcoord[];
1341
void main()
1342
{
1343
texcoord[0] = vec4(1.0, 0.0, 0.0, 1.0);
1344
})";
1345
1346
if (compile(shaderString))
1347
{
1348
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1349
}
1350
}
1351
1352
// Geometry Shaders allow inputs with location qualifier.
1353
TEST_F(GeometryShaderTest, InputWithLocations)
1354
{
1355
const std::string &shaderString =
1356
R"(#version 310 es
1357
#extension GL_EXT_geometry_shader : require
1358
layout (triangles) in;
1359
layout (points, max_vertices = 1) out;
1360
layout (location = 0) in vec4 texcoord1[];
1361
layout (location = 1) in vec4 texcoord2[];
1362
void main()
1363
{
1364
int index = 0;
1365
vec4 coord1 = texcoord1[0];
1366
vec4 coord2 = texcoord2[index];
1367
gl_Position = coord1 + coord2;
1368
})";
1369
1370
if (!compile(shaderString))
1371
{
1372
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1373
}
1374
}
1375
1376
// Geometry Shaders allow inputs with explicit size declared before the declaration of the
1377
// input primitive, but they should have same size and match the declaration of the
1378
// following input primitive declarations.
1379
TEST_F(GeometryShaderTest, InputWithSizeBeforeInputPrimitive)
1380
{
1381
for (auto &primitiveAndArraySize : kInputPrimitivesAndInputArraySizeMap)
1382
{
1383
const std::string &inputLayoutStr =
1384
GetGeometryShaderLayout("in", primitiveAndArraySize.first, -1, -1);
1385
const int inputSize = primitiveAndArraySize.second;
1386
1387
const std::string &inputDeclaration1 = GetInputDeclaration("vec4 input1", inputSize);
1388
if (!compileGeometryShader(inputDeclaration1, "", inputLayoutStr, kOutputLayout))
1389
{
1390
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1391
}
1392
1393
const std::string &inputDeclaration2 = GetInputDeclaration("vec4 input2", inputSize + 1);
1394
if (compileGeometryShader(inputDeclaration2, "", inputLayoutStr, kOutputLayout) ||
1395
compileGeometryShader(inputDeclaration1, inputDeclaration2, inputLayoutStr,
1396
kOutputLayout))
1397
{
1398
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1399
}
1400
}
1401
}
1402
1403
// Geometry shaders allow inputs with explicit size declared after the declaration of the
1404
// input primitive, but their sizes should match the previous input primitive declaration.
1405
TEST_F(GeometryShaderTest, InputWithSizeAfterInputPrimitive)
1406
{
1407
for (auto &primitiveAndArraySize : kInputPrimitivesAndInputArraySizeMap)
1408
{
1409
const std::string &inputLayoutStr =
1410
GetGeometryShaderLayout("in", primitiveAndArraySize.first, -1, -1);
1411
const int inputSize = primitiveAndArraySize.second;
1412
1413
const std::string &inputDeclaration1 = GetInputDeclaration("vec4 input1", inputSize);
1414
if (!compileGeometryShader(inputLayoutStr, kOutputLayout, inputDeclaration1, ""))
1415
{
1416
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1417
}
1418
1419
const std::string &inputDeclaration2 = GetInputDeclaration("vec4 input2", inputSize + 1);
1420
if (compileGeometryShader(inputLayoutStr, kOutputLayout, inputDeclaration2, ""))
1421
{
1422
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1423
}
1424
}
1425
}
1426
1427
// Verify that Geometry Shaders accept non-array outputs.
1428
TEST_F(GeometryShaderTest, NonArrayOutputs)
1429
{
1430
const std::string &shaderString =
1431
R"(#version 310 es
1432
#extension GL_EXT_geometry_shader : require
1433
layout (points) in;
1434
layout (points, max_vertices = 1) out;
1435
out vec4 color;
1436
void main()
1437
{
1438
})";
1439
1440
if (!compile(shaderString))
1441
{
1442
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1443
}
1444
}
1445
1446
// Verify that Geometry Shaders allow declaring outputs with 'location' layout qualifier.
1447
TEST_F(GeometryShaderTest, OutputsWithLocation)
1448
{
1449
const std::string &shaderString =
1450
R"(#version 310 es
1451
#extension GL_EXT_geometry_shader : require
1452
layout (triangles) in;
1453
layout (points, max_vertices = 1) out;
1454
layout (location = 0) out vec4 color1;
1455
layout (location = 1) out vec4 color2;
1456
void main()
1457
{
1458
color1 = vec4(0.0, 1.0, 0.0, 1.0);
1459
color2 = vec4(1.0, 0.0, 0.0, 1.0);
1460
})";
1461
1462
if (!compile(shaderString))
1463
{
1464
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1465
}
1466
}
1467
1468
// Geometry Shaders allow declaring sized array outputs.
1469
TEST_F(GeometryShaderTest, SizedArrayOutputs)
1470
{
1471
const std::string &shaderString =
1472
R"(#version 310 es
1473
#extension GL_EXT_geometry_shader : require
1474
layout (triangles) in;
1475
layout (points, max_vertices = 1) out;
1476
out vec4 color[2];
1477
void main()
1478
{
1479
color[0] = vec4(0.0, 1.0, 0.0, 1.0);
1480
color[1] = vec4(1.0, 0.0, 0.0, 1.0);
1481
})";
1482
1483
if (!compile(shaderString))
1484
{
1485
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1486
}
1487
}
1488
1489
// Verify that Geometry Shader outputs cannot be declared as an unsized array.
1490
TEST_F(GeometryShaderTest, UnsizedArrayOutputs)
1491
{
1492
const std::string &shaderString =
1493
R"(#version 310 es
1494
#extension GL_EXT_geometry_shader : require
1495
layout (triangles) in;
1496
layout (points, max_vertices = 1) out;
1497
out vec4 color[];
1498
void main()
1499
{
1500
})";
1501
1502
if (compile(shaderString))
1503
{
1504
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1505
}
1506
}
1507
1508
// Verify that Geometry Shader inputs can use interpolation qualifiers.
1509
TEST_F(GeometryShaderTest, InputWithInterpolationQualifiers)
1510
{
1511
for (const std::string &qualifier : kInterpolationQualifiers)
1512
{
1513
std::ostringstream stream;
1514
stream << kHeader << kInputLayout << kOutputLayout << qualifier << " in vec4 texcoord[];\n"
1515
<< kEmptyBody;
1516
1517
if (!compile(stream.str()))
1518
{
1519
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1520
}
1521
}
1522
}
1523
1524
// Verify that Geometry Shader outputs can use interpolation qualifiers.
1525
TEST_F(GeometryShaderTest, OutputWithInterpolationQualifiers)
1526
{
1527
for (const std::string &qualifier : kInterpolationQualifiers)
1528
{
1529
std::ostringstream stream;
1530
stream << kHeader << kInputLayout << kOutputLayout << qualifier << " out vec4 color;\n"
1531
<< kEmptyBody;
1532
1533
if (!compile(stream.str()))
1534
{
1535
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1536
}
1537
}
1538
}
1539
1540
// Verify that Geometry Shader outputs can use 'invariant' qualifier.
1541
TEST_F(GeometryShaderTest, InvariantOutput)
1542
{
1543
const std::string &shaderString =
1544
R"(#version 310 es
1545
#extension GL_EXT_geometry_shader : require
1546
layout (points) in;
1547
layout (points, max_vertices = 2) out;
1548
invariant out vec4 gs_output;
1549
void main()
1550
{
1551
gl_Position = gl_in[0].gl_Position;
1552
})";
1553
1554
if (!compile(shaderString))
1555
{
1556
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1557
}
1558
}
1559
1560
// Verify that the member of gl_in won't be incorrectly changed in the output shader string.
1561
TEST_F(GeometryShaderOutputCodeTest, ValidateGLInMembersInOutputShaderString)
1562
{
1563
const std::string &shaderString1 =
1564
R"(#version 310 es
1565
#extension GL_EXT_geometry_shader : require
1566
layout (lines) in;
1567
layout (points, max_vertices = 2) out;
1568
void main()
1569
{
1570
vec4 position;
1571
for (int i = 0; i < 2; i++)
1572
{
1573
position = gl_in[i].gl_Position;
1574
}
1575
})";
1576
1577
compile(shaderString1);
1578
EXPECT_TRUE(foundInESSLCode("].gl_Position"));
1579
1580
const std::string &shaderString2 =
1581
R"(#version 310 es
1582
#extension GL_EXT_geometry_shader : require
1583
layout (points) in;
1584
layout (points, max_vertices = 2) out;
1585
void main()
1586
{
1587
vec4 position;
1588
position = gl_in[0].gl_Position;
1589
})";
1590
1591
compile(shaderString2);
1592
EXPECT_TRUE(foundInESSLCode("].gl_Position"));
1593
}
1594
1595
// Verify that geometry shader inputs can be declared as struct arrays.
1596
TEST_F(GeometryShaderTest, StructArrayInput)
1597
{
1598
const std::string &shaderString =
1599
R"(#version 310 es
1600
#extension GL_EXT_geometry_shader : require
1601
layout (points) in;
1602
layout (points, max_vertices = 2) out;
1603
struct S
1604
{
1605
float value1;
1606
vec4 value2;
1607
};
1608
in S gs_input[];
1609
out S gs_output;
1610
void main()
1611
{
1612
gs_output = gs_input[0];
1613
})";
1614
1615
if (!compile(shaderString))
1616
{
1617
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
1618
}
1619
}
1620
1621
// Verify that geometry shader outputs cannot be declared as struct arrays.
1622
TEST_F(GeometryShaderTest, StructArrayOutput)
1623
{
1624
const std::string &shaderString =
1625
R"(#version 310 es
1626
#extension GL_EXT_geometry_shader : require
1627
layout (points) in;
1628
layout (points, max_vertices = 2) out;
1629
struct S
1630
{
1631
float value1;
1632
vec4 value2;
1633
};
1634
out S gs_output[1];
1635
void main()
1636
{
1637
gs_output[0].value1 = 1.0;
1638
gs_output[0].value2 = vec4(1.0, 0.0, 0.0, 1.0);
1639
})";
1640
1641
if (compile(shaderString))
1642
{
1643
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
1644
}
1645
}
1646
1647