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>
This commit is contained in:
John Stiles 2021-02-24 15:51:01 -05:00 committed by Skia Commit-Bot
parent 029851d951
commit c5ab6fe388
4 changed files with 116 additions and 110 deletions

View File

@ -79,90 +79,6 @@ public:
std::shared_ptr<SymbolTable> fPrevious;
};
// Helper classes for converting caps fields to Expressions and Types in the CapsLookupTable.
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;
};
// Create a lookup table at startup that converts strings into the equivalent ShaderCapsClass
// methods.
static CapsLookupTable sCapsLookupTable{{
#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
}};
IRGenerator::IRGenerator(const Context* context)
: fContext(*context)
, fModifiers(new ModifiersPool()) {}
@ -2430,24 +2346,6 @@ std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi
: Swizzle::Make(fContext, std::move(base), components);
}
const Type* IRGenerator::typeForSetting(int offset, String name) const {
if (const CapsLookupMethod* caps = sCapsLookupTable.lookup(name)) {
return caps->type(fContext);
}
this->errorReporter().error(offset, "unknown capability flag '" + name + "'");
return nullptr;
}
std::unique_ptr<Expression> IRGenerator::valueForSetting(int offset, String name) const {
if (const CapsLookupMethod* caps = sCapsLookupTable.lookup(name)) {
return caps->value(fContext);
}
this->errorReporter().error(offset, "unknown capability flag '" + name + "'");
return nullptr;
}
std::unique_ptr<Expression> IRGenerator::convertTypeField(int offset, const Type& type,
StringFragment field) {
const ProgramElement* enumElement = nullptr;
@ -2595,9 +2493,9 @@ std::unique_ptr<Expression> IRGenerator::convertFieldExpression(const ASTNode& f
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;
}

View File

@ -126,10 +126,6 @@ public:
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; }

View File

@ -11,10 +11,117 @@
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;
};
// Create a lookup table at startup that converts strings into the equivalent ShaderCapsClass
// methods.
static CapsLookupTable sCapsLookupTable{{
#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
}};
} // namespace
const Type* Setting::GetType(const Context& context, int offset, const String& name) {
if (const CapsLookupMethod* caps = sCapsLookupTable.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 = sCapsLookupTable.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;
}

View File

@ -25,6 +25,11 @@ public:
: 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;