Removed ErrorHandler pointers from CodeGenerators

These pointers were largely redundant because the CodeGenerators also
had access to a Context, and in a future CL Context becomes the source
of truth regarding the current ErrorHandler, so they are potentially
dangerous.

Change-Id: Ie4175fcb3e1f586baaa42d16c05058aea78532f0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/439164
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2021-08-13 11:20:09 -04:00 committed by SkCQ
parent abae48eb5b
commit 3abc6c68ad
8 changed files with 78 additions and 80 deletions

View File

@ -892,7 +892,7 @@ bool Compiler::toSPIRV(Program& program, OutputStream& out) {
dsl::DSLWriter::IRGenerator().fSymbolTable = program.fSymbols; dsl::DSLWriter::IRGenerator().fSymbolTable = program.fSymbols;
#ifdef SK_ENABLE_SPIRV_VALIDATION #ifdef SK_ENABLE_SPIRV_VALIDATION
StringStream buffer; StringStream buffer;
SPIRVCodeGenerator cg(fContext.get(), &program, this, &buffer); SPIRVCodeGenerator cg(fContext.get(), &program, &buffer);
bool result = cg.generateCode(); bool result = cg.generateCode();
if (result && program.fConfig->fSettings.fValidateSPIRV) { if (result && program.fConfig->fSettings.fValidateSPIRV) {
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0); spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
@ -925,7 +925,7 @@ bool Compiler::toSPIRV(Program& program, OutputStream& out) {
out.write(data.c_str(), data.size()); out.write(data.c_str(), data.size());
} }
#else #else
SPIRVCodeGenerator cg(fContext.get(), &program, this, &out); SPIRVCodeGenerator cg(fContext.get(), &program, &out);
bool result = cg.generateCode(); bool result = cg.generateCode();
#endif #endif
dsl::End(); dsl::End();
@ -944,7 +944,7 @@ bool Compiler::toSPIRV(Program& program, String* out) {
bool Compiler::toGLSL(Program& program, OutputStream& out) { bool Compiler::toGLSL(Program& program, OutputStream& out) {
TRACE_EVENT0("skia.shaders", "SkSL::Compiler::toGLSL"); TRACE_EVENT0("skia.shaders", "SkSL::Compiler::toGLSL");
AutoSource as(this, program.fSource->c_str()); AutoSource as(this, program.fSource->c_str());
GLSLCodeGenerator cg(fContext.get(), &program, this, &out); GLSLCodeGenerator cg(fContext.get(), &program, &out);
bool result = cg.generateCode(); bool result = cg.generateCode();
return result; return result;
} }
@ -970,7 +970,7 @@ bool Compiler::toHLSL(Program& program, String* out) {
bool Compiler::toMetal(Program& program, OutputStream& out) { bool Compiler::toMetal(Program& program, OutputStream& out) {
TRACE_EVENT0("skia.shaders", "SkSL::Compiler::toMetal"); TRACE_EVENT0("skia.shaders", "SkSL::Compiler::toMetal");
AutoSource as(this, program.fSource->c_str()); AutoSource as(this, program.fSource->c_str());
MetalCodeGenerator cg(fContext.get(), &program, this, &out); MetalCodeGenerator cg(fContext.get(), &program, &out);
bool result = cg.generateCode(); bool result = cg.generateCode();
return result; return result;
} }

View File

@ -19,9 +19,9 @@ namespace SkSL {
*/ */
class CodeGenerator { class CodeGenerator {
public: public:
CodeGenerator(const Program* program, ErrorReporter* errors, OutputStream* out) CodeGenerator(const Context* context, const Program* program, OutputStream* out)
: fProgram(*program) : fContext(*context)
, fErrors(*errors) , fProgram(*program)
, fOut(out) {} , fOut(out) {}
virtual ~CodeGenerator() {} virtual ~CodeGenerator() {}
@ -33,8 +33,8 @@ public:
void setOutputStream(OutputStream* output) { fOut = output; } void setOutputStream(OutputStream* output) { fOut = output; }
protected: protected:
const Context& fContext;
const Program& fProgram; const Program& fProgram;
ErrorReporter& fErrors;
OutputStream* fOut; OutputStream* fOut;
}; };

View File

@ -1546,7 +1546,7 @@ bool GLSLCodeGenerator::generateCode() {
} }
write_stringstream(fExtraFunctions, *rawOut); write_stringstream(fExtraFunctions, *rawOut);
write_stringstream(body, *rawOut); write_stringstream(body, *rawOut);
return 0 == fErrors.errorCount(); return fContext.errors().errorCount() == 0;
} }
} // namespace SkSL } // namespace SkSL

