Reland "Migrate caps-bit lookup code from IRGenerator to Setting."
This reverts commit e79bb32365eac7e44b4c3f8f57a85ae627ae1044.
Reason for revert: removes static constructor
Original change's description:
> Revert "Migrate caps-bit lookup code from IRGenerator to Setting."
>
> This reverts commit c5ab6fe38814b861710e87dd206ac30a1094165e.
>
> Reason for revert: Chrome roll,
> https://logs.chromium.org/logs/chromium/buildbucket/cr-buildbucket.appspot.com/8854325862539635248/+/steps/check_static_initializers__with_patch_/0/stdout
>
> Original change's description:
> > Migrate caps-bit lookup code from IRGenerator to Setting.
> >
> > This CL moves existing code from point A to point B; the logic should be
> > the same as before.
> >
> > Change-Id: I90c39588531a34f74c4b1802a7c692c08ddc4f16
> > Bug: skia:11365
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375075
> > Commit-Queue: John Stiles <johnstiles@google.com>
> > Auto-Submit: John Stiles <johnstiles@google.com>
> > Reviewed-by: Brian Osman <brianosman@google.com>
>
> TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com
>
> Change-Id: I272eaf6ca55c75527538732c1582a26d243572b5
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:11365
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375676
> Reviewed-by: Mike Klein <mtklein@google.com>
> Commit-Queue: Mike Klein <mtklein@google.com>
Bug: skia:11365
Change-Id: Ia4cf08dd4472c4e942263eeb4de5e04ac6c08bdc
Reland "Remove CapsMap from IR Generator."
This reverts commit 45c57e116ee0ce214bdf78405a4762722e4507d9.
Reason for revert: removing static constructor
Original change's description:
> Revert "Remove CapsMap from IR Generator."
>
> This reverts commit 6394bb43cbb5f7fc611bbca5440750c282d0cd76.
>
> Reason for revert: chrome roll still,
>
> Dumping static initializers via dump-static-initializers.py:
> # SkSL::CapsLookupTable::CapsLookupTable(std::initializer_list<std::__1::pair<char const*, SkSL::CapsLookupMethod*> >)
>
>
> Original change's description:
> > Remove CapsMap from IR Generator.
> >
> > Previously, the IRGenerator's fCapsMap was a lookup table from caps-name
> > to caps-value.
> >
> > This has been replaced with a lookup table from caps-name to
> > caps-lookup-method. This is more general-purpose; you can initialize it
> > once and it always works, instead of needing to initialize it based on
> > a static set of caps.
> >
> > The next step after this CL is to migrate this logic into Settings and
> > remove caps handling from the IR Generator entirely.
> >
> > Change-Id: I09fc8220f8d5bf297033adbaf4c955f2ce0589cf
> > Bug: skia:11365, skia:11319
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375074
> > Commit-Queue: John Stiles <johnstiles@google.com>
> > Commit-Queue: Brian Osman <brianosman@google.com>
> > Auto-Submit: John Stiles <johnstiles@google.com>
> > Reviewed-by: Brian Osman <brianosman@google.com>
>
> TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com
>
> Change-Id: I3c3ffcac153faf068b0698ac2e32dbe4896e6ee4
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:11365
> Bug: skia:11319
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375677
> Reviewed-by: Mike Klein <mtklein@google.com>
> Commit-Queue: Mike Klein <mtklein@google.com>
Bug: skia:11365
Bug: skia:11319
Change-Id: Id8695d3b9ea5dd210ba3bc04e27a89212b0f7239
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375696
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index c9d2913..985c0ba 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -79,51 +79,9 @@
std::shared_ptr<SymbolTable> fPrevious;
};
-void IRGenerator::FillCapsMap(const SkSL::ShaderCapsClass& caps,
- std::unordered_map<String, CapsValue>* capsMap) {
-#define CAP(name) capsMap->insert({String(#name), CapsValue(caps.name())})
- CAP(fbFetchSupport);
- CAP(fbFetchNeedsCustomOutput);
- CAP(flatInterpolationSupport);
- CAP(noperspectiveInterpolationSupport);
- CAP(externalTextureSupport);
- CAP(mustEnableAdvBlendEqs);
- CAP(mustDeclareFragmentShaderOutput);
- CAP(mustDoOpBetweenFloorAndAbs);
- CAP(mustGuardDivisionEvenAfterExplicitZeroCheck);
- CAP(inBlendModesFailRandomlyForAllZeroVec);
- CAP(atan2ImplementedAsAtanYOverX);
- CAP(canUseAnyFunctionInShader);
- CAP(floatIs32Bits);
- CAP(integerSupport);
- CAP(builtinFMASupport);
- CAP(builtinDeterminantSupport);
-#undef CAP
-}
-
-std::unique_ptr<Expression> IRGenerator::CapsValue::literal(const Context& context,
- int offset) const {
- switch (fKind) {
- case kBool_Kind:
- return std::make_unique<BoolLiteral>(context, offset, fValue);
-
- case kInt_Kind:
- return std::make_unique<IntLiteral>(context, offset, fValue);
-
- case kFloat_Kind:
- return std::make_unique<FloatLiteral>(context, offset, fValueF);
-
- default:
- SkDEBUGFAILF("unrecognized caps kind: %d", fKind);
- return nullptr;
- }
-}
-
IRGenerator::IRGenerator(const Context* context)
: fContext(*context)
- , fModifiers(new ModifiersPool()) {
- FillCapsMap(context->fCaps, &fCapsMap);
-}
+ , fModifiers(new ModifiersPool()) {}
void IRGenerator::pushSymbolTable() {
auto childSymTable = std::make_shared<SymbolTable>(std::move(fSymbolTable), fIsBuiltinCode);
@@ -2388,30 +2346,6 @@
: Swizzle::Make(fContext, std::move(base), components);
}
-const Type* IRGenerator::typeForSetting(int offset, String name) const {
- auto found = fCapsMap.find(name);
- if (found == fCapsMap.end()) {
- this->errorReporter().error(offset, "unknown capability flag '" + name + "'");
- return nullptr;
- }
- switch (found->second.fKind) {
- case CapsValue::kBool_Kind: return fContext.fTypes.fBool.get();
- case CapsValue::kFloat_Kind: return fContext.fTypes.fFloat.get();
- case CapsValue::kInt_Kind: return fContext.fTypes.fInt.get();
- }
- SkUNREACHABLE;
- return nullptr;
-}
-
-std::unique_ptr<Expression> IRGenerator::valueForSetting(int offset, String name) const {
- auto found = fCapsMap.find(name);
- if (found == fCapsMap.end()) {
- this->errorReporter().error(offset, "unknown capability flag '" + name + "'");
- return nullptr;
- }
- return found->second.literal(fContext, offset);
-}
-
std::unique_ptr<Expression> IRGenerator::convertTypeField(int offset, const Type& type,
StringFragment field) {
const ProgramElement* enumElement = nullptr;
@@ -2559,9 +2493,9 @@
const Type& baseType = base->type();
if (baseType == *fContext.fTypes.fSkCaps) {
if (this->settings().fReplaceSettings && !fIsBuiltinCode) {
- return this->valueForSetting(fieldNode.fOffset, field);
+ return Setting::GetValue(fContext, fieldNode.fOffset, field);
}
- const Type* type = this->typeForSetting(fieldNode.fOffset, field);
+ const Type* type = Setting::GetType(fContext, fieldNode.fOffset, field);
if (!type) {
return nullptr;
}
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 6810253..8a59453 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -126,10 +126,6 @@
size_t length,
const std::vector<std::unique_ptr<ExternalFunction>>* externalFunctions);
- // both of these functions return null and report an error if the setting does not exist
- const Type* typeForSetting(int offset, String name) const;
- std::unique_ptr<Expression> valueForSetting(int offset, String name) const;
-
const Program::Settings& settings() const { return fContext.fConfig->fSettings; }
ProgramKind programKind() const { return fContext.fConfig->fKind; }
@@ -278,30 +274,6 @@
std::unique_ptr<ASTFile> fFile;
- struct CapsValue {
- CapsValue(bool b) : fKind(kBool_Kind), fValue(b) {}
- CapsValue(int i) : fKind(kInt_Kind), fValue(i) {}
- CapsValue(unsigned int i) : fKind(kInt_Kind), fValue(i) {}
- CapsValue(float f) : fKind(kFloat_Kind), fValueF(f) {}
-
- std::unique_ptr<Expression> literal(const Context& context, int offset) const;
-
- enum {
- kBool_Kind,
- kInt_Kind,
- kFloat_Kind,
- } fKind;
-
- union {
- int fValue; // for kBool_Kind and kInt_Kind
- float fValueF; // for kFloat_Kind
- };
- };
-
- static void FillCapsMap(const SkSL::ShaderCapsClass& caps,
- std::unordered_map<String, CapsValue>* capsMap);
-
- std::unordered_map<String, CapsValue> fCapsMap;
std::shared_ptr<SymbolTable> fSymbolTable = nullptr;
// additional statements that need to be inserted before the one that convertStatement is
// currently working on
diff --git a/src/sksl/ir/SkSLSetting.cpp b/src/sksl/ir/SkSLSetting.cpp
index f3ac3f6..65841b4 100644
--- a/src/sksl/ir/SkSLSetting.cpp
+++ b/src/sksl/ir/SkSLSetting.cpp
@@ -11,10 +11,119 @@
namespace SkSL {
+// Helper classes for converting caps fields to Expressions and Types in the CapsLookupTable.
+namespace {
+
+class CapsLookupMethod {
+public:
+ virtual ~CapsLookupMethod() {}
+ virtual const Type* type(const Context& context) const = 0;
+ virtual std::unique_ptr<Expression> value(const Context& context) const = 0;
+};
+
+class BoolCapsLookup : public CapsLookupMethod {
+public:
+ using CapsFn = bool (ShaderCapsClass::*)() const;
+
+ BoolCapsLookup(const CapsFn& fn) : fGetCap(fn) {}
+
+ const Type* type(const Context& context) const override {
+ return context.fTypes.fBool.get();
+ }
+ std::unique_ptr<Expression> value(const Context& context) const override {
+ return std::make_unique<BoolLiteral>(context, /*offset=*/-1, (context.fCaps.*fGetCap)());
+ }
+
+private:
+ CapsFn fGetCap;
+};
+
+class IntCapsLookup : public CapsLookupMethod {
+public:
+ using CapsFn = int (ShaderCapsClass::*)() const;
+
+ IntCapsLookup(const CapsFn& fn) : fGetCap(fn) {}
+
+ const Type* type(const Context& context) const override {
+ return context.fTypes.fInt.get();
+ }
+ std::unique_ptr<Expression> value(const Context& context) const override {
+ return std::make_unique<IntLiteral>(context, /*offset=*/-1, (context.fCaps.*fGetCap)());
+ }
+
+private:
+ CapsFn fGetCap;
+};
+
+class CapsLookupTable {
+public:
+ using Pair = std::pair<const char*, CapsLookupMethod*>;
+
+ CapsLookupTable(std::initializer_list<Pair> capsLookups) {
+ for (auto& entry : capsLookups) {
+ fMap[entry.first] = std::unique_ptr<CapsLookupMethod>(entry.second);
+ }
+ }
+
+ const CapsLookupMethod* lookup(const String& name) const {
+ auto iter = fMap.find(name);
+ return (iter != fMap.end()) ? iter->second.get() : nullptr;
+ }
+
+private:
+ std::unordered_map<String, std::unique_ptr<CapsLookupMethod>> fMap;
+};
+
+static const CapsLookupTable& caps_lookup_table() {
+ // Create a lookup table that converts strings into the equivalent ShaderCapsClass methods.
+ static CapsLookupTable* sCapsLookupTable = new CapsLookupTable({
+ #define CAP(T, name) CapsLookupTable::Pair{#name, new T##CapsLookup{&ShaderCapsClass::name}}
+ CAP(Bool, fbFetchSupport),
+ CAP(Bool, fbFetchNeedsCustomOutput),
+ CAP(Bool, flatInterpolationSupport),
+ CAP(Bool, noperspectiveInterpolationSupport),
+ CAP(Bool, externalTextureSupport),
+ CAP(Bool, mustEnableAdvBlendEqs),
+ CAP(Bool, mustDeclareFragmentShaderOutput),
+ CAP(Bool, mustDoOpBetweenFloorAndAbs),
+ CAP(Bool, mustGuardDivisionEvenAfterExplicitZeroCheck),
+ CAP(Bool, inBlendModesFailRandomlyForAllZeroVec),
+ CAP(Bool, atan2ImplementedAsAtanYOverX),
+ CAP(Bool, canUseAnyFunctionInShader),
+ CAP(Bool, floatIs32Bits),
+ CAP(Bool, integerSupport),
+ CAP(Bool, builtinFMASupport),
+ CAP(Bool, builtinDeterminantSupport),
+ #undef CAP
+ });
+ return *sCapsLookupTable;
+}
+
+} // namespace
+
+const Type* Setting::GetType(const Context& context, int offset, const String& name) {
+ if (const CapsLookupMethod* caps = caps_lookup_table().lookup(name)) {
+ return caps->type(context);
+ }
+
+ context.fErrors.error(offset, "unknown capability flag '" + name + "'");
+ return nullptr;
+}
+
+std::unique_ptr<Expression> Setting::GetValue(const Context& context, int offset,
+ const String& name) {
+ if (const CapsLookupMethod* caps = caps_lookup_table().lookup(name)) {
+ return caps->value(context);
+ }
+
+ context.fErrors.error(offset, "unknown capability flag '" + name + "'");
+ return nullptr;
+}
+
std::unique_ptr<Expression> Setting::constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) {
- if (irGenerator.settings().fReplaceSettings) {
- return irGenerator.valueForSetting(this->fOffset, this->name());
+ if (irGenerator.fContext.fConfig->fSettings.fReplaceSettings) {
+ return GetValue(irGenerator.fContext, fOffset, this->name());
}
return nullptr;
}
diff --git a/src/sksl/ir/SkSLSetting.h b/src/sksl/ir/SkSLSetting.h
index f4bcee5..8ffe827 100644
--- a/src/sksl/ir/SkSLSetting.h
+++ b/src/sksl/ir/SkSLSetting.h
@@ -25,6 +25,11 @@
: INHERITED(offset, kExpressionKind, type)
, fName(std::move(name)) {}
+ static const Type* GetType(const Context& context, int offset, const String& name);
+
+ static std::unique_ptr<Expression> GetValue(const Context& context, int offset,
+ const String& name);
+
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override;