Add support for sample() to DSLCPPCodeGenerator.

This CL also removes some vestiges of the kSampler type, which hasn't
been used in .fp files for a long time.

Change-Id: Iaca1d0c6e77ad2df2b6c5dacd1c68079d6dd5cf2
Bug: skia:11854
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/398738
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2021-04-22 16:08:54 -04:00 committed by Skia Commit-Bot
parent abde8fc182
commit d85d720800
5 changed files with 158 additions and 33 deletions

View File

@ -20,6 +20,7 @@ sksl_dsl_fp_tests = [
"/sksl/dslfp/GrDSLFPTest_DoStatement.fp",
"/sksl/dslfp/GrDSLFPTest_ForStatement.fp",
"/sksl/dslfp/GrDSLFPTest_IfStatement.fp",
"/sksl/dslfp/GrDSLFPTest_Sample.fp",
"/sksl/dslfp/GrDSLFPTest_SwitchStatement.fp",
"/sksl/dslfp/GrDSLFPTest_Swizzle.fp",
"/sksl/dslfp/GrDSLFPTest_Ternary.fp",

View File

@ -0,0 +1,14 @@
in fragmentProcessor fp1, fp2, fp3;
half4 main() {
const float2 coords = float2(0.5);
const float3x3 xform = float3x3(2);
const half4 inColor = half4(0.75);
return sample(fp1) *
sample(fp2, coords) *
sample(fp3, xform) *
sample(fp1, inColor) *
sample(fp2, coords, inColor) *
sample(fp3, xform, inColor);
}

View File

@ -23,8 +23,7 @@
namespace SkSL {
static bool needs_uniform_var(const Variable& var) {
return (var.modifiers().fFlags & Modifiers::kUniform_Flag) &&
var.type().typeKind() != Type::TypeKind::kSampler;
return var.modifiers().fFlags & Modifiers::kUniform_Flag;
}
static const char* get_scalar_type_name(const Context& context, const Type& type) {
@ -112,8 +111,7 @@ static bool is_private(const Variable& var) {
static bool is_uniform_in(const Variable& var) {
const Modifiers& modifiers = var.modifiers();
return (modifiers.fFlags & Modifiers::kUniform_Flag) &&
(modifiers.fFlags & Modifiers::kIn_Flag) &&
var.type().typeKind() != Type::TypeKind::kSampler;
(modifiers.fFlags & Modifiers::kIn_Flag);
}
String DSLCPPCodeGenerator::formatRuntimeValue(const Type& type,
@ -303,7 +301,7 @@ int DSLCPPCodeGenerator::getChildFPIndex(const Variable& var) const {
for (const ProgramElement* p : fProgram.elements()) {
if (p->is<GlobalVarDeclaration>()) {
const VarDeclaration& decl =
p->as<GlobalVarDeclaration>().declaration()->as<VarDeclaration>();
p->as<GlobalVarDeclaration>().declaration()->as<VarDeclaration>();
if (&decl.var() == &var) {
return index;
} else if (decl.var().type().isFragmentProcessor()) {
@ -311,15 +309,39 @@ int DSLCPPCodeGenerator::getChildFPIndex(const Variable& var) const {
}
}
}
SkDEBUGFAIL("child fragment processor not found");
SkDEBUGFAILF("child fragment processor for '%s' not found", var.description().c_str());
return 0;
}
void DSLCPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
const FunctionDeclaration& function = c.function();
if (function.isBuiltin() && function.name() == "sample") {
SK_ABORT("not yet implemented: sample() for DSL");
// The first argument to sample() must be a fragment processor. (Old-school samplers are no
// longer supported in FP files.)
const ExpressionArray& arguments = c.arguments();
SkASSERT(arguments.size() >= 1 && arguments.size() <= 3);
const Expression& fpArgument = *arguments.front();
SkASSERT(fpArgument.type().isFragmentProcessor());
// We can't look up the child FP index unless the fragment-processor is a real variable.
if (!fpArgument.is<VariableReference>()) {
fErrors.error(fpArgument.fOffset,
"sample()'s fragmentProcessor argument must be a variable reference\n");
return;
}
// Pass the index of the fragment processor, and all the other arguments as-is.
int childFPIndex = this->getChildFPIndex(*fpArgument.as<VariableReference>().variable());
this->writef("SampleChild(%d", childFPIndex);
for (int index = 1; index < arguments.count(); ++index) {
this->write(", ");
this->writeExpression(*arguments[index], Precedence::kSequence);
}
this->write(")");
return;
}
if (function.isBuiltin()) {
SK_ABORT("not yet implemented: built-in function support for DSL");
}
@ -786,7 +808,6 @@ void DSLCPPCodeGenerator::writePrivateVarValues() {
static bool is_accessible(const Variable& var) {
const Type& type = var.type();
return !type.isFragmentProcessor() &&
Type::TypeKind::kSampler != type.typeKind() &&
Type::TypeKind::kOther != type.typeKind();
}
@ -941,7 +962,6 @@ void DSLCPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
this->writef(" }\n");
}
if (section) {
int samplerIndex = 0;
for (const ProgramElement* p : fProgram.elements()) {
if (p->is<GlobalVarDeclaration>()) {
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
@ -949,18 +969,11 @@ void DSLCPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
const Variable& variable = decl.var();
String nameString(variable.name());
const char* name = nameString.c_str();
if (variable.type().typeKind() == Type::TypeKind::kSampler) {
this->writef(" const GrSurfaceProxyView& %sView = "
"_outer.textureSampler(%d).view();\n",
name, samplerIndex);
this->writef(" GrTexture& %s = *%sView.proxy()->peekTexture();\n",
name, name);
this->writef(" (void) %s;\n", name);
++samplerIndex;
} else if (needs_uniform_var(variable)) {
if (needs_uniform_var(variable)) {
this->writef(" UniformHandle& %s = %sVar;\n"
" (void) %s;\n",
name, HCodeGenerator::FieldName(name).c_str(), name);
" (void) %s;\n",
name, HCodeGenerator::FieldName(name).c_str(), name);
} else if (SectionAndParameterHelper::IsParameter(variable) &&
!variable.type().isFragmentProcessor()) {
if (!wroteProcessor) {
@ -971,8 +984,8 @@ void DSLCPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
if (!variable.type().isFragmentProcessor()) {
this->writef(" auto %s = _outer.%s;\n"
" (void) %s;\n",
name, name, name);
" (void) %s;\n",
name, name, name);
}
}
}
@ -1001,15 +1014,6 @@ void DSLCPPCodeGenerator::writeClone() {
}
this->writef(" {\n");
this->writef(" this->cloneAndRegisterAllChildProcessors(src);\n");
int samplerCount = 0;
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
if (param->type().typeKind() == Type::TypeKind::kSampler) {
++samplerCount;
}
}
if (samplerCount) {
this->writef(" this->setTextureSamplerCnt(%d);", samplerCount);
}
if (fAccessSampleCoordsDirectly) {
this->writef(" this->setUsesSampleCoordsDirectly();\n");
}
@ -1198,8 +1202,9 @@ bool DSLCPPCodeGenerator::generateCode() {
if (p->is<GlobalVarDeclaration>()) {
const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
if ((decl.var().modifiers().fFlags & Modifiers::kUniform_Flag) &&
decl.var().type().typeKind() != Type::TypeKind::kSampler) {
SkASSERT(decl.var().type().typeKind() != Type::TypeKind::kSampler);
if (decl.var().modifiers().fFlags & Modifiers::kUniform_Flag) {
uniforms.push_back(&decl.var());
}

View File

@ -0,0 +1,66 @@
/**************************************************************************************************
*** This file was autogenerated from GrDSLFPTest_Sample.fp; do not modify.
**************************************************************************************************/
/* TODO(skia:11854): DSLCPPCodeGenerator is currently a work in progress. */
#include "GrDSLFPTest_Sample.h"
#include "src/core/SkUtils.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLCPP.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/dsl/priv/DSLFPs.h"
#include "src/sksl/dsl/priv/DSLWriter.h"
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wcomma"
#endif
class GrGLSLDSLFPTest_Sample : public GrGLSLFragmentProcessor {
public:
GrGLSLDSLFPTest_Sample() {}
void emitCode(EmitArgs& args) override {
const GrDSLFPTest_Sample& _outer = args.fFp.cast<GrDSLFPTest_Sample>();
(void) _outer;
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var coords(kConst_Modifier, DSLType(kFloat2_Type), "coords", Float2(0.5));
Var xform(kConst_Modifier, DSLType(kFloat3x3_Type), "xform", Float3x3(2.0));
Var inColor(kConst_Modifier, DSLType(kHalf4_Type), "inColor", Half4(0.75));
Declare(coords);
Declare(xform);
Declare(inColor);
Return(((((SampleChild(0) * SampleChild(1, coords)) * SampleChild(2, xform)) * SampleChild(0, inColor)) * SampleChild(1, coords, inColor)) * SampleChild(2, xform, inColor));
EndFragmentProcessor();
}
private:
void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
}
};
std::unique_ptr<GrGLSLFragmentProcessor> GrDSLFPTest_Sample::onMakeProgramImpl() const {
return std::make_unique<GrGLSLDSLFPTest_Sample>();
}
void GrDSLFPTest_Sample::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
}
bool GrDSLFPTest_Sample::onIsEqual(const GrFragmentProcessor& other) const {
const GrDSLFPTest_Sample& that = other.cast<GrDSLFPTest_Sample>();
(void) that;
return true;
}
GrDSLFPTest_Sample::GrDSLFPTest_Sample(const GrDSLFPTest_Sample& src)
: INHERITED(kGrDSLFPTest_Sample_ClassID, src.optimizationFlags()) {
this->cloneAndRegisterAllChildProcessors(src);
}
std::unique_ptr<GrFragmentProcessor> GrDSLFPTest_Sample::clone() const {
return std::make_unique<GrDSLFPTest_Sample>(*this);
}
#if GR_TEST_UTILS
SkString GrDSLFPTest_Sample::onDumpInfo() const {
return SkString();
}
#endif

View File

@ -0,0 +1,39 @@
/**************************************************************************************************
*** This file was autogenerated from GrDSLFPTest_Sample.fp; do not modify.
**************************************************************************************************/
#ifndef GrDSLFPTest_Sample_DEFINED
#define GrDSLFPTest_Sample_DEFINED
#include "include/core/SkM44.h"
#include "include/core/SkTypes.h"
#include "src/gpu/GrFragmentProcessor.h"
class GrDSLFPTest_Sample : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp1, std::unique_ptr<GrFragmentProcessor> fp2, std::unique_ptr<GrFragmentProcessor> fp3) {
return std::unique_ptr<GrFragmentProcessor>(new GrDSLFPTest_Sample(std::move(fp1), std::move(fp2), std::move(fp3)));
}
GrDSLFPTest_Sample(const GrDSLFPTest_Sample& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "DSLFPTest_Sample"; }
private:
GrDSLFPTest_Sample(std::unique_ptr<GrFragmentProcessor> fp1, std::unique_ptr<GrFragmentProcessor> fp2, std::unique_ptr<GrFragmentProcessor> fp3)
: INHERITED(kGrDSLFPTest_Sample_ClassID, kNone_OptimizationFlags) {
this->registerChild(std::move(fp1), SkSL::SampleUsage::PassThrough());
this->registerChild(std::move(fp2), SkSL::SampleUsage::Explicit());
this->registerChild(std::move(fp3), SkSL::SampleUsage::VariableMatrix(true));
}
std::unique_ptr<GrGLSLFragmentProcessor> onMakeProgramImpl() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;
#if GR_TEST_UTILS
SkString onDumpInfo() const override;
#endif
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
using INHERITED = GrFragmentProcessor;
};
#endif