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:
parent
abae48eb5b
commit
3abc6c68ad
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user