Move function intrinsic handling into Finalizer

This continues the process of moving code out of IRGenerator and into
better homes.

Change-Id: I4803d39ecb2f4c0e916e82e907b5dcaa285a35ce
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/456116
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2021-10-05 14:15:09 -04:00 committed by SkCQ
parent 37c4976947
commit 04b0e0187e
5 changed files with 53 additions and 43 deletions

View File

@ -371,48 +371,9 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(int line, skstd::stri
}
}
void IRGenerator::copyIntrinsicIfNeeded(const FunctionDeclaration& function) {
if (const ProgramElement* found =
fContext.fIntrinsics->findAndInclude(function.description())) {
const FunctionDefinition& original = found->as<FunctionDefinition>();
// Sort the referenced intrinsics into a consistent order; otherwise our output will become
// non-deterministic.
std::vector<const FunctionDeclaration*> intrinsics(original.referencedIntrinsics().begin(),
original.referencedIntrinsics().end());
std::sort(intrinsics.begin(), intrinsics.end(),
[](const FunctionDeclaration* a, const FunctionDeclaration* b) {
if (a->isBuiltin() != b->isBuiltin()) {
return a->isBuiltin() < b->isBuiltin();
}
if (a->fLine != b->fLine) {
return a->fLine < b->fLine;
}
if (a->name() != b->name()) {
return a->name() < b->name();
}
return a->description() < b->description();
});
for (const FunctionDeclaration* f : intrinsics) {
this->copyIntrinsicIfNeeded(*f);
}
fSharedElements->push_back(found);
}
}
std::unique_ptr<Expression> IRGenerator::call(int line,
const FunctionDeclaration& function,
ExpressionArray arguments) {
if (function.isBuiltin()) {
if (function.intrinsicKind() == k_dFdy_IntrinsicKind) {
fInputs.fUseFlipRTUniform = true;
}
if (!fContext.fConfig->fIsBuiltinCode && fContext.fIntrinsics) {
this->copyIntrinsicIfNeeded(function);
}
}
return FunctionCall::Convert(fContext, line, function, std::move(arguments));
}

View File

@ -135,8 +135,6 @@ private:
/** Appends sk_Position fixup to the bottom of main() if this is a vertex program. */
void appendRTAdjustFixupToVertexMain(const FunctionDeclaration& decl, Block* body);
void copyIntrinsicIfNeeded(const FunctionDeclaration& function);
// Runtime effects (and the interpreter, which uses the same CPU runtime) require adherence to
// the strict rules from The OpenGL ES Shading Language Version 1.00. (Including Appendix A).
bool strictES2Mode() const {

View File

@ -92,6 +92,10 @@ SkSL::ProgramSettings& DSLWriter::Settings() {
return Context().fConfig->fSettings;
}
SkSL::Program::Inputs& DSLWriter::Inputs() {
return IRGenerator().fInputs;
}
const std::shared_ptr<SkSL::SymbolTable>& DSLWriter::SymbolTable() {
return IRGenerator().fSymbolTable;
}

View File

@ -79,6 +79,11 @@ public:
*/
static SkSL::ProgramSettings& Settings();
/**
* Returns the Program::Inputs used by the current thread.
*/
static SkSL::Program::Inputs& Inputs();
/**
* Returns the collection to which DSL program elements in this thread should be appended.
*/

View File

@ -7,7 +7,9 @@
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLIntrinsicMap.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/dsl/priv/DSLWriter.h"
#include "src/sksl/ir/SkSLFunctionCall.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
#include "src/sksl/ir/SkSLReturnStatement.h"
@ -35,6 +37,37 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
SkASSERT(fContinuableLevel == std::forward_list<int>{0});
}
void copyIntrinsicIfNeeded(const FunctionDeclaration& function) {
if (const ProgramElement* found =
fContext.fIntrinsics->findAndInclude(function.description())) {
const FunctionDefinition& original = found->as<FunctionDefinition>();
// Sort the referenced intrinsics into a consistent order; otherwise our output will
// become non-deterministic.
std::vector<const FunctionDeclaration*> intrinsics(
original.referencedIntrinsics().begin(),
original.referencedIntrinsics().end());
std::sort(intrinsics.begin(), intrinsics.end(),
[](const FunctionDeclaration* a, const FunctionDeclaration* b) {
if (a->isBuiltin() != b->isBuiltin()) {
return a->isBuiltin() < b->isBuiltin();
}
if (a->fLine != b->fLine) {
return a->fLine < b->fLine;
}
if (a->name() != b->name()) {
return a->name() < b->name();
}
return a->description() < b->description();
});
for (const FunctionDeclaration* f : intrinsics) {
this->copyIntrinsicIfNeeded(*f);
}
dsl::DSLWriter::SharedElements().push_back(found);
}
}
bool functionReturnsValue() const {
return !fFunction.returnType().isVoid();
}
@ -42,9 +75,18 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
bool visitExpression(Expression& expr) override {
if (expr.is<FunctionCall>()) {
const FunctionDeclaration& func = expr.as<FunctionCall>().function();
if (func.isBuiltin() && func.definition()) {
fReferencedIntrinsics->insert(&func);
if (func.isBuiltin()) {
if (func.intrinsicKind() == k_dFdy_IntrinsicKind) {
dsl::DSLWriter::Inputs().fUseFlipRTUniform = true;
}
if (func.definition()) {
fReferencedIntrinsics->insert(&func);
}
if (!fContext.fConfig->fIsBuiltinCode && fContext.fIntrinsics) {
this->copyIntrinsicIfNeeded(func);
}
}
}
return INHERITED::visitExpression(expr);
}