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:
parent
b42c3834af
commit
494eb3e877
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user