moved SkSL VarDeclarations data into IRNode
Change-Id: I03bdef43c79bc3c997f9a9a6aa8fbb1a7194943a Reviewed-on: https://skia-review.googlesource.com/c/skia/+/326437 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
df5739ce3f
commit
c51f33e784
@ -154,9 +154,10 @@ SkRuntimeEffect::EffectResult SkRuntimeEffect::Make(SkString sksl) {
|
|||||||
for (const auto& elem : program->elements()) {
|
for (const auto& elem : program->elements()) {
|
||||||
// Variables (uniform, varying, etc.)
|
// Variables (uniform, varying, etc.)
|
||||||
if (elem->is<SkSL::GlobalVarDeclaration>()) {
|
if (elem->is<SkSL::GlobalVarDeclaration>()) {
|
||||||
const auto& varDecl = elem->as<SkSL::GlobalVarDeclaration>().fDecl;
|
const SkSL::GlobalVarDeclaration& global = elem->as<SkSL::GlobalVarDeclaration>();
|
||||||
|
const SkSL::VarDeclaration& varDecl = global.declaration()->as<SkSL::VarDeclaration>();
|
||||||
|
|
||||||
const SkSL::Variable& var = *varDecl->fVar;
|
const SkSL::Variable& var = varDecl.var();
|
||||||
const SkSL::Type& varType = var.type();
|
const SkSL::Type& varType = var.type();
|
||||||
|
|
||||||
// Varyings (only used in conjunction with drawVertices)
|
// Varyings (only used in conjunction with drawVertices)
|
||||||
|
@ -479,12 +479,12 @@ bool TProgramVisitor<PROG, EXPR, STMT, ELEM>::visitStatement(STMT s) {
|
|||||||
}
|
}
|
||||||
case Statement::Kind::kVarDeclaration: {
|
case Statement::Kind::kVarDeclaration: {
|
||||||
auto& v = s.template as<VarDeclaration>();
|
auto& v = s.template as<VarDeclaration>();
|
||||||
for (auto& sizeExpr : v.fSizes) {
|
for (int i = 0; i < v.sizeCount(); ++i) {
|
||||||
if (sizeExpr && this->visitExpression(*sizeExpr)) {
|
if (v.size(i) && this->visitExpression(*v.size(i))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v.fValue && this->visitExpression(*v.fValue);
|
return v.value() && this->visitExpression(*v.value());
|
||||||
}
|
}
|
||||||
case Statement::Kind::kWhile: {
|
case Statement::Kind::kWhile: {
|
||||||
auto& w = s.template as<WhileStatement>();
|
auto& w = s.template as<WhileStatement>();
|
||||||
@ -517,7 +517,7 @@ bool TProgramVisitor<PROG, EXPR, STMT, ELEM>::visitProgramElement(ELEM pe) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
case ProgramElement::Kind::kGlobalVar:
|
case ProgramElement::Kind::kGlobalVar:
|
||||||
if (this->visitStatement(*pe.template as<GlobalVarDeclaration>().fDecl)) {
|
if (this->visitStatement(*pe.template as<GlobalVarDeclaration>().declaration())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -161,17 +161,17 @@ bool ByteCodeGenerator::generateCode() {
|
|||||||
}
|
}
|
||||||
case ProgramElement::Kind::kGlobalVar: {
|
case ProgramElement::Kind::kGlobalVar: {
|
||||||
const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
|
||||||
const Variable* declVar = decl.fDecl->fVar;
|
const Variable& declVar = decl.declaration()->as<VarDeclaration>().var();
|
||||||
if (declVar->type() == *fContext.fFragmentProcessor_Type) {
|
if (declVar.type() == *fContext.fFragmentProcessor_Type) {
|
||||||
fOutput->fChildFPCount++;
|
fOutput->fChildFPCount++;
|
||||||
}
|
}
|
||||||
if (declVar->modifiers().fLayout.fBuiltin >= 0 || is_in(*declVar)) {
|
if (declVar.modifiers().fLayout.fBuiltin >= 0 || is_in(declVar)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_uniform(*declVar)) {
|
if (is_uniform(declVar)) {
|
||||||
this->gatherUniforms(declVar->type(), declVar->name());
|
this->gatherUniforms(declVar.type(), declVar.name());
|
||||||
} else {
|
} else {
|
||||||
fOutput->fGlobalSlotCount += SlotCount(declVar->type());
|
fOutput->fGlobalSlotCount += SlotCount(declVar.type());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -457,11 +457,11 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
|
|||||||
for (const auto& e : fProgram.elements()) {
|
for (const auto& e : fProgram.elements()) {
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
|
||||||
const Variable* declVar = decl.fDecl->fVar;
|
const Variable& declVar = decl.declaration()->as<VarDeclaration>().var();
|
||||||
if (declVar->type() != *fContext.fFragmentProcessor_Type) {
|
if (declVar.type() != *fContext.fFragmentProcessor_Type) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (declVar == &var) {
|
if (&declVar == &var) {
|
||||||
SkASSERT(offset <= 255);
|
SkASSERT(offset <= 255);
|
||||||
return { offset, Storage::kChildFP };
|
return { offset, Storage::kChildFP };
|
||||||
}
|
}
|
||||||
@ -485,18 +485,18 @@ ByteCodeGenerator::Location ByteCodeGenerator::getLocation(const Variable& var)
|
|||||||
for (const auto& e : fProgram.elements()) {
|
for (const auto& e : fProgram.elements()) {
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
|
||||||
const Variable* declVar = decl.fDecl->fVar;
|
const Variable& declVar = decl.declaration()->as<VarDeclaration>().var();
|
||||||
if (declVar->modifiers().fLayout.fBuiltin >= 0 || is_in(*declVar)) {
|
if (declVar.modifiers().fLayout.fBuiltin >= 0 || is_in(declVar)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isUniform != is_uniform(*declVar)) {
|
if (isUniform != is_uniform(declVar)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (declVar == &var) {
|
if (&declVar == &var) {
|
||||||
SkASSERT(offset <= 255);
|
SkASSERT(offset <= 255);
|
||||||
return { offset, isUniform ? Storage::kUniform : Storage::kGlobal };
|
return { offset, isUniform ? Storage::kUniform : Storage::kGlobal };
|
||||||
}
|
}
|
||||||
offset += SlotCount(declVar->type());
|
offset += SlotCount(declVar.type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SkASSERT(false);
|
SkASSERT(false);
|
||||||
@ -1762,10 +1762,10 @@ void ByteCodeGenerator::writeSwitchStatement(const SwitchStatement& r) {
|
|||||||
|
|
||||||
void ByteCodeGenerator::writeVarDeclaration(const VarDeclaration& decl) {
|
void ByteCodeGenerator::writeVarDeclaration(const VarDeclaration& decl) {
|
||||||
// we need to grab the location even if we don't use it, to ensure it has been allocated
|
// we need to grab the location even if we don't use it, to ensure it has been allocated
|
||||||
Location location = this->getLocation(*decl.fVar);
|
Location location = this->getLocation(decl.var());
|
||||||
if (decl.fValue) {
|
if (decl.value()) {
|
||||||
this->writeExpression(*decl.fValue);
|
this->writeExpression(*decl.value());
|
||||||
int count = SlotCount(decl.fValue->type());
|
int count = SlotCount(decl.value()->type());
|
||||||
this->write(ByteCodeInstruction::kStore, count);
|
this->write(ByteCodeInstruction::kStore, count);
|
||||||
this->write8(location.fSlot);
|
this->write8(location.fSlot);
|
||||||
}
|
}
|
||||||
|
@ -513,8 +513,8 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
|
|||||||
}
|
}
|
||||||
case Statement::Kind::kVarDeclaration: {
|
case Statement::Kind::kVarDeclaration: {
|
||||||
VarDeclaration& vd = (*s)->as<VarDeclaration>();
|
VarDeclaration& vd = (*s)->as<VarDeclaration>();
|
||||||
if (vd.fValue) {
|
if (vd.value()) {
|
||||||
this->addExpression(cfg, &vd.fValue, /*constantPropagate=*/true);
|
this->addExpression(cfg, &vd.value(), /*constantPropagate=*/true);
|
||||||
}
|
}
|
||||||
cfg.currentBlock().fNodes.push_back(BasicBlock::MakeStatement(s));
|
cfg.currentBlock().fNodes.push_back(BasicBlock::MakeStatement(s));
|
||||||
break;
|
break;
|
||||||
|
@ -415,10 +415,11 @@ int CPPCodeGenerator::getChildFPIndex(const Variable& var) const {
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const VarDeclaration& decl =
|
||||||
if (decl.fVar == &var) {
|
p->as<GlobalVarDeclaration>().declaration()->as<VarDeclaration>();
|
||||||
|
if (&decl.var() == &var) {
|
||||||
return index;
|
return index;
|
||||||
} else if (decl.fVar->type().nonnullable() == *fContext.fFragmentProcessor_Type) {
|
} else if (decl.var().type().nonnullable() == *fContext.fFragmentProcessor_Type) {
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,7 +661,7 @@ void CPPCodeGenerator::writeProgramElement(const ProgramElement& p) {
|
|||||||
return;
|
return;
|
||||||
case ProgramElement::Kind::kGlobalVar: {
|
case ProgramElement::Kind::kGlobalVar: {
|
||||||
const GlobalVarDeclaration& decl = p.as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decl = p.as<GlobalVarDeclaration>();
|
||||||
const Variable& var = *decl.fDecl->fVar;
|
const Variable& var = decl.declaration()->as<VarDeclaration>().var();
|
||||||
if (var.modifiers().fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
|
if (var.modifiers().fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
|
||||||
-1 != var.modifiers().fLayout.fBuiltin) {
|
-1 != var.modifiers().fLayout.fBuiltin) {
|
||||||
return;
|
return;
|
||||||
@ -706,27 +707,27 @@ void CPPCodeGenerator::writeInputVars() {
|
|||||||
void CPPCodeGenerator::writePrivateVars() {
|
void CPPCodeGenerator::writePrivateVars() {
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
|
||||||
if (is_private(*decl.fVar)) {
|
const Variable& var = global.declaration()->as<VarDeclaration>().var();
|
||||||
if (decl.fVar->type() == *fContext.fFragmentProcessor_Type) {
|
if (is_private(var)) {
|
||||||
fErrors.error(decl.fOffset,
|
if (var.type() == *fContext.fFragmentProcessor_Type) {
|
||||||
|
fErrors.error(global.fOffset,
|
||||||
"fragmentProcessor variables must be declared 'in'");
|
"fragmentProcessor variables must be declared 'in'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->writef("%s %s = %s;\n",
|
this->writef("%s %s = %s;\n",
|
||||||
HCodeGenerator::FieldType(fContext, decl.fVar->type(),
|
HCodeGenerator::FieldType(fContext, var.type(),
|
||||||
decl.fVar->modifiers().fLayout)
|
var.modifiers().fLayout).c_str(),
|
||||||
.c_str(),
|
String(var.name()).c_str(),
|
||||||
String(decl.fVar->name()).c_str(),
|
default_value(var).c_str());
|
||||||
default_value(*decl.fVar).c_str());
|
} else if (var.modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
|
||||||
} else if (decl.fVar->modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
|
|
||||||
// An auto-tracked uniform in variable, so add a field to hold onto the prior
|
// An auto-tracked uniform in variable, so add a field to hold onto the prior
|
||||||
// state. Note that tracked variables must be uniform in's and that is validated
|
// state. Note that tracked variables must be uniform in's and that is validated
|
||||||
// before writePrivateVars() is called.
|
// before writePrivateVars() is called.
|
||||||
const UniformCTypeMapper* mapper = UniformCTypeMapper::Get(fContext, *decl.fVar);
|
const UniformCTypeMapper* mapper = UniformCTypeMapper::Get(fContext, var);
|
||||||
SkASSERT(mapper && mapper->supportsTracking());
|
SkASSERT(mapper && mapper->supportsTracking());
|
||||||
|
|
||||||
String name = HCodeGenerator::FieldName(String(decl.fVar->name()).c_str());
|
String name = HCodeGenerator::FieldName(String(var.name()).c_str());
|
||||||
// The member statement is different if the mapper reports a default value
|
// The member statement is different if the mapper reports a default value
|
||||||
if (mapper->defaultValue().size() > 0) {
|
if (mapper->defaultValue().size() > 0) {
|
||||||
this->writef("%s %sPrev = %s;\n",
|
this->writef("%s %sPrev = %s;\n",
|
||||||
@ -744,11 +745,12 @@ void CPPCodeGenerator::writePrivateVars() {
|
|||||||
void CPPCodeGenerator::writePrivateVarValues() {
|
void CPPCodeGenerator::writePrivateVarValues() {
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
|
||||||
if (is_private(*decl.fVar) && decl.fValue) {
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
this->writef("%s = ", String(decl.fVar->name()).c_str());
|
if (is_private(decl.var()) && decl.value()) {
|
||||||
|
this->writef("%s = ", String(decl.var().name()).c_str());
|
||||||
fCPPMode = true;
|
fCPPMode = true;
|
||||||
this->writeExpression(*decl.fValue, kAssignment_Precedence);
|
this->writeExpression(*decl.value(), kAssignment_Precedence);
|
||||||
fCPPMode = false;
|
fCPPMode = false;
|
||||||
this->write(";\n");
|
this->write(";\n");
|
||||||
}
|
}
|
||||||
@ -958,11 +960,12 @@ bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
|
|||||||
fFullName.c_str(), fFullName.c_str());
|
fFullName.c_str(), fFullName.c_str());
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
|
||||||
String nameString(decl.fVar->name());
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
|
String nameString(decl.var().name());
|
||||||
const char* name = nameString.c_str();
|
const char* name = nameString.c_str();
|
||||||
if (SectionAndParameterHelper::IsParameter(*decl.fVar) &&
|
if (SectionAndParameterHelper::IsParameter(decl.var()) &&
|
||||||
is_accessible(*decl.fVar)) {
|
is_accessible(decl.var())) {
|
||||||
this->writef(" auto %s = _outer.%s;\n"
|
this->writef(" auto %s = _outer.%s;\n"
|
||||||
" (void) %s;\n",
|
" (void) %s;\n",
|
||||||
name, name, name);
|
name, name, name);
|
||||||
@ -1071,8 +1074,9 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
|||||||
int samplerIndex = 0;
|
int samplerIndex = 0;
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
|
||||||
const Variable& variable = *decl.fVar;
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
|
const Variable& variable = decl.var();
|
||||||
String nameString(variable.name());
|
String nameString(variable.name());
|
||||||
const char* name = nameString.c_str();
|
const char* name = nameString.c_str();
|
||||||
if (variable.type().typeKind() == Type::TypeKind::kSampler) {
|
if (variable.type().typeKind() == Type::TypeKind::kSampler) {
|
||||||
@ -1244,8 +1248,9 @@ void CPPCodeGenerator::writeGetKey() {
|
|||||||
fFullName.c_str());
|
fFullName.c_str());
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
|
||||||
const Variable& var = *decl.fVar;
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
|
const Variable& var = decl.var();
|
||||||
const Type& varType = var.type();
|
const Type& varType = var.type();
|
||||||
String nameString(var.name());
|
String nameString(var.name());
|
||||||
const char* name = nameString.c_str();
|
const char* name = nameString.c_str();
|
||||||
@ -1260,9 +1265,9 @@ void CPPCodeGenerator::writeGetKey() {
|
|||||||
HCodeGenerator::FieldType(fContext, varType,
|
HCodeGenerator::FieldType(fContext, varType,
|
||||||
var.modifiers().fLayout).c_str(),
|
var.modifiers().fLayout).c_str(),
|
||||||
String(var.name()).c_str());
|
String(var.name()).c_str());
|
||||||
if (decl.fValue) {
|
if (decl.value()) {
|
||||||
fCPPMode = true;
|
fCPPMode = true;
|
||||||
this->writeExpression(*decl.fValue, kAssignment_Precedence);
|
this->writeExpression(*decl.value(), kAssignment_Precedence);
|
||||||
fCPPMode = false;
|
fCPPMode = false;
|
||||||
} else {
|
} else {
|
||||||
this->writef("%s", default_value(var).c_str());
|
this->writef("%s", default_value(var).c_str());
|
||||||
@ -1318,25 +1323,26 @@ bool CPPCodeGenerator::generateCode() {
|
|||||||
std::vector<const Variable*> uniforms;
|
std::vector<const Variable*> uniforms;
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
|
||||||
if ((decl.fVar->modifiers().fFlags & Modifiers::kUniform_Flag) &&
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
decl.fVar->type().typeKind() != Type::TypeKind::kSampler) {
|
if ((decl.var().modifiers().fFlags & Modifiers::kUniform_Flag) &&
|
||||||
uniforms.push_back(decl.fVar);
|
decl.var().type().typeKind() != Type::TypeKind::kSampler) {
|
||||||
|
uniforms.push_back(&decl.var());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_uniform_in(*decl.fVar)) {
|
if (is_uniform_in(decl.var())) {
|
||||||
// Validate the "uniform in" declarations to make sure they are fully supported,
|
// Validate the "uniform in" declarations to make sure they are fully supported,
|
||||||
// instead of generating surprising C++
|
// instead of generating surprising C++
|
||||||
const UniformCTypeMapper* mapper =
|
const UniformCTypeMapper* mapper =
|
||||||
UniformCTypeMapper::Get(fContext, *decl.fVar);
|
UniformCTypeMapper::Get(fContext, decl.var());
|
||||||
if (mapper == nullptr) {
|
if (mapper == nullptr) {
|
||||||
fErrors.error(decl.fOffset, String(decl.fVar->name())
|
fErrors.error(decl.fOffset, String(decl.var().name())
|
||||||
+ "'s type is not supported for use as a 'uniform in'");
|
+ "'s type is not supported for use as a 'uniform in'");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (decl.fVar->modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
|
if (decl.var().modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
|
||||||
if (!mapper->supportsTracking()) {
|
if (!mapper->supportsTracking()) {
|
||||||
fErrors.error(decl.fOffset, String(decl.fVar->name())
|
fErrors.error(decl.fOffset, String(decl.var().name())
|
||||||
+ "'s type does not support state tracking");
|
+ "'s type does not support state tracking");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1344,7 +1350,7 @@ bool CPPCodeGenerator::generateCode() {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If it's not a uniform_in, it's an error to be tracked
|
// If it's not a uniform_in, it's an error to be tracked
|
||||||
if (decl.fVar->modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
|
if (decl.var().modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
|
||||||
fErrors.error(decl.fOffset, "Non-'in uniforms' cannot be tracked");
|
fErrors.error(decl.fOffset, "Non-'in uniforms' cannot be tracked");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -371,9 +371,10 @@ ParsedModule Compiler::parseModule(Program::Kind kind, ModuleData data, const Pa
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ProgramElement::Kind::kGlobalVar: {
|
case ProgramElement::Kind::kGlobalVar: {
|
||||||
const Variable* var = element->as<GlobalVarDeclaration>().fDecl->fVar;
|
const GlobalVarDeclaration& global = element->as<GlobalVarDeclaration>();
|
||||||
SkASSERT(var->isBuiltin());
|
const Variable& var = global.declaration()->as<VarDeclaration>().var();
|
||||||
intrinsics->insertOrDie(var->name(), std::move(element));
|
SkASSERT(var.isBuiltin());
|
||||||
|
intrinsics->insertOrDie(var.name(), std::move(element));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ProgramElement::Kind::kInterfaceBlock: {
|
case ProgramElement::Kind::kInterfaceBlock: {
|
||||||
@ -515,8 +516,8 @@ void Compiler::addDefinitions(const BasicBlock::Node& node, DefinitionMap* defin
|
|||||||
Statement* stmt = node.statement()->get();
|
Statement* stmt = node.statement()->get();
|
||||||
if (stmt->is<VarDeclaration>()) {
|
if (stmt->is<VarDeclaration>()) {
|
||||||
VarDeclaration& vd = stmt->as<VarDeclaration>();
|
VarDeclaration& vd = stmt->as<VarDeclaration>();
|
||||||
if (vd.fValue) {
|
if (vd.value()) {
|
||||||
definitions->set(vd.fVar, &vd.fValue);
|
definitions->set(&vd.var(), &vd.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -570,7 +571,7 @@ static DefinitionMap compute_start_state(const CFG& cfg) {
|
|||||||
if (node.isStatement()) {
|
if (node.isStatement()) {
|
||||||
const Statement* s = node.statement()->get();
|
const Statement* s = node.statement()->get();
|
||||||
if (s->is<VarDeclaration>()) {
|
if (s->is<VarDeclaration>()) {
|
||||||
result[s->as<VarDeclaration>().fVar] = nullptr;
|
result[&s->as<VarDeclaration>().var()] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1284,12 +1285,12 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
|||||||
switch (stmt->kind()) {
|
switch (stmt->kind()) {
|
||||||
case Statement::Kind::kVarDeclaration: {
|
case Statement::Kind::kVarDeclaration: {
|
||||||
const auto& varDecl = stmt->as<VarDeclaration>();
|
const auto& varDecl = stmt->as<VarDeclaration>();
|
||||||
if (varDecl.fVar->dead() &&
|
if (varDecl.var().dead() &&
|
||||||
(!varDecl.fValue ||
|
(!varDecl.value() ||
|
||||||
!varDecl.fValue->hasSideEffects())) {
|
!varDecl.value()->hasSideEffects())) {
|
||||||
if (varDecl.fValue) {
|
if (varDecl.value()) {
|
||||||
SkASSERT((*iter)->statement()->get() == stmt);
|
SkASSERT((*iter)->statement()->get() == stmt);
|
||||||
if (!b.tryRemoveExpressionBefore(iter, varDecl.fValue.get())) {
|
if (!b.tryRemoveExpressionBefore(iter, varDecl.value().get())) {
|
||||||
*outNeedsRescan = true;
|
*outNeedsRescan = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1616,8 +1617,10 @@ bool Compiler::optimize(Program& program) {
|
|||||||
if (!element->is<GlobalVarDeclaration>()) {
|
if (!element->is<GlobalVarDeclaration>()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto& varDecl = element->as<GlobalVarDeclaration>();
|
const auto& global = element->as<GlobalVarDeclaration>();
|
||||||
bool dead = varDecl.fDecl->fVar->dead();
|
const auto& varDecl =
|
||||||
|
global.declaration()->as<VarDeclaration>();
|
||||||
|
bool dead = varDecl.var().dead();
|
||||||
madeChanges |= dead;
|
madeChanges |= dead;
|
||||||
return dead;
|
return dead;
|
||||||
}),
|
}),
|
||||||
|
@ -485,13 +485,13 @@ void Dehydrator::write(const Statement* s) {
|
|||||||
case Statement::Kind::kVarDeclaration: {
|
case Statement::Kind::kVarDeclaration: {
|
||||||
const VarDeclaration& v = s->as<VarDeclaration>();
|
const VarDeclaration& v = s->as<VarDeclaration>();
|
||||||
this->writeCommand(Rehydrator::kVarDeclaration_Command);
|
this->writeCommand(Rehydrator::kVarDeclaration_Command);
|
||||||
this->writeU16(this->symbolId(v.fVar));
|
this->writeU16(this->symbolId(&v.var()));
|
||||||
this->write(v.fBaseType);
|
this->write(v.baseType());
|
||||||
this->writeU8(v.fSizes.size());
|
this->writeU8(v.sizeCount());
|
||||||
for (const std::unique_ptr<Expression>& sizeExpr : v.fSizes) {
|
for (int i = 0; i < v.sizeCount(); ++i) {
|
||||||
this->write(sizeExpr.get());
|
this->write(v.size(i).get());
|
||||||
}
|
}
|
||||||
this->write(v.fValue.get());
|
this->write(v.value().get());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Statement::Kind::kWhile: {
|
case Statement::Kind::kWhile: {
|
||||||
@ -562,7 +562,7 @@ void Dehydrator::write(const ProgramElement& e) {
|
|||||||
case ProgramElement::Kind::kGlobalVar: {
|
case ProgramElement::Kind::kGlobalVar: {
|
||||||
const GlobalVarDeclaration& v = e.as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& v = e.as<GlobalVarDeclaration>();
|
||||||
this->writeCommand(Rehydrator::kVarDeclarations_Command);
|
this->writeCommand(Rehydrator::kVarDeclarations_Command);
|
||||||
this->write(v.fDecl.get());
|
this->write(v.declaration().get());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1246,23 +1246,23 @@ void GLSLCodeGenerator::writeTypePrecision(const Type& type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& var, bool global) {
|
void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& var, bool global) {
|
||||||
this->writeModifiers(var.fVar->modifiers(), global);
|
this->writeModifiers(var.var().modifiers(), global);
|
||||||
this->writeTypePrecision(var.fBaseType);
|
this->writeTypePrecision(var.baseType());
|
||||||
this->writeType(var.fBaseType);
|
this->writeType(var.baseType());
|
||||||
this->write(" ");
|
this->write(" ");
|
||||||
this->write(var.fVar->name());
|
this->write(var.var().name());
|
||||||
for (const auto& size : var.fSizes) {
|
for (int i = 0; i < var.sizeCount(); ++i) {
|
||||||
this->write("[");
|
this->write("[");
|
||||||
if (size) {
|
if (var.size(i)) {
|
||||||
this->writeExpression(*size, kTopLevel_Precedence);
|
this->writeExpression(*var.size(i), kTopLevel_Precedence);
|
||||||
}
|
}
|
||||||
this->write("]");
|
this->write("]");
|
||||||
}
|
}
|
||||||
if (var.fValue) {
|
if (var.value()) {
|
||||||
this->write(" = ");
|
this->write(" = ");
|
||||||
this->writeVarInitializer(*var.fVar, *var.fValue);
|
this->writeVarInitializer(var.var(), *var.value());
|
||||||
}
|
}
|
||||||
if (!fFoundExternalSamplerDecl && var.fVar->type() == *fContext.fSamplerExternalOES_Type) {
|
if (!fFoundExternalSamplerDecl && var.var().type() == *fContext.fSamplerExternalOES_Type) {
|
||||||
if (fProgram.fSettings.fCaps->externalTextureExtensionString()) {
|
if (fProgram.fSettings.fCaps->externalTextureExtensionString()) {
|
||||||
this->writeExtension(fProgram.fSettings.fCaps->externalTextureExtensionString());
|
this->writeExtension(fProgram.fSettings.fCaps->externalTextureExtensionString());
|
||||||
}
|
}
|
||||||
@ -1271,7 +1271,7 @@ void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& var, bool glob
|
|||||||
}
|
}
|
||||||
fFoundExternalSamplerDecl = true;
|
fFoundExternalSamplerDecl = true;
|
||||||
}
|
}
|
||||||
if (!fFoundRectSamplerDecl && var.fVar->type() == *fContext.fSampler2DRect_Type) {
|
if (!fFoundRectSamplerDecl && var.var().type() == *fContext.fSampler2DRect_Type) {
|
||||||
fFoundRectSamplerDecl = true;
|
fFoundRectSamplerDecl = true;
|
||||||
}
|
}
|
||||||
this->write(";");
|
this->write(";");
|
||||||
@ -1487,15 +1487,16 @@ void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
|
|||||||
this->writeExtension(e.as<Extension>().name());
|
this->writeExtension(e.as<Extension>().name());
|
||||||
break;
|
break;
|
||||||
case ProgramElement::Kind::kGlobalVar: {
|
case ProgramElement::Kind::kGlobalVar: {
|
||||||
const VarDeclaration& decl = *e.as<GlobalVarDeclaration>().fDecl;
|
const VarDeclaration& decl =
|
||||||
int builtin = decl.fVar->modifiers().fLayout.fBuiltin;
|
e.as<GlobalVarDeclaration>().declaration()->as<VarDeclaration>();
|
||||||
|
int builtin = decl.var().modifiers().fLayout.fBuiltin;
|
||||||
if (builtin == -1) {
|
if (builtin == -1) {
|
||||||
// normal var
|
// normal var
|
||||||
this->writeVarDeclaration(decl, true);
|
this->writeVarDeclaration(decl, true);
|
||||||
this->writeLine();
|
this->writeLine();
|
||||||
} else if (builtin == SK_FRAGCOLOR_BUILTIN &&
|
} else if (builtin == SK_FRAGCOLOR_BUILTIN &&
|
||||||
fProgram.fSettings.fCaps->mustDeclareFragmentShaderOutput() &&
|
fProgram.fSettings.fCaps->mustDeclareFragmentShaderOutput() &&
|
||||||
decl.fVar->writeCount()) {
|
decl.var().writeCount()) {
|
||||||
if (fProgram.fSettings.fFragColorIsInOut) {
|
if (fProgram.fSettings.fFragColorIsInOut) {
|
||||||
this->write("inout ");
|
this->write("inout ");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1099,19 +1099,19 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
|
|||||||
"only the last entry in an interface block may be a runtime-sized "
|
"only the last entry in an interface block may be a runtime-sized "
|
||||||
"array");
|
"array");
|
||||||
}
|
}
|
||||||
if (vd.fVar == fRTAdjust) {
|
if (&vd.var() == fRTAdjust) {
|
||||||
foundRTAdjust = true;
|
foundRTAdjust = true;
|
||||||
SkASSERT(vd.fVar->type() == *fContext.fFloat4_Type);
|
SkASSERT(vd.var().type() == *fContext.fFloat4_Type);
|
||||||
fRTAdjustFieldIndex = fields.size();
|
fRTAdjustFieldIndex = fields.size();
|
||||||
}
|
}
|
||||||
fields.push_back(Type::Field(vd.fVar->modifiers(), vd.fVar->name(),
|
fields.push_back(Type::Field(vd.var().modifiers(), vd.var().name(),
|
||||||
&vd.fVar->type()));
|
&vd.var().type()));
|
||||||
if (vd.fValue) {
|
if (vd.value()) {
|
||||||
fErrors.error(decl->fOffset,
|
fErrors.error(decl->fOffset,
|
||||||
"initializers are not permitted on interface block fields");
|
"initializers are not permitted on interface block fields");
|
||||||
}
|
}
|
||||||
if (vd.fVar->type().typeKind() == Type::TypeKind::kArray &&
|
if (vd.var().type().typeKind() == Type::TypeKind::kArray &&
|
||||||
vd.fVar->type().columns() == Type::kUnsizedArray) {
|
vd.var().type().columns() == Type::kUnsizedArray) {
|
||||||
haveRuntimeArray = true;
|
haveRuntimeArray = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2829,8 +2829,10 @@ void IRGenerator::cloneBuiltinVariables() {
|
|||||||
const Expression* initialValue = nullptr;
|
const Expression* initialValue = nullptr;
|
||||||
|
|
||||||
if (clonedDecl->is<GlobalVarDeclaration>()) {
|
if (clonedDecl->is<GlobalVarDeclaration>()) {
|
||||||
sharedVar = clonedDecl->as<GlobalVarDeclaration>().fDecl->fVar;
|
GlobalVarDeclaration& global = clonedDecl->as<GlobalVarDeclaration>();
|
||||||
initialValue = clonedDecl->as<GlobalVarDeclaration>().fDecl->fValue.get();
|
VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
|
sharedVar = &decl.var();
|
||||||
|
initialValue = decl.value().get();
|
||||||
} else {
|
} else {
|
||||||
SkASSERT(clonedDecl->is<InterfaceBlock>());
|
SkASSERT(clonedDecl->is<InterfaceBlock>());
|
||||||
sharedVar = clonedDecl->as<InterfaceBlock>().fVariable;
|
sharedVar = clonedDecl->as<InterfaceBlock>().fVariable;
|
||||||
@ -2847,7 +2849,8 @@ void IRGenerator::cloneBuiltinVariables() {
|
|||||||
|
|
||||||
// Go back and update the declaring element to point at the cloned Variable.
|
// Go back and update the declaring element to point at the cloned Variable.
|
||||||
if (clonedDecl->is<GlobalVarDeclaration>()) {
|
if (clonedDecl->is<GlobalVarDeclaration>()) {
|
||||||
clonedDecl->as<GlobalVarDeclaration>().fDecl->fVar = clonedVar;
|
GlobalVarDeclaration& global = clonedDecl->as<GlobalVarDeclaration>();
|
||||||
|
global.declaration()->as<VarDeclaration>().setVar(clonedVar);
|
||||||
} else {
|
} else {
|
||||||
clonedDecl->as<InterfaceBlock>().fVariable = clonedVar;
|
clonedDecl->as<InterfaceBlock>().fVariable = clonedVar;
|
||||||
}
|
}
|
||||||
|
@ -543,29 +543,29 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
|
|||||||
case Statement::Kind::kVarDeclaration: {
|
case Statement::Kind::kVarDeclaration: {
|
||||||
const VarDeclaration& decl = statement.as<VarDeclaration>();
|
const VarDeclaration& decl = statement.as<VarDeclaration>();
|
||||||
ExpressionArray sizes;
|
ExpressionArray sizes;
|
||||||
sizes.reserve(decl.fSizes.size());
|
sizes.reserve(decl.sizeCount());
|
||||||
for (const auto& size : decl.fSizes) {
|
for (int i = 0; i < decl.sizeCount(); ++i) {
|
||||||
sizes.push_back(expr(size));
|
sizes.push_back(expr(decl.size(i)));
|
||||||
}
|
}
|
||||||
std::unique_ptr<Expression> initialValue = expr(decl.fValue);
|
std::unique_ptr<Expression> initialValue = expr(decl.value());
|
||||||
const Variable* old = decl.fVar;
|
const Variable& old = decl.var();
|
||||||
// We assign unique names to inlined variables--scopes hide most of the problems in this
|
// We assign unique names to inlined variables--scopes hide most of the problems in this
|
||||||
// regard, but see `InlinerAvoidsVariableNameOverlap` for a counterexample where unique
|
// regard, but see `InlinerAvoidsVariableNameOverlap` for a counterexample where unique
|
||||||
// names are important.
|
// names are important.
|
||||||
auto name = std::make_unique<String>(
|
auto name = std::make_unique<String>(
|
||||||
this->uniqueNameForInlineVar(String(old->name()), symbolTableForStatement));
|
this->uniqueNameForInlineVar(String(old.name()), symbolTableForStatement));
|
||||||
const String* namePtr = symbolTableForStatement->takeOwnershipOfString(std::move(name));
|
const String* namePtr = symbolTableForStatement->takeOwnershipOfString(std::move(name));
|
||||||
const Type* baseTypePtr = copy_if_needed(&decl.fBaseType, *symbolTableForStatement);
|
const Type* baseTypePtr = copy_if_needed(&decl.baseType(), *symbolTableForStatement);
|
||||||
const Type* typePtr = copy_if_needed(&old->type(), *symbolTableForStatement);
|
const Type* typePtr = copy_if_needed(&old.type(), *symbolTableForStatement);
|
||||||
const Variable* clone = symbolTableForStatement->takeOwnershipOfSymbol(
|
const Variable* clone = symbolTableForStatement->takeOwnershipOfSymbol(
|
||||||
std::make_unique<Variable>(offset,
|
std::make_unique<Variable>(offset,
|
||||||
old->modifiersHandle(),
|
old.modifiersHandle(),
|
||||||
namePtr->c_str(),
|
namePtr->c_str(),
|
||||||
typePtr,
|
typePtr,
|
||||||
isBuiltinCode,
|
isBuiltinCode,
|
||||||
old->storage(),
|
old.storage(),
|
||||||
initialValue.get()));
|
initialValue.get()));
|
||||||
(*varMap)[old] = std::make_unique<VariableReference>(offset, clone);
|
(*varMap)[&old] = std::make_unique<VariableReference>(offset, clone);
|
||||||
return std::make_unique<VarDeclaration>(clone, baseTypePtr, std::move(sizes),
|
return std::make_unique<VarDeclaration>(clone, baseTypePtr, std::move(sizes),
|
||||||
std::move(initialValue));
|
std::move(initialValue));
|
||||||
}
|
}
|
||||||
@ -941,7 +941,7 @@ public:
|
|||||||
case Statement::Kind::kVarDeclaration: {
|
case Statement::Kind::kVarDeclaration: {
|
||||||
VarDeclaration& varDeclStmt = (*stmt)->as<VarDeclaration>();
|
VarDeclaration& varDeclStmt = (*stmt)->as<VarDeclaration>();
|
||||||
// Don't need to scan the declaration's sizes; those are always IntLiterals.
|
// Don't need to scan the declaration's sizes; those are always IntLiterals.
|
||||||
this->visitExpression(&varDeclStmt.fValue);
|
this->visitExpression(&varDeclStmt.value());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Statement::Kind::kWhile: {
|
case Statement::Kind::kWhile: {
|
||||||
|
@ -956,28 +956,28 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
|||||||
for (const auto& e : fProgram.elements()) {
|
for (const auto& e : fProgram.elements()) {
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
||||||
const VarDeclaration& var = *decls.fDecl;
|
const VarDeclaration& var = decls.declaration()->as<VarDeclaration>();
|
||||||
if (var.fVar->type().typeKind() == Type::TypeKind::kSampler) {
|
if (var.var().type().typeKind() == Type::TypeKind::kSampler) {
|
||||||
if (var.fVar->modifiers().fLayout.fBinding < 0) {
|
if (var.var().modifiers().fLayout.fBinding < 0) {
|
||||||
fErrors.error(decls.fOffset,
|
fErrors.error(decls.fOffset,
|
||||||
"Metal samplers must have 'layout(binding=...)'");
|
"Metal samplers must have 'layout(binding=...)'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (var.fVar->type().dimensions() != SpvDim2D) {
|
if (var.var().type().dimensions() != SpvDim2D) {
|
||||||
// TODO: Support other texture types (skbug.com/10797)
|
// TODO: Support other texture types (skbug.com/10797)
|
||||||
fErrors.error(decls.fOffset, "Unsupported texture dimensions");
|
fErrors.error(decls.fOffset, "Unsupported texture dimensions");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->write(", texture2d<float> ");
|
this->write(", texture2d<float> ");
|
||||||
this->writeName(var.fVar->name());
|
this->writeName(var.var().name());
|
||||||
this->write("[[texture(");
|
this->write("[[texture(");
|
||||||
this->write(to_string(var.fVar->modifiers().fLayout.fBinding));
|
this->write(to_string(var.var().modifiers().fLayout.fBinding));
|
||||||
this->write(")]]");
|
this->write(")]]");
|
||||||
this->write(", sampler ");
|
this->write(", sampler ");
|
||||||
this->writeName(var.fVar->name());
|
this->writeName(var.var().name());
|
||||||
this->write(SAMPLER_SUFFIX);
|
this->write(SAMPLER_SUFFIX);
|
||||||
this->write("[[sampler(");
|
this->write("[[sampler(");
|
||||||
this->write(to_string(var.fVar->modifiers().fLayout.fBinding));
|
this->write(to_string(var.var().modifiers().fLayout.fBinding));
|
||||||
this->write(")]]");
|
this->write(")]]");
|
||||||
}
|
}
|
||||||
} else if (e->is<InterfaceBlock>()) {
|
} else if (e->is<InterfaceBlock>()) {
|
||||||
@ -1218,23 +1218,23 @@ void MetalCodeGenerator::writeName(const String& name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MetalCodeGenerator::writeVarDeclaration(const VarDeclaration& var, bool global) {
|
void MetalCodeGenerator::writeVarDeclaration(const VarDeclaration& var, bool global) {
|
||||||
if (global && !(var.fVar->modifiers().fFlags & Modifiers::kConst_Flag)) {
|
if (global && !(var.var().modifiers().fFlags & Modifiers::kConst_Flag)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->writeModifiers(var.fVar->modifiers(), global);
|
this->writeModifiers(var.var().modifiers(), global);
|
||||||
this->writeType(var.fBaseType);
|
this->writeType(var.baseType());
|
||||||
this->write(" ");
|
this->write(" ");
|
||||||
this->writeName(var.fVar->name());
|
this->writeName(var.var().name());
|
||||||
for (const auto& size : var.fSizes) {
|
for (int i = 0; i < var.sizeCount(); ++i) {
|
||||||
this->write("[");
|
this->write("[");
|
||||||
if (size) {
|
if (var.size(i)) {
|
||||||
this->writeExpression(*size, kTopLevel_Precedence);
|
this->writeExpression(*var.size(i), kTopLevel_Precedence);
|
||||||
}
|
}
|
||||||
this->write("]");
|
this->write("]");
|
||||||
}
|
}
|
||||||
if (var.fValue) {
|
if (var.value()) {
|
||||||
this->write(" = ");
|
this->write(" = ");
|
||||||
this->writeVarInitializer(*var.fVar, *var.fValue);
|
this->writeVarInitializer(var.var(), *var.value());
|
||||||
}
|
}
|
||||||
this->write(";");
|
this->write(";");
|
||||||
}
|
}
|
||||||
@ -1395,7 +1395,7 @@ void MetalCodeGenerator::writeUniformStruct() {
|
|||||||
for (const auto& e : fProgram.elements()) {
|
for (const auto& e : fProgram.elements()) {
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
||||||
const Variable& var = *decls.fDecl->fVar;
|
const Variable& var = decls.declaration()->as<VarDeclaration>().var();
|
||||||
if (var.modifiers().fFlags & Modifiers::kUniform_Flag &&
|
if (var.modifiers().fFlags & Modifiers::kUniform_Flag &&
|
||||||
var.type().typeKind() != Type::TypeKind::kSampler) {
|
var.type().typeKind() != Type::TypeKind::kSampler) {
|
||||||
if (-1 == fUniformBuffer) {
|
if (-1 == fUniformBuffer) {
|
||||||
@ -1428,7 +1428,7 @@ void MetalCodeGenerator::writeInputStruct() {
|
|||||||
for (const auto& e : fProgram.elements()) {
|
for (const auto& e : fProgram.elements()) {
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
||||||
const Variable& var = *decls.fDecl->fVar;
|
const Variable& var = decls.declaration()->as<VarDeclaration>().var();
|
||||||
if (var.modifiers().fFlags & Modifiers::kIn_Flag &&
|
if (var.modifiers().fFlags & Modifiers::kIn_Flag &&
|
||||||
-1 == var.modifiers().fLayout.fBuiltin) {
|
-1 == var.modifiers().fLayout.fBuiltin) {
|
||||||
this->write(" ");
|
this->write(" ");
|
||||||
@ -1461,7 +1461,7 @@ void MetalCodeGenerator::writeOutputStruct() {
|
|||||||
for (const auto& e : fProgram.elements()) {
|
for (const auto& e : fProgram.elements()) {
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
|
||||||
const Variable& var = *decls.fDecl->fVar;
|
const Variable& var = decls.declaration()->as<VarDeclaration>().var();
|
||||||
if (var.modifiers().fFlags & Modifiers::kOut_Flag &&
|
if (var.modifiers().fFlags & Modifiers::kOut_Flag &&
|
||||||
-1 == var.modifiers().fLayout.fBuiltin) {
|
-1 == var.modifiers().fLayout.fBuiltin) {
|
||||||
this->write(" ");
|
this->write(" ");
|
||||||
@ -1514,9 +1514,9 @@ void MetalCodeGenerator::visitGlobalStruct(GlobalStructVisitor* visitor) {
|
|||||||
if (!element->is<GlobalVarDeclaration>()) {
|
if (!element->is<GlobalVarDeclaration>()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const GlobalVarDeclaration& decls = element->as<GlobalVarDeclaration>();
|
const GlobalVarDeclaration& global = element->as<GlobalVarDeclaration>();
|
||||||
const VarDeclaration& decl = *decls.fDecl;
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
const Variable& var = *decl.fVar;
|
const Variable& var = decl.var();
|
||||||
if ((!var.modifiers().fFlags && -1 == var.modifiers().fLayout.fBuiltin) ||
|
if ((!var.modifiers().fFlags && -1 == var.modifiers().fLayout.fBuiltin) ||
|
||||||
var.type().typeKind() == Type::TypeKind::kSampler) {
|
var.type().typeKind() == Type::TypeKind::kSampler) {
|
||||||
if (var.type().typeKind() == Type::TypeKind::kSampler) {
|
if (var.type().typeKind() == Type::TypeKind::kSampler) {
|
||||||
@ -1525,7 +1525,7 @@ void MetalCodeGenerator::visitGlobalStruct(GlobalStructVisitor* visitor) {
|
|||||||
visitor->VisitSampler(var.type(), String(var.name()) + SAMPLER_SUFFIX);
|
visitor->VisitSampler(var.type(), String(var.name()) + SAMPLER_SUFFIX);
|
||||||
} else {
|
} else {
|
||||||
// Visit a regular variable.
|
// Visit a regular variable.
|
||||||
visitor->VisitVariable(var, decl.fValue.get());
|
visitor->VisitVariable(var, decl.value().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1640,8 +1640,9 @@ void MetalCodeGenerator::writeProgramElement(const ProgramElement& e) {
|
|||||||
case ProgramElement::Kind::kExtension:
|
case ProgramElement::Kind::kExtension:
|
||||||
break;
|
break;
|
||||||
case ProgramElement::Kind::kGlobalVar: {
|
case ProgramElement::Kind::kGlobalVar: {
|
||||||
const VarDeclaration& decl = *e.as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = e.as<GlobalVarDeclaration>();
|
||||||
int builtin = decl.fVar->modifiers().fLayout.fBuiltin;
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
|
int builtin = decl.var().modifiers().fLayout.fBuiltin;
|
||||||
if (-1 == builtin) {
|
if (-1 == builtin) {
|
||||||
// normal var
|
// normal var
|
||||||
this->writeVarDeclaration(decl, true);
|
this->writeVarDeclaration(decl, true);
|
||||||
@ -1756,7 +1757,7 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Statemen
|
|||||||
}
|
}
|
||||||
case Statement::Kind::kVarDeclaration: {
|
case Statement::Kind::kVarDeclaration: {
|
||||||
const VarDeclaration& var = s->as<VarDeclaration>();
|
const VarDeclaration& var = s->as<VarDeclaration>();
|
||||||
return this->requirements(var.fValue.get());
|
return this->requirements(var.value().get());
|
||||||
}
|
}
|
||||||
case Statement::Kind::kExpression:
|
case Statement::Kind::kExpression:
|
||||||
return this->requirements(s->as<ExpressionStatement>().expression().get());
|
return this->requirements(s->as<ExpressionStatement>().expression().get());
|
||||||
|
@ -46,10 +46,11 @@ void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
if (p->is<GlobalVarDeclaration>()) {
|
if (p->is<GlobalVarDeclaration>()) {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
|
||||||
if (decl.fVar == arguments[0]->as<VariableReference>().variable()) {
|
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
|
||||||
|
if (&decl.var() == arguments[0]->as<VariableReference>().variable()) {
|
||||||
found = true;
|
found = true;
|
||||||
} else if (decl.fVar->type() == *fContext.fFragmentProcessor_Type) {
|
} else if (decl.var().type() == *fContext.fFragmentProcessor_Type) {
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +126,8 @@ void PipelineStageCodeGenerator::writeVariableReference(const VariableReference&
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
const Variable& var = *e->as<GlobalVarDeclaration>().fDecl->fVar;
|
const GlobalVarDeclaration& global = e->as<GlobalVarDeclaration>();
|
||||||
|
const Variable& var = global.declaration()->as<VarDeclaration>().var();
|
||||||
if (&var == ref.variable()) {
|
if (&var == ref.variable()) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -213,7 +215,8 @@ void PipelineStageCodeGenerator::writeProgramElement(const ProgramElement& p) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (p.is<GlobalVarDeclaration>()) {
|
if (p.is<GlobalVarDeclaration>()) {
|
||||||
const Variable& var = *p.as<GlobalVarDeclaration>().fDecl->fVar;
|
const GlobalVarDeclaration& global = p.as<GlobalVarDeclaration>();
|
||||||
|
const Variable& var = global.declaration()->as<VarDeclaration>().var();
|
||||||
if (var.modifiers().fFlags &
|
if (var.modifiers().fFlags &
|
||||||
(Modifiers::kIn_Flag | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag) ||
|
(Modifiers::kIn_Flag | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag) ||
|
||||||
var.modifiers().fLayout.fBuiltin == -1) {
|
var.modifiers().fLayout.fBuiltin == -1) {
|
||||||
|
@ -2780,32 +2780,32 @@ bool is_dead(const Variable& var) {
|
|||||||
#define BUILTIN_IGNORE 9999
|
#define BUILTIN_IGNORE 9999
|
||||||
void SPIRVCodeGenerator::writeGlobalVar(Program::Kind kind, const VarDeclaration& varDecl,
|
void SPIRVCodeGenerator::writeGlobalVar(Program::Kind kind, const VarDeclaration& varDecl,
|
||||||
OutputStream& out) {
|
OutputStream& out) {
|
||||||
const Variable* var = varDecl.fVar;
|
const Variable& var = varDecl.var();
|
||||||
// These haven't been implemented in our SPIR-V generator yet and we only currently use them
|
// These haven't been implemented in our SPIR-V generator yet and we only currently use them
|
||||||
// in the OpenGL backend.
|
// in the OpenGL backend.
|
||||||
SkASSERT(!(var->modifiers().fFlags & (Modifiers::kReadOnly_Flag |
|
SkASSERT(!(var.modifiers().fFlags & (Modifiers::kReadOnly_Flag |
|
||||||
Modifiers::kWriteOnly_Flag |
|
Modifiers::kWriteOnly_Flag |
|
||||||
Modifiers::kCoherent_Flag |
|
Modifiers::kCoherent_Flag |
|
||||||
Modifiers::kVolatile_Flag |
|
Modifiers::kVolatile_Flag |
|
||||||
Modifiers::kRestrict_Flag)));
|
Modifiers::kRestrict_Flag)));
|
||||||
if (var->modifiers().fLayout.fBuiltin == BUILTIN_IGNORE) {
|
if (var.modifiers().fLayout.fBuiltin == BUILTIN_IGNORE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (var->modifiers().fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN &&
|
if (var.modifiers().fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN &&
|
||||||
kind != Program::kFragment_Kind) {
|
kind != Program::kFragment_Kind) {
|
||||||
SkASSERT(!fProgram.fSettings.fFragColorIsInOut);
|
SkASSERT(!fProgram.fSettings.fFragColorIsInOut);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (is_dead(*var)) {
|
if (is_dead(var)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Type& type = var->type();
|
const Type& type = var.type();
|
||||||
SpvStorageClass_ storageClass;
|
SpvStorageClass_ storageClass;
|
||||||
if (var->modifiers().fFlags & Modifiers::kIn_Flag) {
|
if (var.modifiers().fFlags & Modifiers::kIn_Flag) {
|
||||||
storageClass = SpvStorageClassInput;
|
storageClass = SpvStorageClassInput;
|
||||||
} else if (var->modifiers().fFlags & Modifiers::kOut_Flag) {
|
} else if (var.modifiers().fFlags & Modifiers::kOut_Flag) {
|
||||||
storageClass = SpvStorageClassOutput;
|
storageClass = SpvStorageClassOutput;
|
||||||
} else if (var->modifiers().fFlags & Modifiers::kUniform_Flag) {
|
} else if (var.modifiers().fFlags & Modifiers::kUniform_Flag) {
|
||||||
if (type.typeKind() == Type::TypeKind::kSampler ||
|
if (type.typeKind() == Type::TypeKind::kSampler ||
|
||||||
type.typeKind() == Type::TypeKind::kSeparateSampler ||
|
type.typeKind() == Type::TypeKind::kSeparateSampler ||
|
||||||
type.typeKind() == Type::TypeKind::kTexture) {
|
type.typeKind() == Type::TypeKind::kTexture) {
|
||||||
@ -2817,9 +2817,9 @@ void SPIRVCodeGenerator::writeGlobalVar(Program::Kind kind, const VarDeclaration
|
|||||||
storageClass = SpvStorageClassPrivate;
|
storageClass = SpvStorageClassPrivate;
|
||||||
}
|
}
|
||||||
SpvId id = this->nextId();
|
SpvId id = this->nextId();
|
||||||
fVariableMap[var] = id;
|
fVariableMap[&var] = id;
|
||||||
SpvId typeId;
|
SpvId typeId;
|
||||||
if (var->modifiers().fLayout.fBuiltin == SK_IN_BUILTIN) {
|
if (var.modifiers().fLayout.fBuiltin == SK_IN_BUILTIN) {
|
||||||
typeId = this->getPointerType(
|
typeId = this->getPointerType(
|
||||||
Type("sk_in", Type::TypeKind::kArray, type.componentType(), fSkInCount),
|
Type("sk_in", Type::TypeKind::kArray, type.componentType(), fSkInCount),
|
||||||
storageClass);
|
storageClass);
|
||||||
@ -2827,41 +2827,41 @@ void SPIRVCodeGenerator::writeGlobalVar(Program::Kind kind, const VarDeclaration
|
|||||||
typeId = this->getPointerType(type, storageClass);
|
typeId = this->getPointerType(type, storageClass);
|
||||||
}
|
}
|
||||||
this->writeInstruction(SpvOpVariable, typeId, id, storageClass, fConstantBuffer);
|
this->writeInstruction(SpvOpVariable, typeId, id, storageClass, fConstantBuffer);
|
||||||
this->writeInstruction(SpvOpName, id, var->name(), fNameBuffer);
|
this->writeInstruction(SpvOpName, id, var.name(), fNameBuffer);
|
||||||
this->writePrecisionModifier(type, id);
|
this->writePrecisionModifier(type, id);
|
||||||
if (varDecl.fValue) {
|
if (varDecl.value()) {
|
||||||
SkASSERT(!fCurrentBlock);
|
SkASSERT(!fCurrentBlock);
|
||||||
fCurrentBlock = -1;
|
fCurrentBlock = -1;
|
||||||
SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitializersBuffer);
|
SpvId value = this->writeExpression(*varDecl.value(), fGlobalInitializersBuffer);
|
||||||
this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer);
|
this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer);
|
||||||
fCurrentBlock = 0;
|
fCurrentBlock = 0;
|
||||||
}
|
}
|
||||||
this->writeLayout(var->modifiers().fLayout, id);
|
this->writeLayout(var.modifiers().fLayout, id);
|
||||||
if (var->modifiers().fFlags & Modifiers::kFlat_Flag) {
|
if (var.modifiers().fFlags & Modifiers::kFlat_Flag) {
|
||||||
this->writeInstruction(SpvOpDecorate, id, SpvDecorationFlat, fDecorationBuffer);
|
this->writeInstruction(SpvOpDecorate, id, SpvDecorationFlat, fDecorationBuffer);
|
||||||
}
|
}
|
||||||
if (var->modifiers().fFlags & Modifiers::kNoPerspective_Flag) {
|
if (var.modifiers().fFlags & Modifiers::kNoPerspective_Flag) {
|
||||||
this->writeInstruction(SpvOpDecorate, id, SpvDecorationNoPerspective,
|
this->writeInstruction(SpvOpDecorate, id, SpvDecorationNoPerspective,
|
||||||
fDecorationBuffer);
|
fDecorationBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl, OutputStream& out) {
|
void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl, OutputStream& out) {
|
||||||
const Variable* var = varDecl.fVar;
|
const Variable& var = varDecl.var();
|
||||||
// These haven't been implemented in our SPIR-V generator yet and we only currently use them
|
// These haven't been implemented in our SPIR-V generator yet and we only currently use them
|
||||||
// in the OpenGL backend.
|
// in the OpenGL backend.
|
||||||
SkASSERT(!(var->modifiers().fFlags & (Modifiers::kReadOnly_Flag |
|
SkASSERT(!(var.modifiers().fFlags & (Modifiers::kReadOnly_Flag |
|
||||||
Modifiers::kWriteOnly_Flag |
|
Modifiers::kWriteOnly_Flag |
|
||||||
Modifiers::kCoherent_Flag |
|
Modifiers::kCoherent_Flag |
|
||||||
Modifiers::kVolatile_Flag |
|
Modifiers::kVolatile_Flag |
|
||||||
Modifiers::kRestrict_Flag)));
|
Modifiers::kRestrict_Flag)));
|
||||||
SpvId id = this->nextId();
|
SpvId id = this->nextId();
|
||||||
fVariableMap[var] = id;
|
fVariableMap[&var] = id;
|
||||||
SpvId type = this->getPointerType(var->type(), SpvStorageClassFunction);
|
SpvId type = this->getPointerType(var.type(), SpvStorageClassFunction);
|
||||||
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
|
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
|
||||||
this->writeInstruction(SpvOpName, id, var->name(), fNameBuffer);
|
this->writeInstruction(SpvOpName, id, var.name(), fNameBuffer);
|
||||||
if (varDecl.fValue) {
|
if (varDecl.value()) {
|
||||||
SpvId value = this->writeExpression(*varDecl.fValue, out);
|
SpvId value = this->writeExpression(*varDecl.value(), out);
|
||||||
this->writeInstruction(SpvOpStore, id, value, out);
|
this->writeInstruction(SpvOpStore, id, value, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3214,7 +3214,9 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
|||||||
}
|
}
|
||||||
for (const auto& e : program.elements()) {
|
for (const auto& e : program.elements()) {
|
||||||
if (e->is<GlobalVarDeclaration>()) {
|
if (e->is<GlobalVarDeclaration>()) {
|
||||||
this->writeGlobalVar(program.fKind, *e->as<GlobalVarDeclaration>().fDecl, body);
|
this->writeGlobalVar(program.fKind,
|
||||||
|
e->as<GlobalVarDeclaration>().declaration()->as<VarDeclaration>(),
|
||||||
|
body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& e : program.elements()) {
|
for (const auto& e : program.elements()) {
|
||||||
|
@ -30,9 +30,10 @@ SectionAndParameterHelper::SectionAndParameterHelper(const Program* program, Err
|
|||||||
for (const auto& p : fProgram.elements()) {
|
for (const auto& p : fProgram.elements()) {
|
||||||
switch (p->kind()) {
|
switch (p->kind()) {
|
||||||
case ProgramElement::Kind::kGlobalVar: {
|
case ProgramElement::Kind::kGlobalVar: {
|
||||||
const VarDeclaration& decl = *p->as<GlobalVarDeclaration>().fDecl;
|
const VarDeclaration& decl =
|
||||||
if (IsParameter(*decl.fVar)) {
|
p->as<GlobalVarDeclaration>().declaration()->as<VarDeclaration>();
|
||||||
fParameters.push_back(decl.fVar);
|
if (IsParameter(decl.var())) {
|
||||||
|
fParameters.push_back(&decl.var());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,11 @@ IRNode::IRNode(int offset, int kind, const UnresolvedFunctionData& data)
|
|||||||
, fKind(kind)
|
, fKind(kind)
|
||||||
, fData(data) {}
|
, fData(data) {}
|
||||||
|
|
||||||
|
IRNode::IRNode(int offset, int kind, const VarDeclarationData& data)
|
||||||
|
: fOffset(offset)
|
||||||
|
, fKind(kind)
|
||||||
|
, fData(data) {}
|
||||||
|
|
||||||
IRNode::IRNode(int offset, int kind, const VariableData& data)
|
IRNode::IRNode(int offset, int kind, const VariableData& data)
|
||||||
: fOffset(offset)
|
: fOffset(offset)
|
||||||
, fKind(kind)
|
, fKind(kind)
|
||||||
|
@ -202,6 +202,11 @@ protected:
|
|||||||
std::vector<const FunctionDeclaration*> fFunctions;
|
std::vector<const FunctionDeclaration*> fFunctions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VarDeclarationData {
|
||||||
|
const Type* fBaseType;
|
||||||
|
const Variable* fVar;
|
||||||
|
};
|
||||||
|
|
||||||
struct VariableData {
|
struct VariableData {
|
||||||
StringFragment fName;
|
StringFragment fName;
|
||||||
const Type* fType;
|
const Type* fType;
|
||||||
@ -249,6 +254,7 @@ protected:
|
|||||||
kTypeReference,
|
kTypeReference,
|
||||||
kTypeToken,
|
kTypeToken,
|
||||||
kUnresolvedFunction,
|
kUnresolvedFunction,
|
||||||
|
kVarDeclaration,
|
||||||
kVariable,
|
kVariable,
|
||||||
kVariableReference,
|
kVariableReference,
|
||||||
} fKind = Kind::kType;
|
} fKind = Kind::kType;
|
||||||
@ -280,6 +286,7 @@ protected:
|
|||||||
TypeReferenceData fTypeReference;
|
TypeReferenceData fTypeReference;
|
||||||
TypeTokenData fTypeToken;
|
TypeTokenData fTypeToken;
|
||||||
UnresolvedFunctionData fUnresolvedFunction;
|
UnresolvedFunctionData fUnresolvedFunction;
|
||||||
|
VarDeclarationData fVarDeclaration;
|
||||||
VariableData fVariable;
|
VariableData fVariable;
|
||||||
VariableReferenceData fVariableReference;
|
VariableReferenceData fVariableReference;
|
||||||
|
|
||||||
@ -413,6 +420,11 @@ protected:
|
|||||||
*(new(&fContents) UnresolvedFunctionData) = data;
|
*(new(&fContents) UnresolvedFunctionData) = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeData(const VarDeclarationData& data)
|
||||||
|
: fKind(Kind::kVarDeclaration) {
|
||||||
|
*(new(&fContents) VarDeclarationData) = data;
|
||||||
|
}
|
||||||
|
|
||||||
NodeData(const VariableData& data)
|
NodeData(const VariableData& data)
|
||||||
: fKind(Kind::kVariable) {
|
: fKind(Kind::kVariable) {
|
||||||
*(new(&fContents) VariableData) = data;
|
*(new(&fContents) VariableData) = data;
|
||||||
@ -508,6 +520,9 @@ protected:
|
|||||||
case Kind::kUnresolvedFunction:
|
case Kind::kUnresolvedFunction:
|
||||||
*(new(&fContents) UnresolvedFunctionData) = other.fContents.fUnresolvedFunction;
|
*(new(&fContents) UnresolvedFunctionData) = other.fContents.fUnresolvedFunction;
|
||||||
break;
|
break;
|
||||||
|
case Kind::kVarDeclaration:
|
||||||
|
*(new(&fContents) VarDeclarationData) = other.fContents.fVarDeclaration;
|
||||||
|
break;
|
||||||
case Kind::kVariable:
|
case Kind::kVariable:
|
||||||
*(new(&fContents) VariableData) = other.fContents.fVariable;
|
*(new(&fContents) VariableData) = other.fContents.fVariable;
|
||||||
break;
|
break;
|
||||||
@ -599,6 +614,9 @@ protected:
|
|||||||
case Kind::kUnresolvedFunction:
|
case Kind::kUnresolvedFunction:
|
||||||
fContents.fUnresolvedFunction.~UnresolvedFunctionData();
|
fContents.fUnresolvedFunction.~UnresolvedFunctionData();
|
||||||
break;
|
break;
|
||||||
|
case Kind::kVarDeclaration:
|
||||||
|
fContents.fVarDeclaration.~VarDeclarationData();
|
||||||
|
break;
|
||||||
case Kind::kVariable:
|
case Kind::kVariable:
|
||||||
fContents.fVariable.~VariableData();
|
fContents.fVariable.~VariableData();
|
||||||
break;
|
break;
|
||||||
@ -659,6 +677,8 @@ protected:
|
|||||||
|
|
||||||
IRNode(int offset, int kind, const UnresolvedFunctionData& data);
|
IRNode(int offset, int kind, const UnresolvedFunctionData& data);
|
||||||
|
|
||||||
|
IRNode(int offset, int kind, const VarDeclarationData& data);
|
||||||
|
|
||||||
IRNode(int offset, int kind, const VariableData& data);
|
IRNode(int offset, int kind, const VariableData& data);
|
||||||
|
|
||||||
IRNode(int offset, int kind, const VariableReferenceData& data);
|
IRNode(int offset, int kind, const VariableReferenceData& data);
|
||||||
@ -847,6 +867,16 @@ protected:
|
|||||||
return fData.fContents.fUnresolvedFunction;
|
return fData.fContents.fUnresolvedFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VarDeclarationData& varDeclarationData() {
|
||||||
|
SkASSERT(fData.fKind == NodeData::Kind::kVarDeclaration);
|
||||||
|
return fData.fContents.fVarDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VarDeclarationData& varDeclarationData() const {
|
||||||
|
SkASSERT(fData.fKind == NodeData::Kind::kVarDeclaration);
|
||||||
|
return fData.fContents.fVarDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
VariableData& variableData() {
|
VariableData& variableData() {
|
||||||
SkASSERT(fData.fKind == NodeData::Kind::kVariable);
|
SkASSERT(fData.fKind == NodeData::Kind::kVariable);
|
||||||
return fData.fContents.fVariable;
|
return fData.fContents.fVariable;
|
||||||
|
@ -18,7 +18,8 @@ namespace SkSL {
|
|||||||
*
|
*
|
||||||
* layout(blend_support_all_equations) out;
|
* layout(blend_support_all_equations) out;
|
||||||
*/
|
*/
|
||||||
struct ModifiersDeclaration : public ProgramElement {
|
class ModifiersDeclaration : public ProgramElement {
|
||||||
|
public:
|
||||||
static constexpr Kind kProgramElementKind = Kind::kModifiers;
|
static constexpr Kind kProgramElementKind = Kind::kModifiers;
|
||||||
|
|
||||||
ModifiersDeclaration(ModifiersPool::Handle modifiers)
|
ModifiersDeclaration(ModifiersPool::Handle modifiers)
|
||||||
@ -40,6 +41,7 @@ struct ModifiersDeclaration : public ProgramElement {
|
|||||||
return this->modifiers().description() + ";";
|
return this->modifiers().description() + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
using INHERITED = ProgramElement;
|
using INHERITED = ProgramElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,6 +58,9 @@ public:
|
|||||||
Statement(int offset, const InlineMarkerData& data)
|
Statement(int offset, const InlineMarkerData& data)
|
||||||
: INHERITED(offset, (int) Kind::kInlineMarker, data) {}
|
: INHERITED(offset, (int) Kind::kInlineMarker, data) {}
|
||||||
|
|
||||||
|
Statement(int offset, const VarDeclarationData& data)
|
||||||
|
: INHERITED(offset, (int) Kind::kVarDeclaration, data) {}
|
||||||
|
|
||||||
Kind kind() const {
|
Kind kind() const {
|
||||||
return (Kind) fKind;
|
return (Kind) fKind;
|
||||||
}
|
}
|
||||||
|
@ -20,55 +20,82 @@ namespace SkSL {
|
|||||||
* separate (sequential) statements. For instance, the SkSL 'int x = 2, y[3];' produces two
|
* separate (sequential) statements. For instance, the SkSL 'int x = 2, y[3];' produces two
|
||||||
* VarDeclaration instances (wrapped in an unscoped Block).
|
* VarDeclaration instances (wrapped in an unscoped Block).
|
||||||
*/
|
*/
|
||||||
struct VarDeclaration : public Statement {
|
class VarDeclaration : public Statement {
|
||||||
|
public:
|
||||||
static constexpr Kind kStatementKind = Kind::kVarDeclaration;
|
static constexpr Kind kStatementKind = Kind::kVarDeclaration;
|
||||||
|
|
||||||
VarDeclaration(const Variable* var,
|
VarDeclaration(const Variable* var,
|
||||||
const Type* baseType,
|
const Type* baseType,
|
||||||
ExpressionArray sizes,
|
ExpressionArray sizes,
|
||||||
std::unique_ptr<Expression> value)
|
std::unique_ptr<Expression> value)
|
||||||
: INHERITED(var->fOffset, kStatementKind)
|
: INHERITED(var->fOffset, VarDeclarationData{baseType, var}) {
|
||||||
, fVar(var)
|
fExpressionChildren.reserve(sizes.size() + 1);
|
||||||
, fBaseType(*baseType)
|
fExpressionChildren.move_back_n(sizes.size(), sizes.data());
|
||||||
, fSizes(std::move(sizes))
|
fExpressionChildren.push_back(std::move(value));
|
||||||
, fValue(std::move(value)) {}
|
}
|
||||||
|
|
||||||
|
const Type& baseType() const {
|
||||||
|
return *this->varDeclarationData().fBaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Variable& var() const {
|
||||||
|
return *this->varDeclarationData().fVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVar(const Variable* var) {
|
||||||
|
this->varDeclarationData().fVar = var;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sizeCount() const {
|
||||||
|
return fExpressionChildren.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unique_ptr<Expression>& size(int index) const {
|
||||||
|
SkASSERT(index >= 0 && index < this->sizeCount());
|
||||||
|
return fExpressionChildren[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Expression>& value() {
|
||||||
|
return fExpressionChildren.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unique_ptr<Expression>& value() const {
|
||||||
|
return fExpressionChildren.back();
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<Statement> clone() const override {
|
std::unique_ptr<Statement> clone() const override {
|
||||||
ExpressionArray sizesClone;
|
ExpressionArray sizesClone;
|
||||||
sizesClone.reserve(fSizes.size());
|
sizesClone.reserve(this->sizeCount());
|
||||||
for (const auto& s : fSizes) {
|
for (int i = 0; i < this->sizeCount(); ++i) {
|
||||||
if (s) {
|
if (this->size(i)) {
|
||||||
sizesClone.push_back(s->clone());
|
sizesClone.push_back(this->size(i)->clone());
|
||||||
} else {
|
} else {
|
||||||
sizesClone.push_back(nullptr);
|
sizesClone.push_back(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_unique<VarDeclaration>(fVar, &fBaseType, std::move(sizesClone),
|
return std::make_unique<VarDeclaration>(&this->var(),
|
||||||
fValue ? fValue->clone() : nullptr);
|
&this->baseType(),
|
||||||
|
std::move(sizesClone),
|
||||||
|
this->value() ? this->value()->clone() : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
String description() const override {
|
String description() const override {
|
||||||
String result = fVar->modifiers().description() + fBaseType.description() + " " +
|
String result = this->var().modifiers().description() + this->baseType().description() +
|
||||||
fVar->name();
|
" " + this->var().name();
|
||||||
for (const auto& size : fSizes) {
|
for (int i = 0; i < this->sizeCount(); ++i) {
|
||||||
if (size) {
|
if (this->size(i)) {
|
||||||
result += "[" + size->description() + "]";
|
result += "[" + this->size(i)->description() + "]";
|
||||||
} else {
|
} else {
|
||||||
result += "[]";
|
result += "[]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fValue) {
|
if (this->value()) {
|
||||||
result += " = " + fValue->description();
|
result += " = " + this->value()->description();
|
||||||
}
|
}
|
||||||
result += ";";
|
result += ";";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Variable* fVar;
|
|
||||||
const Type& fBaseType;
|
|
||||||
ExpressionArray fSizes;
|
|
||||||
std::unique_ptr<Expression> fValue;
|
|
||||||
|
|
||||||
using INHERITED = Statement;
|
using INHERITED = Statement;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,26 +103,33 @@ struct VarDeclaration : public Statement {
|
|||||||
* A variable declaration appearing at global scope. A global declaration like 'int x, y;' produces
|
* A variable declaration appearing at global scope. A global declaration like 'int x, y;' produces
|
||||||
* two GlobalVarDeclaration elements, each containing the declaration of one variable.
|
* two GlobalVarDeclaration elements, each containing the declaration of one variable.
|
||||||
*/
|
*/
|
||||||
struct GlobalVarDeclaration : public ProgramElement {
|
class GlobalVarDeclaration : public ProgramElement {
|
||||||
|
public:
|
||||||
static constexpr Kind kProgramElementKind = Kind::kGlobalVar;
|
static constexpr Kind kProgramElementKind = Kind::kGlobalVar;
|
||||||
|
|
||||||
// decl must be a unique_ptr<VarDeclaration>, but to simplify construction, we take a Statement
|
|
||||||
GlobalVarDeclaration(int offset, std::unique_ptr<Statement> decl)
|
GlobalVarDeclaration(int offset, std::unique_ptr<Statement> decl)
|
||||||
: INHERITED(offset, kProgramElementKind) {
|
: INHERITED(offset, kProgramElementKind) {
|
||||||
SkASSERT(decl->is<VarDeclaration>());
|
SkASSERT(decl->is<VarDeclaration>());
|
||||||
fDecl.reset(static_cast<VarDeclaration*>(decl.release()));
|
fStatementChildren.push_back(std::move(decl));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Statement>& declaration() {
|
||||||
|
return fStatementChildren[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unique_ptr<Statement>& declaration() const {
|
||||||
|
return fStatementChildren[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ProgramElement> clone() const override {
|
std::unique_ptr<ProgramElement> clone() const override {
|
||||||
return std::make_unique<GlobalVarDeclaration>(fOffset, fDecl->clone());
|
return std::make_unique<GlobalVarDeclaration>(fOffset, this->declaration()->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
String description() const override {
|
String description() const override {
|
||||||
return fDecl->description();
|
return this->declaration()->description();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<VarDeclaration> fDecl;
|
private:
|
||||||
|
|
||||||
using INHERITED = ProgramElement;
|
using INHERITED = ProgramElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user