Revert "Remove CapsMap from IR Generator."

This reverts commit 6394bb43cb.

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>
This commit is contained in:
Mike Klein 2021-02-25 13:22:57 +00:00 committed by Skia Commit-Bot
parent 4903482a2a
commit 45c57e116e
2 changed files with 80 additions and 92 deletions

View File

@ -79,93 +79,51 @@ 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),
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()) {}
, fModifiers(new ModifiersPool()) {
FillCapsMap(context->fCaps, &fCapsMap);
}
void IRGenerator::pushSymbolTable() {
auto childSymTable = std::make_shared<SymbolTable>(std::move(fSymbolTable), fIsBuiltinCode);
@ -2431,21 +2389,27 @@ std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi
}
const Type* IRGenerator::typeForSetting(int offset, String name) const {
if (const CapsLookupMethod* caps = sCapsLookupTable.lookup(name)) {
return caps->type(fContext);
auto found = fCapsMap.find(name);
if (found == fCapsMap.end()) {
this->errorReporter().error(offset, "unknown capability flag '" + name + "'");
return nullptr;
}
this->errorReporter().error(offset, "unknown capability flag '" + name + "'");
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 {
if (const CapsLookupMethod* caps = sCapsLookupTable.lookup(name)) {
return caps->value(fContext);
auto found = fCapsMap.find(name);
if (found == fCapsMap.end()) {
this->errorReporter().error(offset, "unknown capability flag '" + name + "'");
return nullptr;
}
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,

View File

@ -278,6 +278,30 @@ private:
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