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:
parent
abde8fc182
commit
d85d720800
@ -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",
|
||||
|
14
resources/sksl/dslfp/GrDSLFPTest_Sample.fp
Normal file
14
resources/sksl/dslfp/GrDSLFPTest_Sample.fp
Normal 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);
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
|
66
tests/sksl/dslfp/GrDSLFPTest_Sample.dsl.cpp
Normal file
66
tests/sksl/dslfp/GrDSLFPTest_Sample.dsl.cpp
Normal 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
|
39
tests/sksl/dslfp/GrDSLFPTest_Sample.h
Normal file
39
tests/sksl/dslfp/GrDSLFPTest_Sample.h
Normal 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
|
Loading…
Reference in New Issue
Block a user