Enforce layout(location=...) on Metal out variables.

Previously, this would generate invalid code such as `[[user(locn-1)]]`.
We now generate a more-useful error at SkSL compilation time.

Change-Id: Ifbe335ec6d4abcbdfe89b892ba51063c94d22b11
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/339397
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2020-12-01 10:36:37 -05:00 committed by Skia Commit-Bot
parent 46d1e9f5f2
commit 842b3599c8
12 changed files with 22 additions and 11 deletions

View File

@ -175,6 +175,7 @@ sksl_metal_tests = [
"$_tests/sksl/metal/NumericGlobals.sksl",
"$_tests/sksl/metal/OpaqueTypeInInterfaceBlock.sksl",
"$_tests/sksl/metal/OpaqueTypeInStruct.sksl",
"$_tests/sksl/metal/OutVarsRequireLocation.sksl",
"$_tests/sksl/metal/SamplerGlobals.sksl",
]

View File

@ -1559,12 +1559,15 @@ void MetalCodeGenerator::writeOutputStruct() {
this->writeType(var.type());
this->write(" ");
this->writeName(var.name());
if (fProgram.fKind == Program::kVertex_Kind) {
this->write(" [[user(locn" +
to_string(var.modifiers().fLayout.fLocation) + ")]]");
int location = var.modifiers().fLayout.fLocation;
if (location < 0) {
fErrors.error(var.fOffset,
"Metal out variables must have 'layout(location=...)'");
} else if (fProgram.fKind == Program::kVertex_Kind) {
this->write(" [[user(locn" + to_string(location) + ")]]");
} else if (fProgram.fKind == Program::kFragment_Kind) {
this->write(" [[color(" +
to_string(var.modifiers().fLayout.fLocation) +")");
this->write(" [[color(" + to_string(location) + ")");
int colorIndex = var.modifiers().fLayout.fIndex;
if (colorIndex) {
this->write(", index(" + to_string(colorIndex) + ")");

View File

@ -0,0 +1 @@
out int noLocation;

View File

@ -0,0 +1,4 @@
### Compilation failed:
error: 1: Metal out variables must have 'layout(location=...)'
1 error

View File

@ -1,4 +1,4 @@
out int id;
layout(location=1) out int id;
void main() {
id = sk_InstanceID;

View File

@ -1,4 +1,4 @@
out int id;
layout(location=1) out int id;
void main() {
id = sk_VertexID;

View File

@ -6,6 +6,7 @@ OpName %sk_InstanceID "sk_InstanceID"
OpName %id "id"
OpName %main "main"
OpDecorate %sk_InstanceID BuiltIn InstanceIndex
OpDecorate %id Location 1
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%sk_InstanceID = OpVariable %_ptr_Input_int Input

View File

@ -1,5 +1,5 @@
out int id;
layout (location = 1) out int id;
void main() {
id = gl_InstanceID;
}

View File

@ -5,7 +5,7 @@ struct Inputs {
};
struct Outputs {
float4 sk_Position [[position]];
int id [[user(locn-1)]];
int id [[user(locn1)]];
float sk_PointSize [[point_size]];
};

View File

@ -6,6 +6,7 @@ OpName %sk_VertexID "sk_VertexID"
OpName %id "id"
OpName %main "main"
OpDecorate %sk_VertexID BuiltIn VertexIndex
OpDecorate %id Location 1
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%sk_VertexID = OpVariable %_ptr_Input_int Input

View File

@ -1,5 +1,5 @@
out int id;
layout (location = 1) out int id;
void main() {
id = gl_VertexID;
}

View File

@ -5,7 +5,7 @@ struct Inputs {
};
struct Outputs {
float4 sk_Position [[position]];
int id [[user(locn-1)]];
int id [[user(locn1)]];
float sk_PointSize [[point_size]];
};