View File

@ -53,11 +53,9 @@ namespace SkSL {
*/ */
class GLSLCodeGenerator : public CodeGenerator { class GLSLCodeGenerator : public CodeGenerator {
public: public:
GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors, GLSLCodeGenerator(const Context* context, const Program* program, OutputStream* out)
OutputStream* out) : INHERITED(context, program, out)
: INHERITED(program, errors, out) , fLineEnding("\n") {}
, fLineEnding("\n")
, fContext(*context) {}
bool generateCode() override; bool generateCode() override;
@ -179,7 +177,6 @@ protected:
const ShaderCapsClass& caps() const { return fContext.fCaps; } const ShaderCapsClass& caps() const { return fContext.fCaps; }
const char* fLineEnding; const char* fLineEnding;
const Context& fContext;
StringStream fExtensions; StringStream fExtensions;
StringStream fGlobals; StringStream fGlobals;
StringStream fExtraFunctions; StringStream fExtraFunctions;

View File

@ -1038,7 +1038,7 @@ void MetalCodeGenerator::writeConstructorCompound(const ConstructorCompound& c,
} else if (c.type().isMatrix()) { } else if (c.type().isMatrix()) {
this->writeConstructorCompoundMatrix(c, parentPrecedence); this->writeConstructorCompoundMatrix(c, parentPrecedence);
} else { } else {
fErrors.error(c.fOffset, "unsupported compound constructor"); fContext.errors().error(c.fOffset, "unsupported compound constructor");
} }
} }
@ -1686,7 +1686,7 @@ bool MetalCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& f)
this->write("vertex Outputs vertexMain"); this->write("vertex Outputs vertexMain");
break; break;
default: default:
fErrors.error(-1, "unsupported kind of program"); fContext.errors().error(-1, "unsupported kind of program");
return false; return false;
} }
this->write("(Inputs _in [[stage_in]]"); this->write("(Inputs _in [[stage_in]]");
@ -1700,13 +1700,13 @@ bool MetalCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& f)
const VarDeclaration& var = decls.declaration()->as<VarDeclaration>(); const VarDeclaration& var = decls.declaration()->as<VarDeclaration>();
if (var.var().type().typeKind() == Type::TypeKind::kSampler) { if (var.var().type().typeKind() == Type::TypeKind::kSampler) {
if (var.var().modifiers().fLayout.fBinding < 0) { if (var.var().modifiers().fLayout.fBinding < 0) {
fErrors.error(decls.fOffset, fContext.errors().error(decls.fOffset,
"Metal samplers must have 'layout(binding=...)'"); "Metal samplers must have 'layout(binding=...)'");
return false; return false;
} }
if (var.var().type().dimensions() != SpvDim2D) { if (var.var().type().dimensions() != SpvDim2D) {
// Not yet implemented--Skia currently only uses 2D textures. // Not yet implemented--Skia currently only uses 2D textures.
fErrors.error(decls.fOffset, "Unsupported texture dimensions"); fContext.errors().error(decls.fOffset, "Unsupported texture dimensions");
return false; return false;
} }
this->write(", texture2d<float> "); this->write(", texture2d<float> ");
@ -1894,14 +1894,15 @@ void MetalCodeGenerator::writeFields(const std::vector<Type::Field>& fields, int
int fieldOffset = field.fModifiers.fLayout.fOffset; int fieldOffset = field.fModifiers.fLayout.fOffset;
const Type* fieldType = field.fType; const Type* fieldType = field.fType;
if (!MemoryLayout::LayoutIsSupported(*fieldType)) { if (!MemoryLayout::LayoutIsSupported(*fieldType)) {
fErrors.error(parentOffset, "type '" + fieldType->name() + "' is not permitted here"); fContext.errors().error(parentOffset, "type '" + fieldType->name() +
"' is not permitted here");
return; return;
} }
if (fieldOffset != -1) { if (fieldOffset != -1) {
if (currentOffset > fieldOffset) { if (currentOffset > fieldOffset) {
fErrors.error(parentOffset, fContext.errors().error(parentOffset,
"offset of field '" + field.fName + "' must be at least " + "offset of field '" + field.fName + "' must be at least " +
to_string((int) currentOffset)); to_string((int) currentOffset));
return; return;
} else if (currentOffset < fieldOffset) { } else if (currentOffset < fieldOffset) {
this->write("char pad"); this->write("char pad");
@ -1913,15 +1914,15 @@ void MetalCodeGenerator::writeFields(const std::vector<Type::Field>& fields, int
} }
int alignment = memoryLayout.alignment(*fieldType); int alignment = memoryLayout.alignment(*fieldType);
if (fieldOffset % alignment) { if (fieldOffset % alignment) {
fErrors.error(parentOffset, fContext.errors().error(parentOffset,
"offset of field '" + field.fName + "' must be a multiple of " + "offset of field '" + field.fName + "' must be a multiple of " +
to_string((int) alignment)); to_string((int) alignment));
return; return;
} }
} }
size_t fieldSize = memoryLayout.size(*fieldType); size_t fieldSize = memoryLayout.size(*fieldType);
if (fieldSize > static_cast<size_t>(std::numeric_limits<int>::max() - currentOffset)) { if (fieldSize > static_cast<size_t>(std::numeric_limits<int>::max() - currentOffset)) {
fErrors.error(parentOffset, "field offset overflow"); fContext.errors().error(parentOffset, "field offset overflow");
return; return;
} }
currentOffset += fieldSize; currentOffset += fieldSize;
@ -2116,8 +2117,9 @@ void MetalCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
this->writeExpression(*r.expression(), Precedence::kTopLevel); this->writeExpression(*r.expression(), Precedence::kTopLevel);
this->writeLine(";"); this->writeLine(";");
} else { } else {
fErrors.error(r.fOffset, "Metal does not support returning '" + fContext.errors().error(r.fOffset,
r.expression()->type().description() + "' from main()"); "Metal does not support returning '" +
r.expression()->type().description() + "' from main()");
} }
} }
this->writeReturnStatementFromMain(); this->writeReturnStatementFromMain();
@ -2151,8 +2153,9 @@ void MetalCodeGenerator::writeUniformStruct() {
this->write("struct Uniforms {\n"); this->write("struct Uniforms {\n");
fUniformBuffer = uniformSet; fUniformBuffer = uniformSet;
} else if (uniformSet != fUniformBuffer) { } else if (uniformSet != fUniformBuffer) {
fErrors.error(decls.fOffset, "Metal backend requires all uniforms to have " fContext.errors().error(decls.fOffset,
"the same 'layout(set=...)'"); "Metal backend requires all uniforms to have the same "
"'layout(set=...)'");
} }
this->write(" "); this->write(" ");
this->writeType(var.type()); this->writeType(var.type());
@ -2215,8 +2218,8 @@ void MetalCodeGenerator::writeOutputStruct() {
int location = var.modifiers().fLayout.fLocation; int location = var.modifiers().fLayout.fLocation;
if (location < 0) { if (location < 0) {
fErrors.error(var.fOffset, fContext.errors().error(var.fOffset,
"Metal out variables must have 'layout(location=...)'"); "Metal out variables must have 'layout(location=...)'");
} else if (fProgram.fConfig->fKind == ProgramKind::kVertex) { } else if (fProgram.fConfig->fKind == ProgramKind::kVertex) {
this->write(" [[user(locn" + to_string(location) + ")]]"); this->write(" [[user(locn" + to_string(location) + ")]]");
} else if (fProgram.fConfig->fKind == ProgramKind::kFragment) { } else if (fProgram.fConfig->fKind == ProgramKind::kFragment) {
@ -2600,7 +2603,7 @@ bool MetalCodeGenerator::generateCode() {
write_stringstream(fExtraFunctionPrototypes, *fOut); write_stringstream(fExtraFunctionPrototypes, *fOut);
write_stringstream(fExtraFunctions, *fOut); write_stringstream(fExtraFunctions, *fOut);
write_stringstream(body, *fOut); write_stringstream(body, *fOut);
return 0 == fErrors.errorCount(); return fContext.errors().errorCount() == 0;
} }
} // namespace SkSL } // namespace SkSL

View File

@ -58,12 +58,10 @@ public:
static constexpr const char* SAMPLER_SUFFIX = "Smplr"; static constexpr const char* SAMPLER_SUFFIX = "Smplr";
static constexpr const char* PACKED_PREFIX = "packed_"; static constexpr const char* PACKED_PREFIX = "packed_";
MetalCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors, MetalCodeGenerator(const Context* context, const Program* program, OutputStream* out)
OutputStream* out) : INHERITED(context, program, out)
: INHERITED(program, errors, out)
, fReservedWords({"atan2", "rsqrt", "rint", "dfdx", "dfdy", "vertex", "fragment"}) , fReservedWords({"atan2", "rsqrt", "rint", "dfdx", "dfdy", "vertex", "fragment"})
, fLineEnding("\n") , fLineEnding("\n") {}
, fContext(*context) {}
bool generateCode() override; bool generateCode() override;
@ -276,7 +274,6 @@ protected:
int fAnonInterfaceCount = 0; int fAnonInterfaceCount = 0;
int fPaddingCount = 0; int fPaddingCount = 0;
const char* fLineEnding; const char* fLineEnding;
const Context& fContext;
String fFunctionHeader; String fFunctionHeader;
StringStream fExtraFunctions; StringStream fExtraFunctions;
StringStream fExtraFunctionPrototypes; StringStream fExtraFunctionPrototypes;

