Add flags for all layout qualifiers, check for duplicates

Now, even if a qualifier has a default value, we will know that it
appeared in the text. We can use that to check for redundant qualifiers
(as is being done here), and in the IR generator to prevent any use of
certain qualifiers, depending on context. (eg, runtime effects, wrong
shader stage, on a parameter declaration, etc.)

Bug: skia:11301
Change-Id: I2cd6ad35c2b4c4d6f87ade97e80aea84dc16ee4b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/374616
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
Brian Osman 2021-02-23 12:54:22 -05:00 committed by Skia Commit-Bot
parent 70cd6d1446
commit a77ed8b382
12 changed files with 253 additions and 129 deletions

View File

@ -125,6 +125,8 @@ sksl_error_tests = [
"/sksl/errors/InvalidOutParams.sksl",
"/sksl/errors/InvalidToken.sksl",
"/sksl/errors/InvalidUnary.sksl",
"/sksl/errors/LayoutMultiplePrimitiveTypes.sksl",
"/sksl/errors/LayoutRepeatedQualifiers.sksl",
"/sksl/errors/MismatchedNumbers.sksl",
"/sksl/errors/ModifiersInStruct.sksl",
"/sksl/errors/OpaqueTypeAssignment.sksl",

View File

@ -0,0 +1,8 @@
layout (
points,
lines,
line_strip,
lines_adjacency,
triangles,
triangle_strip
) in;

View File

@ -0,0 +1,41 @@
layout (
origin_upper_left,
override_coverage,
push_constant,
blend_support_all_equations,
tracked,
srgb_unpremul,
key,
location = 1,
offset = 1,
binding = 1,
index = 1,
set = 1,
builtin = 1,
input_attachment_index = 1,
max_vertices = 1,
invocations = 1,
marker = one,
when = one,
ctype = int,
origin_upper_left,
override_coverage,
push_constant,
blend_support_all_equations,
tracked,
srgb_unpremul,
key,
location = 2,
offset = 2,
binding = 2,
index = 2,
set = 2,
builtin = 2,
input_attachment_index = 2,
max_vertices = 2,
invocations = 2,
marker = two,
when = two,
ctype = float
) float x;

View File

@ -891,93 +891,119 @@ Layout Parser::layout() {
for (;;) {
Token t = this->nextToken();
String text = this->text(t);
auto setFlag = [&](Layout::Flag f) {
if (flags & f) {
this->error(t, "layout qualifier '" + text + "' appears more than once");
}
flags |= f;
};
auto setPrimitive = [&](Layout::Primitive p) {
if (flags & Layout::kPrimitive_Flag) {
this->error(t, "only one primitive-type layout qualifier is allowed");
}
flags |= Layout::kPrimitive_Flag;
primitive = p;
};
auto found = layoutTokens->find(text);
if (found != layoutTokens->end()) {
switch (found->second) {
case LayoutToken::ORIGIN_UPPER_LEFT:
setFlag(Layout::kOriginUpperLeft_Flag);
break;
case LayoutToken::OVERRIDE_COVERAGE:
setFlag(Layout::kOverrideCoverage_Flag);
break;
case LayoutToken::PUSH_CONSTANT:
setFlag(Layout::kPushConstant_Flag);
break;
case LayoutToken::BLEND_SUPPORT_ALL_EQUATIONS:
setFlag(Layout::kBlendSupportAllEquations_Flag);
break;
case LayoutToken::TRACKED:
setFlag(Layout::kTracked_Flag);
break;
case LayoutToken::SRGB_UNPREMUL:
setFlag(Layout::kSRGBUnpremul_Flag);
break;
case LayoutToken::KEY:
setFlag(Layout::kKey_Flag);
break;
case LayoutToken::LOCATION:
setFlag(Layout::kLocation_Flag);
location = this->layoutInt();
break;
case LayoutToken::OFFSET:
setFlag(Layout::kOffset_Flag);
offset = this->layoutInt();
break;
case LayoutToken::BINDING:
setFlag(Layout::kBinding_Flag);
binding = this->layoutInt();
break;
case LayoutToken::INDEX:
setFlag(Layout::kIndex_Flag);
index = this->layoutInt();
break;
case LayoutToken::SET:
setFlag(Layout::kSet_Flag);
set = this->layoutInt();
break;
case LayoutToken::BUILTIN:
setFlag(Layout::kBuiltin_Flag);
builtin = this->layoutInt();
break;
case LayoutToken::INPUT_ATTACHMENT_INDEX:
setFlag(Layout::kInputAttachmentIndex_Flag);
inputAttachmentIndex = this->layoutInt();
break;
case LayoutToken::ORIGIN_UPPER_LEFT:
flags |= Layout::kOriginUpperLeft_Flag;
break;
case LayoutToken::OVERRIDE_COVERAGE:
flags |= Layout::kOverrideCoverage_Flag;
break;
case LayoutToken::BLEND_SUPPORT_ALL_EQUATIONS:
flags |= Layout::kBlendSupportAllEquations_Flag;
break;
case LayoutToken::PUSH_CONSTANT:
flags |= Layout::kPushConstant_Flag;
break;
case LayoutToken::TRACKED:
flags |= Layout::kTracked_Flag;
break;
case LayoutToken::SRGB_UNPREMUL:
flags |= Layout::kSRGBUnpremul_Flag;
break;
case LayoutToken::KEY:
flags |= Layout::kKey_Flag;
break;
case LayoutToken::POINTS:
primitive = Layout::kPoints_Primitive;
setPrimitive(Layout::kPoints_Primitive);
break;
case LayoutToken::LINES:
primitive = Layout::kLines_Primitive;
setPrimitive(Layout::kLines_Primitive);
break;
case LayoutToken::LINE_STRIP:
primitive = Layout::kLineStrip_Primitive;
setPrimitive(Layout::kLineStrip_Primitive);
break;
case LayoutToken::LINES_ADJACENCY:
primitive = Layout::kLinesAdjacency_Primitive;
setPrimitive(Layout::kLinesAdjacency_Primitive);
break;
case LayoutToken::TRIANGLES:
primitive = Layout::kTriangles_Primitive;
setPrimitive(Layout::kTriangles_Primitive);
break;
case LayoutToken::TRIANGLE_STRIP:
primitive = Layout::kTriangleStrip_Primitive;
setPrimitive(Layout::kTriangleStrip_Primitive);
break;
case LayoutToken::TRIANGLES_ADJACENCY:
primitive = Layout::kTrianglesAdjacency_Primitive;
setPrimitive(Layout::kTrianglesAdjacency_Primitive);
break;
case LayoutToken::MAX_VERTICES:
setFlag(Layout::kMaxVertices_Flag);
maxVertices = this->layoutInt();
break;
case LayoutToken::INVOCATIONS:
setFlag(Layout::kInvocations_Flag);
invocations = this->layoutInt();
break;
case LayoutToken::MARKER:
setFlag(Layout::kMarker_Flag);
marker = this->layoutCode();
break;
case LayoutToken::WHEN:
setFlag(Layout::kWhen_Flag);
when = this->layoutCode();
break;
case LayoutToken::CTYPE:
setFlag(Layout::kCType_Flag);
ctype = this->layoutCType();
break;
default:
this->error(t, ("'" + text + "' is not a valid layout qualifier").c_str());
this->error(t, "'" + text + "' is not a valid layout qualifier");
break;
}
} else {
this->error(t, ("'" + text + "' is not a valid layout qualifier").c_str());
this->error(t, "'" + text + "' is not a valid layout qualifier");
}
if (this->checkNext(Token::Kind::TK_RPAREN)) {
break;

View File

@ -1,6 +1,7 @@
static uint8_t SKSL_INCLUDE_sksl_fp[] = {76,1,
static uint8_t SKSL_INCLUDE_sksl_fp[] = {77,1,
14,71,114,67,108,105,112,69,100,103,101,84,121,112,101,
12,80,77,67,111,110,118,101,114,115,105,111,110,
0,
12,115,107,95,70,114,97,103,67,111,111,114,100,
6,102,108,111,97,116,52,
3,105,110,116,
@ -34,93 +35,93 @@ static uint8_t SKSL_INCLUDE_sksl_fp[] = {76,1,
15,2,0,17,0,
46,3,0,
30,
5,15,0,2,30,0,
43,4,0,43,0,0,
29,0,16,0,0,255,255,255,255,255,15,0,255,255,255,255,30,0,30,0,0,2,31,0,
43,4,0,44,0,0,
0,5,0,
43,6,0,50,0,1,
43,6,0,51,0,1,
46,7,0,
30,
5,20,0,4,54,0,
29,0,16,0,0,255,255,255,255,255,20,0,255,255,255,255,30,0,30,0,0,4,55,0,
40,5,0,0,
0,8,0,
40,4,0,1,
46,9,0,
30,
5,15,39,0,68,0,
29,0,16,0,0,255,255,255,255,255,15,39,255,255,255,255,30,0,30,0,0,0,69,0,
40,8,0,0,
46,10,0,
30,
5,15,39,0,84,0,
43,11,0,101,0,0,
29,0,16,0,0,255,255,255,255,255,15,39,255,255,255,255,30,0,30,0,0,0,85,0,
43,11,0,102,0,0,
46,12,0,
30,
5,15,39,0,107,0,
29,0,16,0,0,255,255,255,255,255,15,39,255,255,255,255,30,0,30,0,0,0,108,0,
40,11,0,0,
46,13,0,
30,
5,15,39,0,127,0,
29,0,16,0,0,255,255,255,255,255,15,39,255,255,255,255,30,0,30,0,0,0,128,0,
40,11,0,0,
46,14,0,
30,
5,27,39,0,152,0,
43,15,0,161,0,0,
29,0,16,0,0,255,255,255,255,255,27,39,255,255,255,255,30,0,30,0,0,0,153,0,
43,15,0,162,0,0,
46,16,0,
30,
5,28,39,0,166,0,
29,0,16,0,0,255,255,255,255,255,28,39,255,255,255,255,30,0,30,0,0,0,167,0,
40,15,0,0,
46,17,0,
9,176,0,
43,18,0,179,0,3,
9,177,0,
43,18,0,180,0,3,
23,19,0,
9,197,0,1,17,0,
9,198,0,1,17,0,
40,11,0,
46,20,0,
9,176,0,
9,177,0,
40,18,0,3,
46,21,0,
9,204,0,
43,22,0,214,0,3,
9,205,0,
43,22,0,215,0,3,
45,23,0,2,
40,19,0,
23,24,0,
9,197,0,2,20,0,21,0,
9,198,0,2,20,0,21,0,
40,11,0,
40,24,0,
46,25,0,
9,176,0,
9,177,0,
40,18,0,3,
46,26,0,
9,223,0,
43,27,0,230,0,3,
9,224,0,
43,27,0,231,0,3,
45,28,0,3,
40,19,0,
40,24,0,
23,29,0,
9,197,0,2,25,0,26,0,
9,198,0,2,25,0,26,0,
40,11,0,
40,29,0,
46,30,0,
9,176,0,
9,177,0,
40,18,0,3,
46,31,0,
9,237,0,
9,238,0,
40,11,0,3,
45,32,0,4,
40,19,0,
40,24,0,
40,29,0,
23,33,0,
9,197,0,2,30,0,31,0,
9,198,0,2,30,0,31,0,
40,11,0,
40,33,0,
46,34,0,
9,176,0,
9,177,0,
40,18,0,3,
46,35,0,
9,237,0,
9,238,0,
40,11,0,3,
46,36,0,
9,204,0,
9,205,0,
40,22,0,3,
45,37,0,5,
40,19,0,
@ -128,17 +129,17 @@ static uint8_t SKSL_INCLUDE_sksl_fp[] = {76,1,
40,29,0,
40,33,0,
23,38,0,
9,197,0,3,34,0,35,0,36,0,
9,198,0,3,34,0,35,0,36,0,
40,11,0,
40,38,0,
46,39,0,
9,176,0,
9,177,0,
40,18,0,3,
46,40,0,
9,237,0,
9,238,0,
40,11,0,3,
46,41,0,
9,223,0,
9,224,0,
40,27,0,3,
45,42,0,6,
40,19,0,
@ -147,7 +148,7 @@ static uint8_t SKSL_INCLUDE_sksl_fp[] = {76,1,
40,33,0,
40,38,0,
23,43,0,
9,197,0,3,39,0,40,0,41,0,
9,198,0,3,39,0,40,0,41,0,
40,11,0,
40,43,0,11,0,
0,0,
@ -166,23 +167,23 @@ static uint8_t SKSL_INCLUDE_sksl_fp[] = {76,1,
42,5,0,
46,44,0,
30,
8,1,243,0,
8,1,244,0,
40,1,0,0,
46,45,0,
30,
8,1,251,0,
8,1,252,0,
40,1,0,0,
46,46,0,
30,
8,1,3,1,
8,1,4,1,
40,1,0,0,
46,47,0,
30,
8,1,18,1,
8,1,19,1,
40,1,0,0,
46,48,0,
30,
8,1,33,1,
8,1,34,1,
40,1,0,0,5,0,
1,0,
0,0,
@ -193,15 +194,15 @@ static uint8_t SKSL_INCLUDE_sksl_fp[] = {76,1,
42,3,0,
46,49,0,
30,
8,1,39,1,
8,1,40,1,
40,2,0,0,
46,50,0,
30,
8,1,49,1,
8,1,50,1,
40,2,0,0,
46,51,0,
30,
8,1,61,1,
8,1,62,1,
40,2,0,0,3,0,
2,0,
0,0,

View File

@ -1,4 +1,5 @@
static uint8_t SKSL_INCLUDE_sksl_frag[] = {142,0,
0,
12,115,107,95,70,114,97,103,67,111,111,114,100,
6,102,108,111,97,116,52,
12,115,107,95,67,108,111,99,107,119,105,115,101,
@ -7,7 +8,6 @@ static uint8_t SKSL_INCLUDE_sksl_frag[] = {142,0,
13,115,107,95,83,97,109,112,108,101,77,97,115,107,
24,103,108,95,83,101,99,111,110,100,97,114,121,70,114,97,103,67,111,108,111,114,69,88,84,
5,104,97,108,102,52,
0,
12,115,107,95,70,114,97,103,67,111,108,111,114,
16,115,107,95,76,97,115,116,70,114,97,103,67,111,108,111,114,
8,115,107,95,87,105,100,116,104,
@ -16,37 +16,37 @@ static uint8_t SKSL_INCLUDE_sksl_frag[] = {142,0,
42,9,0,
46,1,0,
30,
5,15,0,2,2,0,
43,2,0,15,0,0,
29,0,16,0,0,255,255,255,255,255,15,0,255,255,255,255,2,0,2,0,0,2,3,0,
43,2,0,16,0,0,
46,3,0,
30,
5,17,0,2,22,0,
43,4,0,35,0,0,
29,0,16,0,0,255,255,255,255,255,17,0,255,255,255,255,2,0,2,0,0,2,23,0,
43,4,0,36,0,0,
0,5,0,
43,6,0,40,0,1,
43,6,0,41,0,1,
46,7,0,
30,
5,20,0,4,44,0,
29,0,16,0,0,255,255,255,255,255,20,0,255,255,255,255,2,0,2,0,0,4,45,0,
40,5,0,0,
46,8,0,
30,
5,15,39,4,58,0,
43,9,0,83,0,0,
29,0,16,0,0,255,255,255,255,255,15,39,255,255,255,255,2,0,2,0,0,4,59,0,
43,9,0,84,0,0,
46,10,0,
30,
29,0,0,0,0,0,255,255,0,255,17,39,255,255,255,255,89,0,89,0,0,4,90,0,
29,128,20,0,0,0,255,255,0,255,17,39,255,255,255,255,2,0,2,0,0,4,90,0,
40,9,0,0,
46,11,0,
30,
5,24,39,0,103,0,
29,0,16,0,0,255,255,255,255,255,24,39,255,255,255,255,2,0,2,0,0,0,103,0,
40,9,0,0,
46,12,0,
30,
5,27,39,0,120,0,
29,0,16,0,0,255,255,255,255,255,27,39,255,255,255,255,2,0,2,0,0,0,120,0,
43,13,0,129,0,0,
46,14,0,
30,
5,28,39,0,134,0,
29,0,16,0,0,255,255,255,255,255,28,39,255,255,255,255,2,0,2,0,0,0,134,0,
40,13,0,0,8,0,
4,0,
1,0,

View File

@ -1,5 +1,6 @@
static uint8_t SKSL_INCLUDE_sksl_geom[] = {134,0,
12,115,107,95,80,101,114,86,101,114,116,101,120,
0,
11,115,107,95,80,111,115,105,116,105,111,110,
6,102,108,111,97,116,52,
12,115,107,95,80,111,105,110,116,83,105,122,101,
@ -12,54 +13,53 @@ static uint8_t SKSL_INCLUDE_sksl_geom[] = {134,0,
18,69,110,100,83,116,114,101,97,109,80,114,105,109,105,116,105,118,101,
10,69,109,105,116,86,101,114,116,101,120,
12,69,110,100,80,114,105,109,105,116,105,118,101,
0,
42,12,0,
37,1,0,2,0,2,
30,
5,0,0,0,15,0,
43,2,0,27,0,
29,0,16,0,0,255,255,255,255,255,0,0,255,255,255,255,15,0,15,0,0,0,16,0,
43,2,0,28,0,
30,
5,1,0,0,34,0,
43,3,0,47,0,
29,0,16,0,0,255,255,255,255,255,1,0,255,255,255,255,15,0,15,0,0,0,35,0,
43,3,0,48,0,
46,4,0,
30,
5,18,39,2,53,0,
29,0,16,0,0,255,255,255,255,255,18,39,255,255,255,255,15,0,15,0,0,2,54,0,
0,5,0,
40,1,0,255,0,
37,6,0,2,0,2,
30,
5,0,0,0,15,0,
29,0,16,0,0,255,255,255,255,255,0,0,255,255,255,255,15,0,15,0,0,0,16,0,
40,2,0,
30,
5,1,0,0,34,0,
29,0,16,0,0,255,255,255,255,255,1,0,255,255,255,255,15,0,15,0,0,0,35,0,
40,3,0,
46,7,0,
30,
5,23,39,4,2,0,
29,0,16,0,0,255,255,255,255,255,23,39,255,255,255,255,15,0,15,0,0,4,2,0,
40,6,0,0,
17,7,0,0,
17,7,0,1,
46,8,0,
9,59,0,
43,9,0,66,0,3,
9,60,0,
43,9,0,67,0,3,
23,10,0,
30,
8,64,70,0,1,8,0,
43,11,0,87,0,
8,64,71,0,1,8,0,
43,11,0,88,0,
46,12,0,
9,59,0,
9,60,0,
40,9,0,3,
23,13,0,
30,
8,64,92,0,1,12,0,
8,64,93,0,1,12,0,
40,11,0,
23,14,0,
30,
8,64,111,0,0,
8,64,112,0,0,
40,11,0,
23,15,0,
30,
8,64,122,0,0,
8,64,123,0,0,
40,11,0,7,0,
7,0,
10,0,
@ -70,8 +70,8 @@ static uint8_t SKSL_INCLUDE_sksl_geom[] = {134,0,
1,0,
12,
27,
40,4,0,2,0,53,0,255,
40,4,0,2,0,54,0,255,
27,
40,7,0,2,0,135,0,0,
40,7,0,2,0,15,0,0,
13,};
static constexpr size_t SKSL_INCLUDE_sksl_geom_LENGTH = sizeof(SKSL_INCLUDE_sksl_geom);

View File

@ -1,4 +1,5 @@
static uint8_t SKSL_INCLUDE_sksl_runtime[] = {87,0,
static uint8_t SKSL_INCLUDE_sksl_runtime[] = {88,0,
0,
12,115,107,95,70,114,97,103,67,111,111,114,100,
6,102,108,111,97,116,52,
2,102,112,
@ -12,37 +13,37 @@ static uint8_t SKSL_INCLUDE_sksl_runtime[] = {87,0,
42,11,0,
46,1,0,
30,
5,15,0,0,2,0,
43,2,0,15,0,0,
29,0,16,0,0,255,255,255,255,255,15,0,255,255,255,255,2,0,2,0,0,0,3,0,
43,2,0,16,0,0,
46,3,0,
9,22,0,
43,4,0,25,0,3,
9,23,0,
43,4,0,26,0,3,
23,5,0,
9,43,0,1,3,0,
43,6,0,50,0,
9,44,0,1,3,0,
43,6,0,51,0,
46,7,0,
9,22,0,
9,23,0,
40,4,0,3,
46,8,0,
9,56,0,
43,9,0,63,0,3,
9,57,0,
43,9,0,64,0,3,
45,10,0,2,
40,5,0,
23,11,0,
9,43,0,2,7,0,8,0,
9,44,0,2,7,0,8,0,
40,6,0,
40,11,0,
46,12,0,
9,22,0,
9,23,0,
40,4,0,3,
46,13,0,
9,70,0,
43,14,0,80,0,3,
9,71,0,
43,14,0,81,0,3,
45,15,0,3,
40,5,0,
40,11,0,
23,16,0,
9,43,0,2,12,0,13,0,
9,44,0,2,12,0,13,0,
40,6,0,
40,16,0,2,0,
9,0,

View File

@ -1,5 +1,6 @@
static uint8_t SKSL_INCLUDE_sksl_vert[] = {82,0,
12,115,107,95,80,101,114,86,101,114,116,101,120,
0,
11,115,107,95,80,111,115,105,116,105,111,110,
6,102,108,111,97,116,52,
12,115,107,95,80,111,105,110,116,83,105,122,101,
@ -7,15 +8,14 @@ static uint8_t SKSL_INCLUDE_sksl_vert[] = {82,0,
11,115,107,95,86,101,114,116,101,120,73,68,
3,105,110,116,
13,115,107,95,73,110,115,116,97,110,99,101,73,68,
0,
42,6,0,
37,1,0,2,0,2,
30,
5,0,0,0,15,0,
43,2,0,27,0,
29,0,16,0,0,255,255,255,255,255,0,0,255,255,255,255,15,0,15,0,0,0,16,0,
43,2,0,28,0,
30,
5,1,0,0,34,0,
43,3,0,47,0,
29,0,16,0,0,255,255,255,255,255,1,0,255,255,255,255,15,0,15,0,0,0,35,0,
43,3,0,48,0,
46,4,0,
30,
8,4,2,0,
@ -24,11 +24,11 @@ static uint8_t SKSL_INCLUDE_sksl_vert[] = {82,0,
17,4,0,1,
46,5,0,
30,
5,42,0,2,53,0,
43,6,0,65,0,0,
29,0,16,0,0,255,255,255,255,255,42,0,255,255,255,255,15,0,15,0,0,2,54,0,
43,6,0,66,0,0,
46,7,0,
30,
5,43,0,2,69,0,
29,0,16,0,0,255,255,255,255,255,43,0,255,255,255,255,15,0,15,0,0,2,70,0,
40,6,0,0,4,0,
5,0,
3,0,
@ -36,7 +36,7 @@ static uint8_t SKSL_INCLUDE_sksl_vert[] = {82,0,
4,0,
12,
27,
40,4,0,2,0,83,0,0,
40,4,0,2,0,15,0,0,
48,
47,5,0,
40,6,0,0,

View File

@ -27,6 +27,21 @@ struct Layout {
kTracked_Flag = 1 << 4,
kSRGBUnpremul_Flag = 1 << 5,
kKey_Flag = 1 << 6,
// These flags indicate if the qualifier appeared, regardless of the accompanying value.
kLocation_Flag = 1 << 7,
kOffset_Flag = 1 << 8,
kBinding_Flag = 1 << 9,
kIndex_Flag = 1 << 10,
kSet_Flag = 1 << 11,
kBuiltin_Flag = 1 << 12,
kInputAttachmentIndex_Flag = 1 << 13,
kPrimitive_Flag = 1 << 14,
kMaxVertices_Flag = 1 << 15,
kInvocations_Flag = 1 << 16,
kMarker_Flag = 1 << 17,
kWhen_Flag = 1 << 18,
kCType_Flag = 1 << 19,
};
enum Primitive {

View File

@ -0,0 +1,8 @@
### Compilation failed:
error: 3: only one primitive-type layout qualifier is allowed
error: 4: only one primitive-type layout qualifier is allowed
error: 5: only one primitive-type layout qualifier is allowed
error: 6: only one primitive-type layout qualifier is allowed
error: 7: only one primitive-type layout qualifier is allowed
5 errors

View File

@ -0,0 +1,22 @@
### Compilation failed:
error: 22: layout qualifier 'origin_upper_left' appears more than once
error: 23: layout qualifier 'override_coverage' appears more than once
error: 24: layout qualifier 'push_constant' appears more than once
error: 25: layout qualifier 'blend_support_all_equations' appears more than once
error: 26: layout qualifier 'tracked' appears more than once
error: 27: layout qualifier 'srgb_unpremul' appears more than once
error: 28: layout qualifier 'key' appears more than once
error: 29: layout qualifier 'location' appears more than once
error: 30: layout qualifier 'offset' appears more than once
error: 31: layout qualifier 'binding' appears more than once
error: 32: layout qualifier 'index' appears more than once
error: 33: layout qualifier 'set' appears more than once
error: 34: layout qualifier 'builtin' appears more than once
error: 35: layout qualifier 'input_attachment_index' appears more than once
error: 36: layout qualifier 'max_vertices' appears more than once
error: 37: layout qualifier 'invocations' appears more than once
error: 38: layout qualifier 'marker' appears more than once
error: 39: layout qualifier 'when' appears more than once
error: 40: layout qualifier 'ctype' appears more than once
19 errors