Refactored IRGenerator::convertInterfaceBlock

Previously the magic surrounding sk_RTAdjust was inaccessible to the
DSL, meaning that the DSLParser would not work properly when the
sk_RTAdjust field was present in an interface block. This refactoring
means all interface blocks are processed via the same path.

Change-Id: I99a2fe6875dfcbccc53f7a44f0fb1912cb2722ce
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/442456
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
Ethan Nicholas 2021-08-27 19:17:01 -04:00 committed by SkCQ
parent b42c3834af
commit 494eb3e877
4 changed files with 75 additions and 31 deletions

View File

@ -801,6 +801,21 @@ std::unique_ptr<StructDefinition> IRGenerator::convertStructDefinition(const AST
return std::make_unique<StructDefinition>(node.fOffset, *type);
}
void IRGenerator::scanInterfaceBlock(SkSL::InterfaceBlock& intf) {
const std::vector<Type::Field>& fields = intf.variable().type().componentType().fields();
for (size_t i = 0; i < fields.size(); ++i) {
const Type::Field& f = fields[i];
if (f.fName == Compiler::RTADJUST_NAME) {
if (*f.fType == *fContext.fTypes.fFloat4) {
fRTAdjustInterfaceBlock = &intf.variable();
fRTAdjustFieldIndex = i;
} else {
this->errorReporter().error(intf.fOffset, "sk_RTAdjust must have type 'float4'");
}
}
}
}
std::unique_ptr<SkSL::InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode& intf) {
if (this->programKind() != ProgramKind::kFragment &&
this->programKind() != ProgramKind::kVertex) {
@ -813,7 +828,6 @@ std::unique_ptr<SkSL::InterfaceBlock> IRGenerator::convertInterfaceBlock(const A
std::shared_ptr<SymbolTable> old = fSymbolTable;
std::shared_ptr<SymbolTable> symbols;
std::vector<Type::Field> fields;
bool foundRTAdjust = false;
auto iter = intf.begin();
{
AutoSymbolTable table(this);
@ -826,11 +840,6 @@ std::unique_ptr<SkSL::InterfaceBlock> IRGenerator::convertInterfaceBlock(const A
}
for (const auto& decl : decls) {
const VarDeclaration& vd = decl->as<VarDeclaration>();
if (&vd.var() == fRTAdjust) {
foundRTAdjust = true;
SkASSERT(vd.var().type() == *fContext.fTypes.fFloat4);
fRTAdjustFieldIndex = fields.size();
}
fields.push_back(Type::Field(vd.var().modifiers(), vd.var().name(),
&vd.var().type()));
}
@ -855,9 +864,6 @@ std::unique_ptr<SkSL::InterfaceBlock> IRGenerator::convertInterfaceBlock(const A
type,
fIsBuiltinCode,
Variable::Storage::kGlobal));
if (foundRTAdjust) {
fRTAdjustInterfaceBlock = var;
}
if (id.fInstanceName.length()) {
old->addWithoutOwnership(var);
} else {
@ -865,12 +871,10 @@ std::unique_ptr<SkSL::InterfaceBlock> IRGenerator::convertInterfaceBlock(const A
old->add(std::make_unique<Field>(intf.fOffset, var, (int)i));
}
}
return std::make_unique<SkSL::InterfaceBlock>(intf.fOffset,
var,
id.fTypeName,
id.fInstanceName,
arraySize,
symbols);
std::unique_ptr<SkSL::InterfaceBlock> result = std::make_unique<SkSL::InterfaceBlock>(
intf.fOffset, var, id.fTypeName, id.fInstanceName, arraySize, symbols);
this->scanInterfaceBlock(*result);
return result;
}
void IRGenerator::convertGlobalVarDeclarations(const ASTNode& decl) {

View File

@ -144,6 +144,10 @@ public:
std::unique_ptr<Expression> convertIdentifier(int offset, skstd::string_view identifier);
bool haveRTAdjustInterfaceBlock() { return fRTAdjustInterfaceBlock != nullptr; }
int getRTAdjustFieldIndex() { return fRTAdjustFieldIndex; }
const Context& fContext;
private:
@ -205,6 +209,7 @@ private:
std::unique_ptr<Statement> convertFor(const ASTNode& f);
std::unique_ptr<Expression> convertIdentifier(const ASTNode& identifier);
std::unique_ptr<Statement> convertIf(const ASTNode& s);
void scanInterfaceBlock(SkSL::InterfaceBlock& intf);
std::unique_ptr<InterfaceBlock> convertInterfaceBlock(const ASTNode& s);
Modifiers convertModifiers(const Modifiers& m);
std::unique_ptr<Expression> convertPrefixExpression(const ASTNode& expression);

View File

@ -216,8 +216,10 @@ public:
if (!DSLWriter::Settings().fDSLMarkVarsDeclared) {
DSLWriter::MarkDeclared(var);
}
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::InterfaceBlock>(/*offset=*/-1,
DSLWriter::Var(var), typeName, varName, arraySize, DSLWriter::SymbolTable()));
auto intf = std::make_unique<SkSL::InterfaceBlock>(/*offset=*/-1,
DSLWriter::Var(var), typeName, varName, arraySize, DSLWriter::SymbolTable());
DSLWriter::IRGenerator().scanInterfaceBlock(*intf);
DSLWriter::ProgramElements().push_back(std::move(intf));
if (varName.empty()) {
const std::vector<SkSL::Type::Field>& structFields = structType->fields();
const SkSL::Variable* skslVar = DSLWriter::Var(var);
@ -229,6 +231,7 @@ public:
} else {
AddToSymbolTable(var);
}
GetErrorReporter().reportPendingErrors(pos);
return var;
}

View File

@ -2002,20 +2002,52 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWrapper, r, ctxInfo) {
}
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLRTAdjust, r, ctxInfo) {
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared(),
SkSL::ProgramKind::kVertex);
DSLGlobalVar rtAdjust(kUniform_Modifier, kFloat4_Type, "sk_RTAdjust");
Declare(rtAdjust);
DSLFunction(kVoid_Type, "main").define(
sk_Position() = Half4(0)
);
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1],
"void main() {"
"(sk_PerVertex.sk_Position = float4(0.0));"
"(sk_PerVertex.sk_Position = float4(((sk_PerVertex.sk_Position.xy * sk_RTAdjust.xz) + "
"(sk_PerVertex.sk_Position.ww * sk_RTAdjust.yw)), 0.0, sk_PerVertex.sk_Position.w));"
"}");
{
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared(),
SkSL::ProgramKind::kVertex);
DSLGlobalVar rtAdjust(kUniform_Modifier, kFloat4_Type, "sk_RTAdjust");
Declare(rtAdjust);
DSLFunction(kVoid_Type, "main").define(
sk_Position() = Half4(0)
);
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1],
"void main() {"
"(sk_PerVertex.sk_Position = float4(0.0));"
"(sk_PerVertex.sk_Position = float4(((sk_PerVertex.sk_Position.xy * sk_RTAdjust.xz) + "
"(sk_PerVertex.sk_Position.ww * sk_RTAdjust.yw)), 0.0, sk_PerVertex.sk_Position.w));"
"}");
}
{
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared(),
SkSL::ProgramKind::kVertex);
REPORTER_ASSERT(r, !DSLWriter::IRGenerator().haveRTAdjustInterfaceBlock());
DSLGlobalVar intf = InterfaceBlock(kUniform_Modifier, "uniforms",
{ Field(kInt_Type, "unused"),
Field(kFloat4_Type, "sk_RTAdjust") });
REPORTER_ASSERT(r, DSLWriter::IRGenerator().haveRTAdjustInterfaceBlock());
REPORTER_ASSERT(r, DSLWriter::IRGenerator().getRTAdjustFieldIndex() == 1);
}
{
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared(),
SkSL::ProgramKind::kVertex);
ExpectError error(r, "sk_RTAdjust must have type 'float4'");
InterfaceBlock(kUniform_Modifier, "uniforms",
{ Field(kInt_Type, "unused"), Field(kHalf4_Type, "sk_RTAdjust") });
}
{
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared(),
SkSL::ProgramKind::kVertex);
ExpectError error(r, "symbol 'sk_RTAdjust' was already defined");
InterfaceBlock(kUniform_Modifier, "uniforms1",
{ Field(kInt_Type, "unused1"), Field(kFloat4_Type, "sk_RTAdjust") });
InterfaceBlock(kUniform_Modifier, "uniforms2",
{ Field(kInt_Type, "unused2"), Field(kFloat4_Type, "sk_RTAdjust") });
}
}
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInlining, r, ctxInfo) {