View File

@ -439,7 +439,8 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
for (int32_t i = 0; i < (int32_t) type.fields().size(); i++) { for (int32_t i = 0; i < (int32_t) type.fields().size(); i++) {
const Type::Field& field = type.fields()[i]; const Type::Field& field = type.fields()[i];
if (!MemoryLayout::LayoutIsSupported(*field.fType)) { if (!MemoryLayout::LayoutIsSupported(*field.fType)) {
fErrors.error(type.fOffset, "type '" + field.fType->name() + "' is not permitted here"); fContext.errors().error(type.fOffset, "type '" + field.fType->name() +
"' is not permitted here");
return; return;
} }
size_t size = memoryLayout.size(*field.fType); size_t size = memoryLayout.size(*field.fType);
@ -447,14 +448,14 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
const Layout& fieldLayout = field.fModifiers.fLayout; const Layout& fieldLayout = field.fModifiers.fLayout;
if (fieldLayout.fOffset >= 0) { if (fieldLayout.fOffset >= 0) {
if (fieldLayout.fOffset < (int) offset) { if (fieldLayout.fOffset < (int) offset) {
fErrors.error(type.fOffset, fContext.errors().error(type.fOffset,
"offset of field '" + field.fName + "' must be at " "offset of field '" + field.fName + "' must be at "
"least " + to_string((int) offset)); "least " + to_string((int) offset));
} }
if (fieldLayout.fOffset % alignment) { if (fieldLayout.fOffset % alignment) {
fErrors.error(type.fOffset, fContext.errors().error(type.fOffset,
"offset of field '" + field.fName + "' must be a multiple" "offset of field '" + field.fName + "' must be a multiple"
" of " + to_string((int) alignment)); " of " + to_string((int) alignment));
} }
offset = fieldLayout.fOffset; offset = fieldLayout.fOffset;
} else { } else {
@ -581,8 +582,8 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
break; break;
case Type::TypeKind::kArray: { case Type::TypeKind::kArray: {
if (!MemoryLayout::LayoutIsSupported(*type)) { if (!MemoryLayout::LayoutIsSupported(*type)) {
fErrors.error(type->fOffset, fContext.errors().error(type->fOffset,
"type '" + type->name() + "' is not permitted here"); "type '" + type->name() + "' is not permitted here");
return this->nextId(nullptr); return this->nextId(nullptr);
} }
if (type->columns() > 0) { if (type->columns() > 0) {
@ -597,8 +598,8 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
fDecorationBuffer); fDecorationBuffer);
} else { } else {
// We shouldn't have any runtime-sized arrays right now // We shouldn't have any runtime-sized arrays right now
fErrors.error(type->fOffset, fContext.errors().error(type->fOffset,
"runtime-sized arrays are not supported in SPIR-V"); "runtime-sized arrays are not supported in SPIR-V");
this->writeInstruction(SpvOpTypeRuntimeArray, result, this->writeInstruction(SpvOpTypeRuntimeArray, result,
this->getType(type->componentType(), layout), this->getType(type->componentType(), layout),
fConstantBuffer); fConstantBuffer);
@ -787,7 +788,8 @@ SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, OutputStream
const FunctionDeclaration& function = c.function(); const FunctionDeclaration& function = c.function();
auto intrinsic = fIntrinsicMap.find(function.intrinsicKind()); auto intrinsic = fIntrinsicMap.find(function.intrinsicKind());
if (intrinsic == fIntrinsicMap.end()) { if (intrinsic == fIntrinsicMap.end()) {
fErrors.error(c.fOffset, "unsupported intrinsic '" + function.description() + "'"); fContext.errors().error(c.fOffset, "unsupported intrinsic '" + function.description() +
"'");
return -1; return -1;
} }
int32_t intrinsicId; int32_t intrinsicId;
@ -861,7 +863,8 @@ SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, OutputStream
case kSpecial_IntrinsicOpcodeKind: case kSpecial_IntrinsicOpcodeKind:
return this->writeSpecialIntrinsic(c, (SpecialIntrinsic) intrinsicId, out); return this->writeSpecialIntrinsic(c, (SpecialIntrinsic) intrinsicId, out);
default: default:
fErrors.error(c.fOffset, "unsupported intrinsic '" + function.description() + "'"); fContext.errors().error(c.fOffset, "unsupported intrinsic '" + function.description() +
"'");
return -1; return -1;
} }
} }
@ -1176,7 +1179,8 @@ SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, OutputStream&
const ExpressionArray& arguments = c.arguments(); const ExpressionArray& arguments = c.arguments();
const auto& entry = fFunctionMap.find(&function); const auto& entry = fFunctionMap.find(&function);
if (entry == fFunctionMap.end()) { if (entry == fFunctionMap.end()) {
fErrors.error(c.fOffset, "function '" + function.description() + "' is not defined"); fContext.errors().error(c.fOffset, "function '" + function.description() +
"' is not defined");
return -1; return -1;
} }
// Temp variables are used to write back out-parameters after the function call is complete. // Temp variables are used to write back out-parameters after the function call is complete.
@ -1282,8 +1286,8 @@ SpvId SPIRVCodeGenerator::castScalarToType(SpvId inputExprId,
return this->castScalarToBoolean(inputExprId, inputType, outputType, out); return this->castScalarToBoolean(inputExprId, inputType, outputType, out);
} }
fErrors.error(-1, "unsupported cast: " + inputType.description() + fContext.errors().error(-1, "unsupported cast: " + inputType.description() +
" to " + outputType.description()); " to " + outputType.description());
return inputExprId; return inputExprId;
} }
@ -2029,7 +2033,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
} }
SpvId base = lvalue->getPointer(); SpvId base = lvalue->getPointer();
if (base == (SpvId) -1) { if (base == (SpvId) -1) {
fErrors.error(swizzle.fOffset, "unable to retrieve lvalue from swizzle"); fContext.errors().error(swizzle.fOffset, "unable to retrieve lvalue from swizzle");
} }
if (swizzle.components().size() == 1) { if (swizzle.components().size() == 1) {
SpvId member = this->nextId(nullptr); SpvId member = this->nextId(nullptr);
@ -2203,8 +2207,8 @@ SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType,
} else if (is_bool(fContext, operandType)) { } else if (is_bool(fContext, operandType)) {
this->writeInstruction(ifBool, this->getType(resultType), result, lhs, rhs, out); this->writeInstruction(ifBool, this->getType(resultType), result, lhs, rhs, out);
} else { } else {
fErrors.error(operandType.fOffset, fContext.errors().error(operandType.fOffset,
"unsupported operand for binary expression: " + operandType.description()); "unsupported operand for binary expression: " + operandType.description());
} }
return result; return result;
} }
@ -2420,7 +2424,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
resultType, out); resultType, out);
} }
} else { } else {
fErrors.error(leftType.fOffset, "unsupported mixed-type expression"); fContext.errors().error(leftType.fOffset, "unsupported mixed-type expression");
return -1; return -1;
} }
} else { } else {
@ -2551,7 +2555,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs,
return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpUndef, return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpUndef,
SpvOpBitwiseXor, SpvOpBitwiseXor, SpvOpUndef, out); SpvOpBitwiseXor, SpvOpBitwiseXor, SpvOpUndef, out);
default: default:
fErrors.error(0, "unsupported token"); fContext.errors().error(0, "unsupported token");
return -1; return -1;
} }
} }
@ -3042,7 +3046,7 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool a
const Variable& intfVar = intf.variable(); const Variable& intfVar = intf.variable();
const Type& type = intfVar.type(); const Type& type = intfVar.type();
if (!MemoryLayout::LayoutIsSupported(type)) { if (!MemoryLayout::LayoutIsSupported(type)) {
fErrors.error(type.fOffset, "type '" + type.name() + "' is not permitted here"); fContext.errors().error(type.fOffset, "type '" + type.name() + "' is not permitted here");
return this->nextId(nullptr); return this->nextId(nullptr);
} }
SpvStorageClass_ storageClass = get_storage_class(intf.variable(), SpvStorageClassFunction); SpvStorageClass_ storageClass = get_storage_class(intf.variable(), SpvStorageClassFunction);
@ -3490,16 +3494,16 @@ SPIRVCodeGenerator::EntrypointAdapter SPIRVCodeGenerator::writeEntrypointAdapter
VariableReference::RefKind::kWrite); VariableReference::RefKind::kWrite);
// Synthesize a call to the `main()` function. // Synthesize a call to the `main()` function.
if (main.returnType() != skFragColorRef->type()) { if (main.returnType() != skFragColorRef->type()) {
fErrors.error(main.fOffset, "SPIR-V does not support returning '" + fContext.errors().error(main.fOffset, "SPIR-V does not support returning '" +
main.returnType().description() + "' from main()"); main.returnType().description() + "' from main()");
return {}; return {};
} }
ExpressionArray args; ExpressionArray args;
if (main.parameters().size() == 1) { if (main.parameters().size() == 1) {
if (main.parameters()[0]->type() != *fContext.fTypes.fFloat2) { if (main.parameters()[0]->type() != *fContext.fTypes.fFloat2) {
fErrors.error(main.fOffset, fContext.errors().error(main.fOffset,
"SPIR-V does not support parameter of type '" + "SPIR-V does not support parameter of type '" +
main.parameters()[0]->type().description() + "' to main()"); main.parameters()[0]->type().description() + "' to main()");
return {}; return {};
} }
auto zero = std::make_unique<FloatLiteral>( auto zero = std::make_unique<FloatLiteral>(
@ -3590,7 +3594,7 @@ void SPIRVCodeGenerator::addRTFlipUniform(int offset) {
fWroteRTFlip = true; fWroteRTFlip = true;
std::vector<Type::Field> fields; std::vector<Type::Field> fields;
if (fProgram.fConfig->fSettings.fRTFlipOffset < 0) { if (fProgram.fConfig->fSettings.fRTFlipOffset < 0) {
fErrors.error(offset, "RTFlipOffset is negative"); fContext.errors().error(offset, "RTFlipOffset is negative");
} }
fields.emplace_back(Modifiers(Layout(/*flags=*/0, fields.emplace_back(Modifiers(Layout(/*flags=*/0,
/*location=*/-1, /*location=*/-1,
@ -3611,11 +3615,11 @@ void SPIRVCodeGenerator::addRTFlipUniform(int offset) {
fSynthetics.takeOwnershipOfSymbol(Type::MakeStructType(/*offset=*/-1, name, fields)); fSynthetics.takeOwnershipOfSymbol(Type::MakeStructType(/*offset=*/-1, name, fields));
int binding = fProgram.fConfig->fSettings.fRTFlipBinding; int binding = fProgram.fConfig->fSettings.fRTFlipBinding;
if (binding == -1) { if (binding == -1) {
fErrors.error(offset, "layout(binding=...) is required in SPIR-V"); fContext.errors().error(offset, "layout(binding=...) is required in SPIR-V");
} }
int set = fProgram.fConfig->fSettings.fRTFlipSet; int set = fProgram.fConfig->fSettings.fRTFlipSet;
if (set == -1) { if (set == -1) {
fErrors.error(offset, "layout(set=...) is required in SPIR-V"); fContext.errors().error(offset, "layout(set=...) is required in SPIR-V");
} }
bool usePushConstants = fProgram.fConfig->fSettings.fUsePushConstants; bool usePushConstants = fProgram.fConfig->fSettings.fUsePushConstants;
int flags = usePushConstants ? Layout::Flag::kPushConstant_Flag : 0; int flags = usePushConstants ? Layout::Flag::kPushConstant_Flag : 0;
@ -3653,7 +3657,7 @@ void SPIRVCodeGenerator::addRTFlipUniform(int offset) {
name, name,
/*instanceName=*/"", /*instanceName=*/"",
/*arraySize=*/0, /*arraySize=*/0,
std::make_shared<SymbolTable>(&fErrors, /*builtin=*/false)); std::make_shared<SymbolTable>(&fContext.errors(), /*builtin=*/false));
this->writeInterfaceBlock(intf, false); this->writeInterfaceBlock(intf, false);
} }
@ -3675,7 +3679,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
} }
// Make sure we have a main() function. // Make sure we have a main() function.
if (!main) { if (!main) {
fErrors.error(/*offset=*/0, "program does not contain a main() function"); fContext.errors().error(/*offset=*/0, "program does not contain a main() function");
return; return;
} }
// Emit interface blocks. // Emit interface blocks.
@ -3776,7 +3780,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
} }
bool SPIRVCodeGenerator::generateCode() { bool SPIRVCodeGenerator::generateCode() {
SkASSERT(!fErrors.errorCount()); SkASSERT(!fContext.errors().errorCount());
this->writeWord(SpvMagicNumber, *fOut); this->writeWord(SpvMagicNumber, *fOut);
this->writeWord(SpvVersion, *fOut); this->writeWord(SpvVersion, *fOut);
this->writeWord(SKSL_MAGIC, *fOut); this->writeWord(SKSL_MAGIC, *fOut);
@ -3785,7 +3789,7 @@ bool SPIRVCodeGenerator::generateCode() {
this->writeWord(fIdCount, *fOut); this->writeWord(fIdCount, *fOut);
this->writeWord(0, *fOut); // reserved, always zero this->writeWord(0, *fOut); // reserved, always zero
write_stringstream(buffer, *fOut); write_stringstream(buffer, *fOut);
return 0 == fErrors.errorCount(); return fContext.errors().errorCount() == 0;
} }
} // namespace SkSL } // namespace SkSL

View File

@ -128,10 +128,8 @@ public:
SPIRVCodeGenerator(const Context* context, SPIRVCodeGenerator(const Context* context,
const Program* program, const Program* program,
ErrorReporter* errors,
OutputStream* out) OutputStream* out)
: INHERITED(program, errors, out) : INHERITED(context, program, out)
, fContext(*context)
, fDefaultLayout(MemoryLayout::k140_Standard) , fDefaultLayout(MemoryLayout::k140_Standard)
, fCapabilities(0) , fCapabilities(0)
, fIdCount(1) , fIdCount(1)
@ -139,7 +137,7 @@ public:
, fBoolFalse(0) , fBoolFalse(0)
, fSetupFragPosition(false) , fSetupFragPosition(false)
, fCurrentBlock(0) , fCurrentBlock(0)
, fSynthetics(errors, /*builtin=*/true) { , fSynthetics(&fContext.errors(), /*builtin=*/true) {
this->setupIntrinsics(); this->setupIntrinsics();
} }
@ -467,7 +465,6 @@ private:
void addRTFlipUniform(int offset); void addRTFlipUniform(int offset);
const Context& fContext;
const MemoryLayout fDefaultLayout; const MemoryLayout fDefaultLayout;
uint64_t fCapabilities; uint64_t fCapabilities;