Added modifier support to DSLFunction
This also includes a couple of fixes to DSLFunction error reporting. Change-Id: Iab813143511c408df2dba7a4dc8beddea1a8e8d0 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/427736 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
6b7ec00e6e
commit
292a09da2b
@ -27,7 +27,12 @@ class DSLType;
|
||||
class DSLFunction {
|
||||
public:
|
||||
template<class... Parameters>
|
||||
DSLFunction(const DSLType& returnType, skstd::string_view name, Parameters&... parameters) {
|
||||
DSLFunction(const DSLType& returnType, skstd::string_view name, Parameters&... parameters)
|
||||
: DSLFunction(DSLModifiers(), returnType, name, parameters...) {}
|
||||
|
||||
template<class... Parameters>
|
||||
DSLFunction(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
Parameters&... parameters) {
|
||||
SkTArray<DSLVar*> parameterArray;
|
||||
parameterArray.reserve_back(sizeof...(parameters));
|
||||
|
||||
@ -35,11 +40,16 @@ public:
|
||||
// (parameterArray.push_back(¶meters), ...);
|
||||
int unused[] = {0, (static_cast<void>(parameterArray.push_back(¶meters)), 0)...};
|
||||
static_cast<void>(unused);
|
||||
this->init(returnType, name, std::move(parameterArray));
|
||||
this->init(modifiers, returnType, name, std::move(parameterArray));
|
||||
}
|
||||
|
||||
DSLFunction(const DSLType& returnType, const char* name, SkTArray<DSLVar*> parameters) {
|
||||
this->init(returnType, name, std::move(parameters));
|
||||
DSLFunction(const DSLType& returnType, skstd::string_view name, SkTArray<DSLVar*> parameters) {
|
||||
this->init(DSLModifiers(), returnType, name, std::move(parameters));
|
||||
}
|
||||
|
||||
DSLFunction(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
SkTArray<DSLVar*> parameters) {
|
||||
this->init(modifiers, returnType, name, std::move(parameters));
|
||||
}
|
||||
|
||||
DSLFunction(const SkSL::FunctionDeclaration* decl)
|
||||
@ -88,7 +98,8 @@ private:
|
||||
collectArgs(args, std::forward<RemainingArgs>(remaining)...);
|
||||
}
|
||||
|
||||
void init(const DSLType& returnType, skstd::string_view name, SkTArray<DSLVar*> params);
|
||||
void init(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
SkTArray<DSLVar*> params);
|
||||
|
||||
const SkSL::FunctionDeclaration* fDecl = nullptr;
|
||||
};
|
||||
|
@ -18,8 +18,20 @@ namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
|
||||
void DSLFunction::init(const DSLType& returnType, skstd::string_view name,
|
||||
void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
SkTArray<DSLVar*> params) {
|
||||
// Conservatively assume all user-defined functions have side effects.
|
||||
if (!DSLWriter::IsModule()) {
|
||||
modifiers.fModifiers.fFlags |= Modifiers::kHasSideEffects_Flag;
|
||||
}
|
||||
|
||||
if (DSLWriter::Context().fConfig->fSettings.fForceNoInline) {
|
||||
// Apply the `noinline` modifier to every function. This allows us to test Runtime
|
||||
// Effects without any inlining, even when the code is later added to a paint.
|
||||
modifiers.fModifiers.fFlags &= ~Modifiers::kInline_Flag;
|
||||
modifiers.fModifiers.fFlags |= Modifiers::kNoInline_Flag;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Variable>> paramVars;
|
||||
paramVars.reserve(params.size());
|
||||
bool isMain = name == "main";
|
||||
@ -66,20 +78,26 @@ void DSLFunction::init(const DSLType& returnType, skstd::string_view name,
|
||||
param->fDeclaration = nullptr;
|
||||
}
|
||||
SkASSERT(paramVars.size() == params.size());
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
params[i]->fVar = paramVars[i].get();
|
||||
}
|
||||
fDecl = SkSL::FunctionDeclaration::Convert(DSLWriter::Context(),
|
||||
*DSLWriter::SymbolTable(),
|
||||
/*offset=*/-1,
|
||||
DSLWriter::Modifiers(SkSL::Modifiers()),
|
||||
DSLWriter::Modifiers(modifiers.fModifiers),
|
||||
isMain ? name : DSLWriter::Name(name),
|
||||
std::move(paramVars), &returnType.skslType(),
|
||||
/*isBuiltin=*/false);
|
||||
DSLWriter::IsModule());
|
||||
DSLWriter::ReportErrors();
|
||||
if (fDecl) {
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
params[i]->fVar = fDecl->parameters()[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DSLFunction::define(DSLBlock block) {
|
||||
if (!fDecl) {
|
||||
// Evidently we failed to create the declaration; error should already have been reported.
|
||||
// Release the block so we don't fail its destructor assert.
|
||||
block.release();
|
||||
return;
|
||||
}
|
||||
SkASSERTF(!fDecl->definition(), "function '%s' already defined", fDecl->description().c_str());
|
||||
@ -98,7 +116,8 @@ DSLExpression DSLFunction::call(SkTArray<DSLWrapper<DSLExpression>> args) {
|
||||
for (DSLWrapper<DSLExpression>& arg : args) {
|
||||
released.push_back(arg->release());
|
||||
}
|
||||
return DSLExpression(DSLWriter::Call(*fDecl, std::move(released)));
|
||||
std::unique_ptr<SkSL::Expression> result = DSLWriter::Call(*fDecl, std::move(released));
|
||||
return result ? DSLExpression(std::move(result)) : DSLExpression();
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
@ -36,7 +36,8 @@ DSLWriter::DSLWriter(SkSL::Compiler* compiler, SkSL::ProgramKind kind,
|
||||
const SkSL::ProgramSettings& settings, SkSL::ParsedModule module,
|
||||
bool isModule)
|
||||
: fCompiler(compiler)
|
||||
, fSettings(settings) {
|
||||
, fSettings(settings)
|
||||
, fIsModule(isModule) {
|
||||
fOldModifiersPool = fCompiler->fContext->fModifiersPool;
|
||||
|
||||
fOldConfig = fCompiler->fContext->fConfig;
|
||||
@ -151,6 +152,9 @@ DSLPossibleExpression DSLWriter::Construct(const SkSL::Type& type,
|
||||
args.reserve_back(rawArgs.size());
|
||||
|
||||
for (DSLExpression& arg : rawArgs) {
|
||||
if (!arg.valid()) {
|
||||
return DSLPossibleExpression(nullptr);
|
||||
}
|
||||
args.push_back(arg.release());
|
||||
}
|
||||
return SkSL::Constructor::Convert(Context(), /*offset=*/-1, type, std::move(args));
|
||||
|
@ -98,6 +98,8 @@ public:
|
||||
*/
|
||||
static std::unique_ptr<ProgramConfig>& GetProgramConfig() { return Instance().fConfig; }
|
||||
|
||||
static bool IsModule() { return Instance().fIsModule; }
|
||||
|
||||
static void Reset();
|
||||
|
||||
/**
|
||||
@ -272,6 +274,7 @@ private:
|
||||
ErrorHandler* fErrorHandler = nullptr;
|
||||
ProgramSettings fSettings;
|
||||
Mangler fMangler;
|
||||
bool fIsModule;
|
||||
bool fEncounteredErrors = false;
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
struct StackFrame {
|
||||
|
@ -126,7 +126,8 @@ static SkSL::String stringize(DSLPossibleStatement& stmt) { return stmt.release
|
||||
static SkSL::String stringize(DSLExpression& expr) { return expr.release()->description(); }
|
||||
static SkSL::String stringize(DSLPossibleExpression& expr) { return expr.release()->description(); }
|
||||
static SkSL::String stringize(DSLBlock& blck) { return blck.release()->description(); }
|
||||
static SkSL::String stringize(SkSL::IRNode& node) { return node.description(); }
|
||||
static SkSL::String stringize(SkSL::IRNode& node) { return node.description(); }
|
||||
static SkSL::String stringize(SkSL::Program& program) { return program.description(); }
|
||||
|
||||
template <typename T>
|
||||
static void expect_equal(skiatest::Reporter* r, int lineNumber, T& input, const char* expected) {
|
||||
@ -1978,3 +1979,24 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLRTAdjust, r, ctxInfo) {
|
||||
"(sk_PerVertex.sk_Position.ww * sk_RTAdjust.yw)), 0.0, sk_PerVertex.sk_Position.w));"
|
||||
"}");
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInlining, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared());
|
||||
DSLVar x(kFloat_Type, "x");
|
||||
DSLFunction sqr(kFloat_Type, "sqr", x);
|
||||
sqr.define(
|
||||
Return(x * x)
|
||||
);
|
||||
DSLFunction(kVoid_Type, "main").define(
|
||||
sk_FragColor() = (sqr(2), Half4(sqr(3)))
|
||||
);
|
||||
std::unique_ptr<SkSL::Program> program = ReleaseProgram();
|
||||
EXPECT_EQUAL(*program,
|
||||
"layout(location = 0, index = 0, builtin = 10001) out half4 sk_FragColor;"
|
||||
"layout(builtin = 17)in bool sk_Clockwise;"
|
||||
"void main() {"
|
||||
"/* inlined: sqr */;"
|
||||
"/* inlined: sqr */;"
|
||||
"(sk_FragColor = (4.0 , half4(half(9.0))));"
|
||||
"}");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user