Added DSL fragmentProcessor and Sample function

Change-Id: I76348d151fbf27454a6f60e4f5f7e1774731e61b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/395216
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2021-04-09 15:33:53 -04:00 committed by Skia Commit-Bot
parent 67e52cf47d
commit ee49efcc91
10 changed files with 99 additions and 23 deletions

View File

@ -13,6 +13,7 @@ skia_sksl_sources = [
"$_include/private/SkSLLayout.h",
"$_include/private/SkSLModifiers.h",
"$_include/private/SkSLProgramElement.h",
"$_include/private/SkSLProgramKind.h",
"$_include/private/SkSLSampleUsage.h",
"$_include/private/SkSLStatement.h",
"$_include/private/SkSLString.h",

View File

@ -0,0 +1,29 @@
/*
* Copyright 2021 Google LLC.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkSLProgramKind_DEFINED
#define SkSLProgramKind_DEFINED
#include <cinttypes>
namespace SkSL {
/**
* SkSL supports several different program kinds.
*/
enum class ProgramKind : int8_t {
kFragment,
kVertex,
kGeometry,
kFragmentProcessor,
kRuntimeEffect,
kGeneric,
};
} // namespace SkSL
#endif

View File

@ -8,6 +8,7 @@
#ifndef SKSL_DSL_CORE
#define SKSL_DSL_CORE
#include "include/private/SkSLProgramKind.h"
#include "include/private/SkTArray.h"
#include "include/sksl/DSLBlock.h"
#include "include/sksl/DSLCase.h"
@ -34,7 +35,7 @@ using namespace SkSL::SwizzleComponent;
* Starts DSL output on the current thread using the specified compiler. This must be called
* prior to any other DSL functions.
*/
void Start(SkSL::Compiler* compiler);
void Start(SkSL::Compiler* compiler, SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment);
/**
* Signals the end of DSL output. This must be called sometime between a call to Start() and the
@ -350,6 +351,27 @@ DSLExpression Reflect(DSLExpression i, DSLExpression n, PositionInfo pos = Posit
DSLExpression Refract(DSLExpression i, DSLExpression n, DSLExpression eta,
PositionInfo pos = PositionInfo());
/**
* Samples the child processor at the current coordinates.
*/
DSLExpression Sample(DSLExpression fp, PositionInfo pos = PositionInfo());
/**
* Implements the following functions:
* half4 sample(fragmentProcessor fp, float3x3 transform);
* half4 sample(fragmentProcessor fp, float2 coords);
* half4 sample(fragmentProcessor fp, half4 input);
*/
DSLExpression Sample(DSLExpression target, DSLExpression x, PositionInfo pos = PositionInfo());
/**
* Implements the following functions:
* half4 sample(fragmentProcessor fp, half4 input, float3x3 transform);
* half4 sample(fragmentProcessor fp, half4 input, float2 coords);
*/
DSLExpression Sample(DSLExpression childProcessor, DSLExpression x, DSLExpression y,
PositionInfo pos = PositionInfo());
/**
* Returns x clamped to the range [0, 1]. If x is a vector, operates componentwise.
*/

View File

