Use SkTHashMap/Set in the SPIRVCodeGenerator.
Change-Id: Iffc3b1febeae0c29d4c24a483f6c05a01ef363d7 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/515716 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
7d4e12544e
commit
9f67845661
@ -569,11 +569,11 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
|
||||
? MemoryLayout::Standard::k430_Standard
|
||||
: MemoryLayout::Standard::k140_Standard;
|
||||
std::string otherKey = type->displayName() + std::to_string(otherStd);
|
||||
SkASSERT(fTypeMap.find(otherKey) == fTypeMap.end());
|
||||
SkASSERT(!fTypeMap.find(otherKey));
|
||||
#endif
|
||||
}
|
||||
auto entry = fTypeMap.find(key);
|
||||
if (entry == fTypeMap.end()) {
|
||||
SpvId* entry = fTypeMap.find(key);
|
||||
if (!entry) {
|
||||
SpvId result = this->nextId(nullptr);
|
||||
switch (type->typeKind()) {
|
||||
case Type::TypeKind::kScalar:
|
||||
@ -669,7 +669,7 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
|
||||
fTypeMap[key] = result;
|
||||
return result;
|
||||
}
|
||||
return entry->second;
|
||||
return *entry;
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) {
|
||||
@ -682,8 +682,8 @@ SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) {
|
||||
key += std::to_string(this->getType(parameters[i]->type()));
|
||||
}
|
||||
key += ")";
|
||||
auto entry = fTypeMap.find(key);
|
||||
if (entry == fTypeMap.end()) {
|
||||
SpvId* entry = fTypeMap.find(key);
|
||||
if (!entry) {
|
||||
SpvId result = this->nextId(nullptr);
|
||||
int32_t length = 3 + (int32_t) parameters.size();
|
||||
SpvId returnType = this->getType(function.returnType());
|
||||
@ -720,10 +720,10 @@ SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) {
|
||||
for (SpvId id : parameterTypes) {
|
||||
this->writeWord(id, fConstantBuffer);
|
||||
}
|
||||
fTypeMap[key] = result;
|
||||
fTypeMap.set(key, result);
|
||||
return result;
|
||||
}
|
||||
return entry->second;
|
||||
return *entry;
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::getPointerType(const Type& type, SpvStorageClass_ storageClass) {
|
||||
@ -735,15 +735,15 @@ SpvId SPIRVCodeGenerator::getPointerType(const Type& rawType, const MemoryLayout
|
||||
const Type& type = this->getActualType(rawType);
|
||||
std::string key = type.displayName() + "*" + std::to_string(layout.fStd) +
|
||||
std::to_string(storageClass);
|
||||
auto entry = fTypeMap.find(key);
|
||||
if (entry == fTypeMap.end()) {
|
||||
SpvId* entry = fTypeMap.find(key);
|
||||
if (!entry) {
|
||||
SpvId result = this->nextId(nullptr);
|
||||
this->writeInstruction(SpvOpTypePointer, result, storageClass,
|
||||
this->getType(type), fConstantBuffer);
|
||||
fTypeMap[key] = result;
|
||||
fTypeMap.set(key, result);
|
||||
return result;
|
||||
}
|
||||
return entry->second;
|
||||
return *entry;
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, OutputStream& out) {
|
||||
@ -794,27 +794,26 @@ SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, OutputStream&
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, OutputStream& out) {
|
||||
const FunctionDeclaration& function = c.function();
|
||||
auto iter = fIntrinsicMap.find(function.intrinsicKind());
|
||||
if (iter == fIntrinsicMap.end()) {
|
||||
Intrinsic* intrinsic = fIntrinsicMap.find(function.intrinsicKind());
|
||||
if (!intrinsic) {
|
||||
fContext.fErrors->error(c.fLine, "unsupported intrinsic '" + function.description() + "'");
|
||||
return -1;
|
||||
}
|
||||
const ExpressionArray& arguments = c.arguments();
|
||||
const Intrinsic& intrinsic = iter->second;
|
||||
int32_t intrinsicId = intrinsic.floatOp;
|
||||
int32_t intrinsicId = intrinsic->floatOp;
|
||||
if (arguments.size() > 0) {
|
||||
const Type& type = arguments[0]->type();
|
||||
if (intrinsic.opKind == kSpecial_IntrinsicOpcodeKind || is_float(fContext, type)) {
|
||||
if (intrinsic->opKind == kSpecial_IntrinsicOpcodeKind || is_float(fContext, type)) {
|
||||
// Keep the default float op.
|
||||
} else if (is_signed(fContext, type)) {
|
||||
intrinsicId = intrinsic.signedOp;
|
||||
intrinsicId = intrinsic->signedOp;
|
||||
} else if (is_unsigned(fContext, type)) {
|
||||
intrinsicId = intrinsic.unsignedOp;
|
||||
intrinsicId = intrinsic->unsignedOp;
|
||||
} else if (is_bool(fContext, type)) {
|
||||
intrinsicId = intrinsic.boolOp;
|
||||
intrinsicId = intrinsic->boolOp;
|
||||
}
|
||||
}
|
||||
switch (intrinsic.opKind) {
|
||||
switch (intrinsic->opKind) {
|
||||
case kGLSL_STD_450_IntrinsicOpcodeKind: {
|
||||
SpvId result = this->nextId(&c.type());
|
||||
std::vector<SpvId> argumentIds;
|
||||
@ -1219,8 +1218,8 @@ SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, OutputStream&
|
||||
return this->writeIntrinsicCall(c, out);
|
||||
}
|
||||
const ExpressionArray& arguments = c.arguments();
|
||||
const auto& entry = fFunctionMap.find(&function);
|
||||
if (entry == fFunctionMap.end()) {
|
||||
SpvId* entry = fFunctionMap.find(&function);
|
||||
if (!entry) {
|
||||
fContext.fErrors->error(c.fLine, "function '" + function.description() +
|
||||
"' is not defined");
|
||||
return -1;
|
||||
@ -1236,7 +1235,7 @@ SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, OutputStream&
|
||||
this->writeOpCode(SpvOpFunctionCall, 4 + (int32_t) arguments.size(), out);
|
||||
this->writeWord(this->getType(c.type()), out);
|
||||
this->writeWord(result, out);
|
||||
this->writeWord(entry->second, out);
|
||||
this->writeWord(*entry, out);
|
||||
for (SpvId id : argumentIds) {
|
||||
this->writeWord(id, out);
|
||||
}
|
||||
@ -1264,19 +1263,20 @@ SpvId SPIRVCodeGenerator::writeConstantVector(const AnyConstructor& c) {
|
||||
}
|
||||
|
||||
// Check to see if we've already synthesized this vector constant.
|
||||
auto [iter, newlyCreated] = fVectorConstants.insert({key, (SpvId)-1});
|
||||
if (newlyCreated) {
|
||||
// Emit an OpConstantComposite instruction for this constant.
|
||||
SpvId result = this->nextId(&type);
|
||||
this->writeOpCode(SpvOpConstantComposite, 3 + type.columns(), fConstantBuffer);
|
||||
this->writeWord(key.fTypeId, fConstantBuffer);
|
||||
this->writeWord(result, fConstantBuffer);
|
||||
for (int i = 0; i < type.columns(); i++) {
|
||||
this->writeWord(key.fValueId[i], fConstantBuffer);
|
||||
}
|
||||
iter->second = result;
|
||||
if (SpvId* entry = fVectorConstants.find(key)) {
|
||||
return *entry;
|
||||
}
|
||||
return iter->second;
|
||||
|
||||
// Emit an OpConstantComposite instruction for this constant.
|
||||
SpvId result = this->nextId(&type);
|
||||
this->writeOpCode(SpvOpConstantComposite, 3 + type.columns(), fConstantBuffer);
|
||||
this->writeWord(key.fTypeId, fConstantBuffer);
|
||||
this->writeWord(result, fConstantBuffer);
|
||||
for (int i = 0; i < type.columns(); i++) {
|
||||
this->writeWord(key.fValueId[i], fConstantBuffer);
|
||||
}
|
||||
fVectorConstants.set(key, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::castScalarToType(SpvId inputExprId,
|
||||
@ -1974,8 +1974,8 @@ private:
|
||||
};
|
||||
|
||||
int SPIRVCodeGenerator::findUniformFieldIndex(const Variable& var) const {
|
||||
auto iter = fTopLevelUniformMap.find(&var);
|
||||
return (iter != fTopLevelUniformMap.end()) ? iter->second : -1;
|
||||
int* fieldIndex = fTopLevelUniformMap.find(&var);
|
||||
return fieldIndex ? *fieldIndex : -1;
|
||||
}
|
||||
|
||||
std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr,
|
||||
@ -1997,9 +1997,9 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
|
||||
this->getType(type), precision);
|
||||
}
|
||||
SpvId typeId = this->getType(type, this->memoryLayoutForVariable(var));
|
||||
auto entry = fVariableMap.find(&var);
|
||||
SkASSERTF(entry != fVariableMap.end(), "%s", expr.description().c_str());
|
||||
return std::make_unique<PointerLValue>(*this, entry->second,
|
||||
SpvId* entry = fVariableMap.find(&var);
|
||||
SkASSERTF(entry, "%s", expr.description().c_str());
|
||||
return std::make_unique<PointerLValue>(*this, *entry,
|
||||
/*isMemoryObjectPointer=*/true,
|
||||
typeId, precision);
|
||||
}
|
||||
@ -2096,7 +2096,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
fContext.fTypes.fFloat4.get(),
|
||||
/*builtin=*/true,
|
||||
Variable::Storage::kGlobal);
|
||||
fSPIRVBonusVariables.insert(coordsVar.get());
|
||||
fSPIRVBonusVariables.add(coordsVar.get());
|
||||
symbols.add(std::move(coordsVar));
|
||||
}
|
||||
DSLGlobalVar deviceCoord(DEVICE_COORDS_NAME);
|
||||
@ -2131,7 +2131,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
fContext.fTypes.fBool.get(),
|
||||
/*builtin=*/true,
|
||||
Variable::Storage::kGlobal);
|
||||
fSPIRVBonusVariables.insert(clockwiseVar.get());
|
||||
fSPIRVBonusVariables.add(clockwiseVar.get());
|
||||
symbols.add(std::move(clockwiseVar));
|
||||
}
|
||||
DSLGlobalVar deviceClockwise(DEVICE_CLOCKWISE_NAME);
|
||||
@ -2884,21 +2884,22 @@ SpvId SPIRVCodeGenerator::writeLiteral(double value, const Type& type) {
|
||||
}
|
||||
|
||||
SPIRVNumberConstant key{valueBits, type.numberKind()};
|
||||
auto [iter, newlyCreated] = fNumberConstants.insert({key, (SpvId)-1});
|
||||
if (newlyCreated) {
|
||||
SpvId result = this->nextId(nullptr);
|
||||
iter->second = result;
|
||||
|
||||
if (type.isBoolean()) {
|
||||
this->writeInstruction(valueBits ? SpvOpConstantTrue : SpvOpConstantFalse,
|
||||
this->getType(type), result, fConstantBuffer);
|
||||
} else {
|
||||
this->writeInstruction(SpvOpConstant, this->getType(type), result,
|
||||
(SpvId)valueBits, fConstantBuffer);
|
||||
}
|
||||
if (SpvId* entry = fNumberConstants.find(key)) {
|
||||
return *entry;
|
||||
}
|
||||
|
||||
return iter->second;
|
||||
SpvId result = this->nextId(nullptr);
|
||||
fNumberConstants.set(key, result);
|
||||
|
||||
if (type.isBoolean()) {
|
||||
this->writeInstruction(valueBits ? SpvOpConstantTrue : SpvOpConstantFalse,
|
||||
this->getType(type), result, fConstantBuffer);
|
||||
} else {
|
||||
this->writeInstruction(SpvOpConstant, this->getType(type), result,
|
||||
(SpvId)valueBits, fConstantBuffer);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, OutputStream& out) {
|
||||
@ -2914,7 +2915,7 @@ SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, Outpu
|
||||
fNameBuffer);
|
||||
for (const Variable* parameter : f.parameters()) {
|
||||
SpvId id = this->nextId(nullptr);
|
||||
fVariableMap[parameter] = id;
|
||||
fVariableMap.set(parameter, id);
|
||||
SpvId type = this->getPointerType(parameter->type(), SpvStorageClassFunction);
|
||||
this->writeInstruction(SpvOpFunctionParameter, type, id, out);
|
||||
}
|
||||
@ -3048,7 +3049,7 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool a
|
||||
rtFlipStructType,
|
||||
intfVar.isBuiltin(),
|
||||
intfVar.storage()));
|
||||
fSPIRVBonusVariables.insert(modifiedVar);
|
||||
fSPIRVBonusVariables.add(modifiedVar);
|
||||
InterfaceBlock modifiedCopy(intf.fLine,
|
||||
*modifiedVar,
|
||||
intf.typeName(),
|
||||
@ -3059,7 +3060,7 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool a
|
||||
fProgram.fSymbols->add(std::make_unique<Field>(
|
||||
/*line=*/-1, modifiedVar, rtFlipStructType->fields().size() - 1));
|
||||
}
|
||||
fVariableMap[&intfVar] = result;
|
||||
fVariableMap.set(&intfVar, result);
|
||||
fWroteRTFlip = true;
|
||||
return result;
|
||||
}
|
||||
@ -3076,14 +3077,14 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool a
|
||||
layout.fSet = fProgram.fConfig->fSettings.fDefaultUniformSet;
|
||||
}
|
||||
this->writeLayout(layout, result, intfVar.fLine);
|
||||
fVariableMap[&intfVar] = result;
|
||||
fVariableMap.set(&intfVar, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SPIRVCodeGenerator::isDead(const Variable& var) const {
|
||||
// During SPIR-V code generation, we synthesize some extra bonus variables that don't actually
|
||||
// exist in the Program at all and aren't tracked by the ProgramUsage. They aren't dead, though.
|
||||
if (fSPIRVBonusVariables.count(&var)) {
|
||||
if (fSPIRVBonusVariables.contains(&var)) {
|
||||
return false;
|
||||
}
|
||||
ProgramUsage::VariableCounts counts = fProgram.usage()->get(var);
|
||||
@ -3115,7 +3116,7 @@ void SPIRVCodeGenerator::writeGlobalVar(ProgramKind kind, const VarDeclaration&
|
||||
// Add this global to the variable map.
|
||||
const Type& type = var.type();
|
||||
SpvId id = this->nextId(&type);
|
||||
fVariableMap[&var] = id;
|
||||
fVariableMap.set(&var, id);
|
||||
if (var.modifiers().fLayout.fBuiltin == SK_SECONDARYFRAGCOLOR_BUILTIN) {
|
||||
// sk_SecondaryFragColor corresponds to gl_SecondaryFragColorEXT, which isn't supposed to
|
||||
// appear in a SPIR-V program (it's only valid in ES2). Report an error.
|
||||
@ -3149,7 +3150,7 @@ void SPIRVCodeGenerator::writeGlobalVar(ProgramKind kind, const VarDeclaration&
|
||||
void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl, OutputStream& out) {
|
||||
const Variable& var = varDecl.var();
|
||||
SpvId id = this->nextId(&var.type());
|
||||
fVariableMap[&var] = id;
|
||||
fVariableMap.set(&var, id);
|
||||
SpvId type = this->getPointerType(var.type(), SpvStorageClassFunction);
|
||||
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
|
||||
this->writeInstruction(SpvOpName, id, var.name(), fNameBuffer);
|
||||
@ -3437,10 +3438,9 @@ void SPIRVCodeGenerator::writeUniformBuffer(std::shared_ptr<SymbolTable> topLeve
|
||||
// a lookup table of variables to UniformBuffer field indices.
|
||||
std::vector<Type::Field> fields;
|
||||
fields.reserve(fTopLevelUniforms.size());
|
||||
fTopLevelUniformMap.reserve(fTopLevelUniforms.size());
|
||||
for (const VarDeclaration* topLevelUniform : fTopLevelUniforms) {
|
||||
const Variable* var = &topLevelUniform->var();
|
||||
fTopLevelUniformMap[var] = (int)fields.size();
|
||||
fTopLevelUniformMap.set(var, (int)fields.size());
|
||||
fields.emplace_back(var->modifiers(), var->name(), &var->type());
|
||||
}
|
||||
fUniformBuffer.fStruct = Type::MakeStructType(
|
||||
@ -3524,7 +3524,7 @@ void SPIRVCodeGenerator::addRTFlipUniform(int line) {
|
||||
intfStruct,
|
||||
/*builtin=*/false,
|
||||
Variable::Storage::kGlobal));
|
||||
fSPIRVBonusVariables.insert(intfVar);
|
||||
fSPIRVBonusVariables.add(intfVar);
|
||||
{
|
||||
AutoAttachPoolToThread attach(fProgram.fPool.get());
|
||||
fProgram.fSymbols->add(std::make_unique<Field>(/*line=*/-1, intfVar, /*field=*/0));
|
||||
@ -3548,7 +3548,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
if (e->is<FunctionDefinition>()) {
|
||||
const FunctionDefinition& funcDef = e->as<FunctionDefinition>();
|
||||
const FunctionDeclaration& funcDecl = funcDef.declaration();
|
||||
fFunctionMap[&funcDecl] = this->nextId(nullptr);
|
||||
fFunctionMap.set(&funcDecl, this->nextId(nullptr));
|
||||
if (funcDecl.isMain()) {
|
||||
main = &funcDecl;
|
||||
}
|
||||
@ -3590,7 +3590,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
if (main->returnType().matches(*fContext.fTypes.fHalf4)) {
|
||||
adapter = this->writeEntrypointAdapter(*main);
|
||||
if (adapter.entrypointDecl) {
|
||||
fFunctionMap[adapter.entrypointDecl.get()] = this->nextId(nullptr);
|
||||
fFunctionMap.set(adapter.entrypointDecl.get(), this->nextId(nullptr));
|
||||
this->writeFunction(*adapter.entrypointDef, body);
|
||||
main = adapter.entrypointDecl.get();
|
||||
}
|
||||
@ -3602,12 +3602,11 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
}
|
||||
}
|
||||
// Add global in/out variables to the list of interface variables.
|
||||
for (auto entry : fVariableMap) {
|
||||
const Variable* var = entry.first;
|
||||
for (const auto& [var, spvId] : fVariableMap) {
|
||||
if (var->storage() == Variable::Storage::kGlobal &&
|
||||
(var->modifiers().fFlags & (Modifiers::kIn_Flag | Modifiers::kOut_Flag)) &&
|
||||
!this->isDead(*var)) {
|
||||
interfaceVars.insert(entry.second);
|
||||
interfaceVars.insert(spvId);
|
||||
}
|
||||
}
|
||||
this->writeCapabilities(out);
|
||||
|
@ -9,9 +9,8 @@
|
||||
#define SKSL_SPIRVCODEGENERATOR
|
||||
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "include/private/SkTHash.h"
|
||||
#include "src/core/SkOpts.h"
|
||||
#include "src/sksl/SkSLMemoryLayout.h"
|
||||
#include "src/sksl/SkSLStringStream.h"
|
||||
@ -58,6 +57,12 @@ struct SPIRVNumberConstant {
|
||||
}
|
||||
int32_t fValueBits;
|
||||
SkSL::Type::NumberKind fKind;
|
||||
|
||||
struct Hash {
|
||||
uint32_t operator()(const SPIRVNumberConstant& key) const {
|
||||
return key.fValueBits ^ (int)key.fKind;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct SPIRVVectorConstant {
|
||||
@ -70,30 +75,14 @@ struct SPIRVVectorConstant {
|
||||
}
|
||||
SpvId fTypeId;
|
||||
SpvId fValueId[4];
|
||||
|
||||
struct Hash {
|
||||
uint32_t operator()(const SPIRVVectorConstant& key) const {
|
||||
return SkOpts::hash(&key, sizeof(key));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<SkSL::SPIRVNumberConstant> {
|
||||
size_t operator()(const SkSL::SPIRVNumberConstant& key) const {
|
||||
return key.fValueBits ^ (int)key.fKind;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<SkSL::SPIRVVectorConstant> {
|
||||
size_t operator()(const SkSL::SPIRVVectorConstant& key) const {
|
||||
return SkOpts::hash(&key, sizeof(key));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Converts a Program into a SPIR-V binary.
|
||||
*/
|
||||
@ -483,18 +472,18 @@ private:
|
||||
int32_t unsignedOp;
|
||||
int32_t boolOp;
|
||||
};
|
||||
std::unordered_map<IntrinsicKind, Intrinsic> fIntrinsicMap;
|
||||
std::unordered_map<const FunctionDeclaration*, SpvId> fFunctionMap;
|
||||
std::unordered_map<const Variable*, SpvId> fVariableMap;
|
||||
std::unordered_map<std::string, SpvId> fTypeMap;
|
||||
SkTHashMap<IntrinsicKind, Intrinsic> fIntrinsicMap;
|
||||
SkTHashMap<const FunctionDeclaration*, SpvId> fFunctionMap;
|
||||
SkTHashMap<const Variable*, SpvId> fVariableMap;
|
||||
SkTHashMap<std::string, SpvId> fTypeMap;
|
||||
StringStream fGlobalInitializersBuffer;
|
||||
StringStream fConstantBuffer;
|
||||
StringStream fVariableBuffer;
|
||||
StringStream fNameBuffer;
|
||||
StringStream fDecorationBuffer;
|
||||
|
||||
std::unordered_map<SPIRVNumberConstant, SpvId> fNumberConstants;
|
||||
std::unordered_map<SPIRVVectorConstant, SpvId> fVectorConstants;
|
||||
SkTHashMap<SPIRVNumberConstant, SpvId, SPIRVNumberConstant::Hash> fNumberConstants;
|
||||
SkTHashMap<SPIRVVectorConstant, SpvId, SPIRVVectorConstant::Hash> fVectorConstants;
|
||||
// label of the current block, or 0 if we are not in a block
|
||||
SpvId fCurrentBlock;
|
||||
std::stack<SpvId> fBreakTarget;
|
||||
@ -506,8 +495,8 @@ private:
|
||||
// interface block.
|
||||
UniformBuffer fUniformBuffer;
|
||||
std::vector<const VarDeclaration*> fTopLevelUniforms;
|
||||
std::unordered_map<const Variable*, int> fTopLevelUniformMap; //<var, UniformBuffer field index>
|
||||
std::unordered_set<const Variable*> fSPIRVBonusVariables;
|
||||
SkTHashMap<const Variable*, int> fTopLevelUniformMap; // <var, UniformBuffer field index>
|
||||
SkTHashSet<const Variable*> fSPIRVBonusVariables;
|
||||
SpvId fUniformBufferId = -1;
|
||||
|
||||
friend class PointerLValue;
|
||||
|
Loading…
Reference in New Issue
Block a user