Re-land sksl fragment processor support
This reverts commit ed50200682e0de72c3abecaa4d5324ebcd1ed9f9.
Bug: skia:
Change-Id: I9caa7454b391450620d6989dc472abb3cf7a2cab
Reviewed-on: https://skia-review.googlesource.com/20965
Reviewed-by: Ben Wagner <benjaminwagner@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h
index 07dad1d..89a1a1e 100644
--- a/src/sksl/ir/SkSLExpression.h
+++ b/src/sksl/ir/SkSLExpression.h
@@ -36,6 +36,7 @@
kIndex_Kind,
kPrefix_Kind,
kPostfix_Kind,
+ kSetting_Kind,
kSwizzle_Kind,
kVariableReference_Kind,
kTernary_Kind,
diff --git a/src/sksl/ir/SkSLFunctionDeclaration.h b/src/sksl/ir/SkSLFunctionDeclaration.h
index 8704c9a..64236d3 100644
--- a/src/sksl/ir/SkSLFunctionDeclaration.h
+++ b/src/sksl/ir/SkSLFunctionDeclaration.h
@@ -71,7 +71,7 @@
bool determineFinalTypes(const std::vector<std::unique_ptr<Expression>>& arguments,
std::vector<const Type*>* outParameterTypes,
const Type** outReturnType) const {
- assert(arguments.size() == fParameters.size());
+ ASSERT(arguments.size() == fParameters.size());
int genericIndex = -1;
for (size_t i = 0; i < arguments.size(); i++) {
if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) {
@@ -93,7 +93,7 @@
}
}
if (fReturnType.kind() == Type::kGeneric_Kind) {
- assert(genericIndex != -1);
+ ASSERT(genericIndex != -1);
*outReturnType = fReturnType.coercibleTypes()[genericIndex];
} else {
*outReturnType = &fReturnType;
diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h
index 3a8416ac..8bf0472 100644
--- a/src/sksl/ir/SkSLLayout.h
+++ b/src/sksl/ir/SkSLLayout.h
@@ -8,6 +8,7 @@
#ifndef SKSL_LAYOUT
#define SKSL_LAYOUT
+#include "SkSLString.h"
#include "SkSLUtil.h"
namespace SkSL {
@@ -42,6 +43,16 @@
kR8I,
};
+ // used by SkSL processors
+ enum Key {
+ // field is not a key
+ kNo_Key,
+ // field is a key
+ kKey_Key,
+ // key is 0 or 1 depending on whether the matrix is an identity matrix
+ kIdentity_Key,
+ };
+
static const char* FormatToStr(Format format) {
switch (format) {
case Format::kUnspecified: return "";
@@ -55,7 +66,6 @@
case Format::kR8I: return "r8i";
}
ABORT("Unexpected format");
- return "";
}
static bool ReadFormat(String str, Format* format) {
@@ -90,7 +100,7 @@
Layout(int location, int offset, int binding, int index, int set, int builtin,
int inputAttachmentIndex, bool originUpperLeft, bool overrideCoverage,
bool blendSupportAllEquations, Format format, bool pushconstant, Primitive primitive,
- int maxVertices, int invocations)
+ int maxVertices, int invocations, String when, Key key)
: fLocation(location)
, fOffset(offset)
, fBinding(binding)
@@ -105,7 +115,9 @@
, fPushConstant(pushconstant)
, fPrimitive(primitive)
, fMaxVertices(maxVertices)
- , fInvocations(invocations) {}
+ , fInvocations(invocations)
+ , fWhen(when)
+ , fKey(key) {}
Layout()
: fLocation(-1)
@@ -122,7 +134,8 @@
, fPushConstant(false)
, fPrimitive(kUnspecified_Primitive)
, fMaxVertices(-1)
- , fInvocations(-1) {}
+ , fInvocations(-1)
+ , fKey(kNo_Key) {}
String description() const {
String result;
@@ -215,6 +228,22 @@
result += separator + "invocations = " + to_string(fInvocations);
separator = ", ";
}
+ if (fWhen.size()) {
+ result += separator + "when = " + fWhen;
+ separator = ", ";
+ }
+ switch (fKey) {
+ case kNo_Key:
+ break;
+ case kKey_Key:
+ result += separator + "key";
+ separator = ", ";
+ break;
+ case kIdentity_Key:
+ result += separator + "key=identity";
+ separator = ", ";
+ break;
+ }
if (result.size() > 0) {
result = "layout (" + result + ")";
}
@@ -261,6 +290,8 @@
Primitive fPrimitive;
int fMaxVertices;
int fInvocations;
+ String fWhen;
+ Key fKey;
};
} // namespace
diff --git a/src/sksl/ir/SkSLPrefixExpression.h b/src/sksl/ir/SkSLPrefixExpression.h
index acab37e..5ac84c6 100644
--- a/src/sksl/ir/SkSLPrefixExpression.h
+++ b/src/sksl/ir/SkSLPrefixExpression.h
@@ -33,9 +33,8 @@
fOperand->hasSideEffects();
}
- virtual std::unique_ptr<Expression> constantPropagate(
- const IRGenerator& irGenerator,
- const DefinitionMap& definitions) override {
+ std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
+ const DefinitionMap& definitions) override {
if (fOperand->fKind == Expression::kFloatLiteral_Kind) {
return std::unique_ptr<Expression>(new FloatLiteral(
irGenerator.fContext,
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index 96bd5c4..a3eeaa3 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -11,7 +11,9 @@
#include <vector>
#include <memory>
-#include "SkSLContext.h"
+#include "SkSLBoolLiteral.h"
+#include "SkSLExpression.h"
+#include "SkSLIntLiteral.h"
#include "SkSLModifiers.h"
#include "SkSLProgramElement.h"
#include "SkSLSymbolTable.h"
@@ -21,11 +23,46 @@
namespace SkSL {
+class Context;
+
/**
* Represents a fully-digested program, ready for code generation.
*/
struct Program {
struct Settings {
+ struct Value {
+ Value(bool b)
+ : fKind(kBool_Kind)
+ , fValue(b) {}
+
+ Value(int i)
+ : fKind(kInt_Kind)
+ , fValue(i) {}
+
+ std::unique_ptr<Expression> literal(const Context& context, Position position) const {
+ switch (fKind) {
+ case Program::Settings::Value::kBool_Kind:
+ return std::unique_ptr<Expression>(new BoolLiteral(context,
+ position,
+ fValue));
+ case Program::Settings::Value::kInt_Kind:
+ return std::unique_ptr<Expression>(new IntLiteral(context,
+ position,
+ fValue));
+ default:
+ ASSERT(false);
+ return nullptr;
+ }
+ }
+
+ enum {
+ kBool_Kind,
+ kInt_Kind,
+ } fKind;
+
+ int fValue;
+ };
+
#ifdef SKSL_STANDALONE
const StandaloneShaderCaps* fCaps = &standaloneCaps;
#else
@@ -34,6 +71,10 @@
// if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
// must be flipped.
bool fFlipY = false;
+ // if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their
+ // constant equivalents during compilation
+ bool fReplaceSettings = true;
+ std::unordered_map<String, Value> fArgs;
};
struct Inputs {
@@ -57,7 +98,8 @@
enum Kind {
kFragment_Kind,
kVertex_Kind,
- kGeometry_Kind
+ kGeometry_Kind,
+ kFragmentProcessor_Kind
};
Program(Kind kind,
diff --git a/src/sksl/ir/SkSLProgramElement.h b/src/sksl/ir/SkSLProgramElement.h
index ebb4e9a..1e2bb48 100644
--- a/src/sksl/ir/SkSLProgramElement.h
+++ b/src/sksl/ir/SkSLProgramElement.h
@@ -21,7 +21,8 @@
kFunction_Kind,
kInterfaceBlock_Kind,
kExtension_Kind,
- kModifiers_Kind
+ kModifiers_Kind,
+ kSection_Kind
};
ProgramElement(Position position, Kind kind)
diff --git a/src/sksl/ir/SkSLSection.h b/src/sksl/ir/SkSLSection.h
new file mode 100644
index 0000000..f9815b1
--- /dev/null
+++ b/src/sksl/ir/SkSLSection.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKSL_SECTION
+#define SKSL_SECTION
+
+#include "SkSLProgramElement.h"
+
+namespace SkSL {
+
+/**
+ * A section declaration (e.g. @body { body code here })..
+ */
+struct Section : public ProgramElement {
+ Section(Position position, String name, String arg, String text)
+ : INHERITED(position, kSection_Kind)
+ , fName(std::move(name))
+ , fArgument(std::move(arg))
+ , fText(std::move(text)) {}
+
+ String description() const override {
+ String result = "@" + fName;
+ if (fArgument.size()) {
+ result += "(" + fArgument + ")";
+ }
+ result += " { " + fText + " }";
+ return result;
+ }
+
+ const String fName;
+ const String fArgument;
+ const String fText;
+
+ typedef ProgramElement INHERITED;
+};
+
+} // namespace
+
+#endif
diff --git a/src/sksl/ir/SkSLSetting.cpp b/src/sksl/ir/SkSLSetting.cpp
new file mode 100644
index 0000000..2d4a8ba
--- /dev/null
+++ b/src/sksl/ir/SkSLSetting.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkSLSetting.h"
+#include "SkSLIRGenerator.h"
+#include "SkSLVariableReference.h"
+
+namespace SkSL {
+
+std::unique_ptr<Expression> Setting::constantPropagate(const IRGenerator& irGenerator,
+ const DefinitionMap& definitions) {
+ if (irGenerator.fSettings->fReplaceSettings) {
+ return VariableReference::copy_constant(irGenerator, fValue.get());
+ }
+ return nullptr;
+ }
+} // namespace
+
diff --git a/src/sksl/ir/SkSLSetting.h b/src/sksl/ir/SkSLSetting.h
new file mode 100644
index 0000000..995fcf5
--- /dev/null
+++ b/src/sksl/ir/SkSLSetting.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKSL_SETTING
+#define SKSL_SETTING
+
+#include "SkSLContext.h"
+#include "SkSLExpression.h"
+
+namespace SkSL {
+
+/**
+ * Represents a compile-time constant setting, such as sk_Caps.fbFetchSupport. These are generally
+ * collapsed down to their constant representations during the compilation process.
+ */
+struct Setting : public Expression {
+ Setting(Position position, String name, std::unique_ptr<Expression> value)
+ : INHERITED(position, kSetting_Kind, value->fType)
+ , fName(std::move(name))
+ , fValue(std::move(value)) {
+ ASSERT(fValue->isConstant());
+ }
+
+ std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
+ const DefinitionMap& definitions) override;
+
+ String description() const override {
+ return fName;
+ }
+
+ bool hasSideEffects() const override {
+ return false;
+ }
+
+ bool isConstant() const override {
+ return true;
+ }
+
+ const String fName;
+ std::unique_ptr<Expression> fValue;
+
+ typedef Expression INHERITED;
+};
+
+} // namespace
+
+#endif
diff --git a/src/sksl/ir/SkSLSwizzle.h b/src/sksl/ir/SkSLSwizzle.h
index 1e36c41..442e92f 100644
--- a/src/sksl/ir/SkSLSwizzle.h
+++ b/src/sksl/ir/SkSLSwizzle.h
@@ -71,10 +71,8 @@
ASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);
}
- virtual std::unique_ptr<Expression> constantPropagate(
- const IRGenerator& irGenerator,
- const DefinitionMap& definitions) override {
-
+ std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
+ const DefinitionMap& definitions) override {
if (fBase->fKind == Expression::kConstructor_Kind && fBase->isConstant()) {
// we're swizzling a constant vector, e.g. vec4(1).x. Simplify it.
ASSERT(fBase->fKind == Expression::kConstructor_Kind);
diff --git a/src/sksl/ir/SkSLVarDeclarations.h b/src/sksl/ir/SkSLVarDeclarations.h
index c07fee8..1eda87e 100644
--- a/src/sksl/ir/SkSLVarDeclarations.h
+++ b/src/sksl/ir/SkSLVarDeclarations.h
@@ -55,7 +55,7 @@
* A variable declaration statement, which may consist of one or more individual variables.
*/
struct VarDeclarations : public ProgramElement {
- VarDeclarations(Position position, const Type* baseType,
+ VarDeclarations(Position position, const Type* baseType,
std::vector<std::unique_ptr<VarDeclaration>> vars)
: INHERITED(position, kVar_Kind)
, fBaseType(*baseType) {
diff --git a/src/sksl/ir/SkSLVariableReference.h b/src/sksl/ir/SkSLVariableReference.h
index 92aef94..ba17437 100644
--- a/src/sksl/ir/SkSLVariableReference.h
+++ b/src/sksl/ir/SkSLVariableReference.h
@@ -14,6 +14,7 @@
#include "SkSLFloatLiteral.h"
#include "SkSLIRGenerator.h"
#include "SkSLIntLiteral.h"
+#include "SkSLSetting.h"
namespace SkSL {
@@ -104,6 +105,12 @@
return std::unique_ptr<Expression>(new Constructor(Position(), c->fType,
std::move(args)));
}
+ case Expression::kSetting_Kind: {
+ const Setting* s = (const Setting*) expr;
+ return std::unique_ptr<Expression>(new Setting(Position(), s->fName,
+ copy_constant(irGenerator,
+ s->fValue.get())));
+ }
default:
ABORT("unsupported constant\n");
}