Added DSL layout() support
Change-Id: I698dd607ff4676b6fb29be0a718c6073b66dc7c7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/406336
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 28edbd8..edd2401 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -25,6 +25,7 @@
"$_include/sksl/DSLErrorHandling.h",
"$_include/sksl/DSLExpression.h",
"$_include/sksl/DSLFunction.h",
+ "$_include/sksl/DSLLayout.h",
"$_include/sksl/DSLModifiers.h",
"$_include/sksl/DSLRuntimeEffects.h",
"$_include/sksl/DSLStatement.h",
@@ -82,6 +83,7 @@
"$_src/sksl/dsl/DSLCore.cpp",
"$_src/sksl/dsl/DSLExpression.cpp",
"$_src/sksl/dsl/DSLFunction.cpp",
+ "$_src/sksl/dsl/DSLLayout.cpp",
"$_src/sksl/dsl/DSLRuntimeEffects.cpp",
"$_src/sksl/dsl/DSLStatement.cpp",
"$_src/sksl/dsl/DSLType.cpp",
diff --git a/include/sksl/DSL.h b/include/sksl/DSL.h
index 4c6cbb2..74f313b 100644
--- a/include/sksl/DSL.h
+++ b/include/sksl/DSL.h
@@ -19,6 +19,7 @@
using Expression = DSLExpression;
using Field = DSLField;
using Function = DSLFunction;
+using Layout = DSLLayout;
using Modifiers = DSLModifiers;
using Statement = DSLStatement;
using Var = DSLVar;
diff --git a/include/sksl/DSLLayout.h b/include/sksl/DSLLayout.h
new file mode 100644
index 0000000..e237ada
--- /dev/null
+++ b/include/sksl/DSLLayout.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2021 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKSL_DSL_LAYOUT
+#define SKSL_DSL_LAYOUT
+
+#include "include/sksl/DSLLayout.h"
+
+#include "include/private/SkSLLayout.h"
+#include "include/sksl/DSLErrorHandling.h"
+
+namespace SkSL {
+
+namespace dsl {
+
+class DSLLayout {
+public:
+ DSLLayout& originUpperLeft(PositionInfo pos = PositionInfo()) {
+ return this->flag(SkSL::Layout::kOriginUpperLeft_Flag, "origin_upper_left", pos);
+ }
+
+ DSLLayout& overrideCoverage(PositionInfo pos = PositionInfo()) {
+ return this->flag(SkSL::Layout::kOverrideCoverage_Flag, "override_coverage", pos);
+ }
+
+ DSLLayout& pushConstant(PositionInfo pos = PositionInfo()) {
+ return this->flag(SkSL::Layout::kPushConstant_Flag, "push_constant", pos);
+ }
+
+ DSLLayout& blendSupportAllEquations(PositionInfo pos = PositionInfo()) {
+ return this->flag(SkSL::Layout::kBlendSupportAllEquations_Flag,
+ "blend_support_all_equations", pos);
+ }
+
+ DSLLayout& srgbUnpremul(PositionInfo pos = PositionInfo()) {
+ return this->flag(SkSL::Layout::kSRGBUnpremul_Flag, "srgb_unpremul", pos);
+ }
+
+ DSLLayout& location(int location, PositionInfo pos = PositionInfo()) {
+ return this->intValue(&fSkSLLayout.fLocation, location, SkSL::Layout::kLocation_Flag,
+ "location", pos);
+ }
+
+ DSLLayout& offset(int offset, PositionInfo pos = PositionInfo()) {
+ return this->intValue(&fSkSLLayout.fOffset, offset, SkSL::Layout::kOffset_Flag, "offset",
+ pos);
+ }
+
+ DSLLayout& binding(int binding, PositionInfo pos = PositionInfo()) {
+ return this->intValue(&fSkSLLayout.fBinding, binding, SkSL::Layout::kBinding_Flag,
+ "binding", pos);
+ }
+
+ DSLLayout& index(int index, PositionInfo pos = PositionInfo()) {
+ return this->intValue(&fSkSLLayout.fIndex, index, SkSL::Layout::kIndex_Flag, "index", pos);
+ }
+
+ DSLLayout& set(int set, PositionInfo pos = PositionInfo()) {
+ return this->intValue(&fSkSLLayout.fSet, set, SkSL::Layout::kSet_Flag, "set", pos);
+ }
+
+ DSLLayout& builtin(int builtin, PositionInfo pos = PositionInfo()) {
+ return this->intValue(&fSkSLLayout.fBuiltin, builtin, SkSL::Layout::kBuiltin_Flag,
+ "builtin", pos);
+ }
+
+ DSLLayout& inputAttachmentIndex(int inputAttachmentIndex, PositionInfo pos = PositionInfo()) {
+ return this->intValue(&fSkSLLayout.fInputAttachmentIndex, inputAttachmentIndex,
+ SkSL::Layout::kInputAttachmentIndex_Flag, "input_attachment_index",
+ pos);
+ }
+
+private:
+ DSLLayout& flag(SkSL::Layout::Flag mask, const char* name, PositionInfo pos);
+
+ DSLLayout& intValue(int* target, int value, SkSL::Layout::Flag flag, const char* name,
+ PositionInfo pos);
+
+ SkSL::Layout fSkSLLayout;
+
+ friend class DSLModifiers;
+};
+
+} // namespace dsl
+
+} // namespace SkSL
+
+#endif
diff --git a/include/sksl/DSLModifiers.h b/include/sksl/DSLModifiers.h
index 70f142c..262ef20 100644
--- a/include/sksl/DSLModifiers.h
+++ b/include/sksl/DSLModifiers.h
@@ -10,6 +10,7 @@
#include "include/private/SkSLModifiers.h"
#include "include/private/SkTArray.h"
+#include "include/sksl/DSLLayout.h"
namespace SkSL {
@@ -32,10 +33,11 @@
class DSLModifiers {
public:
- DSLModifiers() {}
+ DSLModifiers(int flags = 0)
+ : DSLModifiers(DSLLayout(), flags) {}
- DSLModifiers(int flags)
- : fModifiers(SkSL::Layout(), flags) {}
+ DSLModifiers(DSLLayout layout, int flags = 0)
+ : fModifiers(layout.fSkSLLayout, flags) {}
int flags() const {
return fModifiers.fFlags;
diff --git a/src/sksl/dsl/DSLLayout.cpp b/src/sksl/dsl/DSLLayout.cpp
new file mode 100644
index 0000000..3d70e60
--- /dev/null
+++ b/src/sksl/dsl/DSLLayout.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/sksl/DSLLayout.h"
+
+#include "src/sksl/dsl/priv/DSLWriter.h"
+
+namespace SkSL {
+
+namespace dsl {
+
+DSLLayout& DSLLayout::flag(SkSL::Layout::Flag mask, const char* name, PositionInfo pos) {
+ if (fSkSLLayout.fFlags & mask) {
+ DSLWriter::ReportError(("error: layout qualifier '" + String(name) +
+ "' appears more than once\n").c_str(), &pos);
+ }
+ fSkSLLayout.fFlags |= mask;
+ return *this;
+}
+
+DSLLayout& DSLLayout::intValue(int* target, int value, SkSL::Layout::Flag flag, const char* name,
+ PositionInfo pos) {
+ this->flag(flag, name, pos);
+ *target = value;
+ return *this;
+}
+
+} // namespace dsl
+
+} // namespace SkSL
diff --git a/tests/SkSLDSLTest.cpp b/tests/SkSLDSLTest.cpp
index c73fc4c..bd07534 100644
--- a/tests/SkSLDSLTest.cpp
+++ b/tests/SkSLDSLTest.cpp
@@ -1763,6 +1763,95 @@
// Uniforms do not need to be explicitly declared
}
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLayout, r, ctxInfo) {
+ AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), /*markVarsDeclared=*/false);
+ Var v1(DSLModifiers(DSLLayout().location(1).set(2).binding(3).offset(4).index(5).builtin(6)
+ .inputAttachmentIndex(7),
+ kConst_Modifier), kInt_Type, "v1", 0);
+ EXPECT_EQUAL(Declare(v1), "layout (location = 1, offset = 4, binding = 3, index = 5, set = 2, "
+ "builtin = 6, input_attachment_index = 7) const int v1 = 0;");
+
+ Var v2(DSLLayout().originUpperLeft(), kFloat2_Type, "v2");
+ EXPECT_EQUAL(Declare(v2), "layout (origin_upper_left) float2 v2;");
+
+ Var v3(DSLLayout().overrideCoverage(), kHalf_Type, "v3");
+ EXPECT_EQUAL(Declare(v3), "layout (override_coverage) half v3;");
+
+ Var v4(DSLLayout().pushConstant(), kBool_Type, "v4");
+ EXPECT_EQUAL(Declare(v4), "layout (push_constant) bool v4;");
+
+ Var v5(DSLLayout().blendSupportAllEquations(), kHalf4_Type, "v5");
+ EXPECT_EQUAL(Declare(v5), "layout (blend_support_all_equations) half4 v5;");
+
+ Var v6(DSLModifiers(DSLLayout().srgbUnpremul(), kUniform_Modifier), kBool_Type, "v6");
+ DeclareGlobal(v6);
+ EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "layout (srgb_unpremul) uniform bool v6;");
+
+ {
+ ExpectError error(r, "error: layout qualifier 'location' appears more than once\n");
+ DSLLayout().location(1).location(2);
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'set' appears more than once\n");
+ DSLLayout().set(1).set(2);
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'binding' appears more than once\n");
+ DSLLayout().binding(1).binding(2);
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'offset' appears more than once\n");
+ DSLLayout().offset(1).offset(2);
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'index' appears more than once\n");
+ DSLLayout().index(1).index(2);
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'builtin' appears more than once\n");
+ DSLLayout().builtin(1).builtin(2);
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'input_attachment_index' appears more than "
+ "once\n");
+ DSLLayout().inputAttachmentIndex(1).inputAttachmentIndex(2);
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'origin_upper_left' appears more than "
+ "once\n");
+ DSLLayout().originUpperLeft().originUpperLeft();
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'override_coverage' appears more than "
+ "once\n");
+ DSLLayout().overrideCoverage().overrideCoverage();
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'push_constant' appears more than once\n");
+ DSLLayout().pushConstant().pushConstant();
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'blend_support_all_equations' appears more "
+ "than once\n");
+ DSLLayout().blendSupportAllEquations().blendSupportAllEquations();
+ }
+
+ {
+ ExpectError error(r, "error: layout qualifier 'srgb_unpremul' appears more than once\n");
+ DSLLayout().srgbUnpremul().srgbUnpremul();
+ }
+}
+
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSampleFragmentProcessor, r, ctxInfo) {
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), /*markVarsDeclared=*/true,
SkSL::ProgramKind::kFragmentProcessor);