@ -34,6 +34,7 @@ enum TypeConstant : uint8_t {
kFloat2_Type,
kFloat3_Type,
kFloat4_Type,
kFragmentProcessor_Type,
kInt_Type,
kInt2_Type,
kInt3_Type,

View File

@ -9,21 +9,10 @@
#define SKSL_PROGRAMSETTINGS
#include "include/private/SkSLDefines.h"
#include "include/private/SkSLProgramKind.h"
namespace SkSL {
/**
* SkSL supports several different program kinds.
*/
enum class ProgramKind : int8_t {
kFragment,
kVertex,
kGeometry,
kFragmentProcessor,
kRuntimeEffect,
kGeneric,
};
/**
* Holds the compiler settings for a program.
*/

View File

@ -25,9 +25,8 @@ namespace SkSL {
namespace dsl {
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
void Start(SkSL::Compiler* compiler) {
DSLWriter::SetInstance(std::make_unique<DSLWriter>(compiler));
void Start(SkSL::Compiler* compiler, ProgramKind kind) {
DSLWriter::SetInstance(std::make_unique<DSLWriter>(compiler, kind));
}
void End() {
@ -35,7 +34,6 @@ void End() {
"more calls to StartFragmentProcessor than to EndFragmentProcessor");
DSLWriter::SetInstance(nullptr);
}
#endif // SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
void SetErrorHandler(ErrorHandler* errorHandler) {
DSLWriter::SetErrorHandler(errorHandler);
@ -361,6 +359,20 @@ DSLExpression Refract(DSLExpression i, DSLExpression n, DSLExpression eta, Posit
return DSLExpression(DSLCore::Call("refract", std::move(i), std::move(n), std::move(eta)), pos);
}
DSLExpression Sample(DSLExpression target, PositionInfo pos) {
return DSLExpression(DSLCore::Call("sample", std::move(target)), pos);
}
DSLExpression Sample(DSLExpression target, DSLExpression x, PositionInfo pos) {
return DSLExpression(DSLCore::Call("sample", std::move(target), std::move(x)), pos);
}
DSLExpression Sample(DSLExpression target, DSLExpression x, DSLExpression y, PositionInfo pos) {
return DSLExpression(DSLCore::Call("sample", std::move(target), std::move(x), std::move(y)),
pos);
}
DSLExpression Saturate(DSLExpression x, PositionInfo pos) {
return DSLExpression(DSLCore::Call("saturate", std::move(x)), pos);
}

View File

@ -45,6 +45,8 @@ const SkSL::Type& DSLType::skslType() const {
return *context.fTypes.fFloat3;
case kFloat4_Type:
return *context.fTypes.fFloat4;
case kFragmentProcessor_Type:
return *context.fTypes.fFragmentProcessor;
case kInt_Type:
return *context.fTypes.fInt;
case kInt2_Type:

View File

@ -31,10 +31,10 @@ namespace SkSL {
namespace dsl {
DSLWriter::DSLWriter(SkSL::Compiler* compiler)
DSLWriter::DSLWriter(SkSL::Compiler* compiler, SkSL::ProgramKind kind)
: fCompiler(compiler) {
SkSL::ParsedModule module = fCompiler->moduleForProgramKind(SkSL::ProgramKind::kFragment);
fConfig.fKind = SkSL::ProgramKind::kFragment;
SkSL::ParsedModule module = fCompiler->moduleForProgramKind(kind);
fConfig.fKind = kind;
SkSL::IRGenerator& ir = *fCompiler->fIRGenerator;
fOldSymbolTable = ir.fSymbolTable;

View File

@ -43,7 +43,7 @@ class ErrorHandler;
*/
class DSLWriter {
public:
DSLWriter(SkSL::Compiler* compiler);
DSLWriter(SkSL::Compiler* compiler, SkSL::ProgramKind kind);
~DSLWriter();
@ -140,6 +140,10 @@ public:
static void EndFragmentProcessor();
static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLVar& var);
#else
static bool InFragmentProcessor() {
return false;
}
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
static std::unique_ptr<SkSL::Expression> Call(const FunctionDeclaration& function,

View File

@ -27,8 +27,9 @@ using namespace SkSL::dsl;
*/
class AutoDSLContext {
public:
AutoDSLContext(GrGpu* gpu, bool markVarsDeclared = true) {
Start(gpu->shaderCompiler());
AutoDSLContext(GrGpu* gpu, bool markVarsDeclared = true,
SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment) {
Start(gpu->shaderCompiler(), kind);
DSLWriter::Instance().fMangle = false;
DSLWriter::Instance().fMarkVarsDeclared = markVarsDeclared;
}
@ -1394,6 +1395,21 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLModifiers, r, ctxInfo) {
// Uniforms do not need to be explicitly declared
}
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSample, r, ctxInfo) {
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), /*markVarsDeclared=*/true,
SkSL::ProgramKind::kFragmentProcessor);
DSLVar child(kUniform_Modifier, kFragmentProcessor_Type, "child");
EXPECT_EQUAL(Sample(child), "sample(child)");
EXPECT_EQUAL(Sample(child, Float2(0, 0)), "sample(child, float2(0.0, 0.0))");
EXPECT_EQUAL(Sample(child, Half4(1)), "sample(child, half4(1.0))");
EXPECT_EQUAL(Sample(child, Half4(1), Float2(0)), "sample(child, half4(1.0), float2(0.0))");
{
ExpectError error(r, "error: no match for sample(fragmentProcessor, bool)\n");
Sample(child, true).release();
}
}
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStruct, r, ctxInfo) {
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), /*markVarsDeclared=*/false);