Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables. This splits it into three separate subclasses. In addition to just being a cleaner API in general, this also addresses an issue we ran into with the upcoming DSLParser: previously, a global DSLVar's storage was not set correctly until DeclareGlobal was called, so an AddToSymbolTable call prior to DeclareGlobal would create the SkSL variable with the wrong storage, causing spurious errors on global-only modifiers. But holding off on the AddToSymbolTable tends to break constructs like "int x = 0, y = x", so improving the API seemed like the best way to address it. Now that we have greater type safety around variables, we can potentially avoid having to call AddToSymbolTable for DSLVar and DSLGlobalVar altogether, since we know they are both supposed to end up in the symbol table, but that isn't something I want to change in this CL. Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
0397ae4e15
commit
a2d22b2e08
@ -36,8 +36,8 @@ public:
|
||||
Declare(x);
|
||||
SkASSERT(DSLWriter::Var(x)->initialValue()->description() == "1");
|
||||
|
||||
Var blueAlpha(kUniform_Modifier, kHalf2_Type, "blueAlpha");
|
||||
DeclareGlobal(blueAlpha);
|
||||
GlobalVar blueAlpha(kUniform_Modifier, kHalf2_Type, "blueAlpha");
|
||||
Declare(blueAlpha);
|
||||
fBlueAlphaUniform = VarUniformHandle(blueAlpha);
|
||||
Var coords(kFloat4_Type, sk_FragCoord());
|
||||
Declare(coords);
|
||||
|
@ -19,8 +19,10 @@ using Case = DSLCase;
|
||||
using Expression = DSLExpression;
|
||||
using Field = DSLField;
|
||||
using Function = DSLFunction;
|
||||
using GlobalVar = DSLGlobalVar;
|
||||
using Layout = DSLLayout;
|
||||
using Modifiers = DSLModifiers;
|
||||
using Parameter = DSLParameter;
|
||||
using Statement = DSLStatement;
|
||||
using Var = DSLVar;
|
||||
template<typename T> using Wrapper = DSLWrapper<T>;
|
||||
|
@ -59,9 +59,9 @@ std::unique_ptr<SkSL::Program> ReleaseProgram();
|
||||
*/
|
||||
void SetErrorHandler(ErrorHandler* errorHandler);
|
||||
|
||||
DSLVar sk_FragColor();
|
||||
DSLGlobalVar sk_FragColor();
|
||||
|
||||
DSLVar sk_FragCoord();
|
||||
DSLGlobalVar sk_FragCoord();
|
||||
|
||||
DSLExpression sk_Position();
|
||||
|
||||
@ -83,7 +83,7 @@ DSLStatement Declare(DSLVar& var, PositionInfo pos = PositionInfo());
|
||||
/**
|
||||
* Declares a global variable.
|
||||
*/
|
||||
void DeclareGlobal(DSLVar& var, PositionInfo pos = PositionInfo());
|
||||
void Declare(DSLGlobalVar& var, PositionInfo pos = PositionInfo());
|
||||
|
||||
/**
|
||||
* default: statements
|
||||
@ -115,9 +115,9 @@ DSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression nex
|
||||
DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse = DSLStatement(),
|
||||
PositionInfo pos = PositionInfo());
|
||||
|
||||
DSLVar InterfaceBlock(DSLModifiers modifiers, skstd::string_view typeName,
|
||||
SkTArray<DSLField> fields, skstd::string_view varName = "", int arraySize = 0,
|
||||
PositionInfo pos = PositionInfo());
|
||||
DSLGlobalVar InterfaceBlock(DSLModifiers modifiers, skstd::string_view typeName,
|
||||
SkTArray<DSLField> fields, skstd::string_view varName = "",
|
||||
int arraySize = 0, PositionInfo pos = PositionInfo());
|
||||
|
||||
/**
|
||||
* return [value];
|
||||
|
@ -27,7 +27,7 @@ namespace dsl {
|
||||
class DSLPossibleExpression;
|
||||
class DSLStatement;
|
||||
class DSLType;
|
||||
class DSLVar;
|
||||
class DSLVarBase;
|
||||
|
||||
/**
|
||||
* Represents an expression such as 'cos(x)' or 'a + b'.
|
||||
@ -69,9 +69,9 @@ public:
|
||||
/**
|
||||
* Creates an expression representing a variable reference.
|
||||
*/
|
||||
DSLExpression(DSLVar& var);
|
||||
DSLExpression(DSLVarBase& var);
|
||||
|
||||
DSLExpression(DSLVar&& var);
|
||||
DSLExpression(DSLVarBase&& var);
|
||||
|
||||
DSLExpression(DSLPossibleExpression expr, PositionInfo pos = PositionInfo());
|
||||
|
||||
@ -150,7 +150,7 @@ private:
|
||||
friend class DSLCore;
|
||||
friend class DSLFunction;
|
||||
friend class DSLPossibleExpression;
|
||||
friend class DSLVar;
|
||||
friend class DSLVarBase;
|
||||
friend class DSLWriter;
|
||||
template<typename T> friend class DSLWrapper;
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
template<class... Parameters>
|
||||
DSLFunction(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
Parameters&... parameters) {
|
||||
SkTArray<DSLVar*> parameterArray;
|
||||
SkTArray<DSLParameter*> parameterArray;
|
||||
parameterArray.reserve_back(sizeof...(parameters));
|
||||
|
||||
// in C++17, we could just do:
|
||||
@ -43,12 +43,13 @@ public:
|
||||
this->init(modifiers, returnType, name, std::move(parameterArray));
|
||||
}
|
||||
|
||||
DSLFunction(const DSLType& returnType, skstd::string_view name, SkTArray<DSLVar*> parameters) {
|
||||
DSLFunction(const DSLType& returnType, skstd::string_view name,
|
||||
SkTArray<DSLParameter*> parameters) {
|
||||
this->init(DSLModifiers(), returnType, name, std::move(parameters));
|
||||
}
|
||||
|
||||
DSLFunction(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
SkTArray<DSLVar*> parameters) {
|
||||
SkTArray<DSLParameter*> parameters) {
|
||||
this->init(modifiers, returnType, name, std::move(parameters));
|
||||
}
|
||||
|
||||
@ -99,7 +100,7 @@ private:
|
||||
}
|
||||
|
||||
void init(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
SkTArray<DSLVar*> params);
|
||||
SkTArray<DSLParameter*> params);
|
||||
|
||||
const SkSL::FunctionDeclaration* fDecl = nullptr;
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ private:
|
||||
|
||||
friend DSLType Struct(skstd::string_view name, SkTArray<DSLField> fields);
|
||||
friend class DSLFunction;
|
||||
friend class DSLVar;
|
||||
friend class DSLVarBase;
|
||||
friend class DSLWriter;
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ bool IsType(skstd::string_view name);
|
||||
/**
|
||||
* Adds a variable to the current symbol table.
|
||||
*/
|
||||
void AddToSymbolTable(DSLVar& var);
|
||||
void AddToSymbolTable(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* Attaches a String to the current symbol table. The String will persist as long as the symbol
|
||||
|
@ -21,6 +21,7 @@ namespace dsl {
|
||||
|
||||
class DSLExpression;
|
||||
class DSLField;
|
||||
class DSLVarBase;
|
||||
|
||||
enum TypeConstant : uint8_t {
|
||||
kBool_Type,
|
||||
@ -157,7 +158,7 @@ private:
|
||||
static void CollectArgs(SkTArray<DSLExpression>& args) {}
|
||||
|
||||
template<class... RemainingArgs>
|
||||
static void CollectArgs(SkTArray<DSLExpression>& args, DSLVar& var,
|
||||
static void CollectArgs(SkTArray<DSLExpression>& args, DSLVarBase& var,
|
||||
RemainingArgs&&... remaining) {
|
||||
args.push_back(var);
|
||||
CollectArgs(args, std::forward<RemainingArgs>(remaining)...);
|
||||
@ -176,7 +177,7 @@ private:
|
||||
friend DSLType Struct(skstd::string_view name, SkTArray<DSLField> fields);
|
||||
friend class DSLCore;
|
||||
friend class DSLFunction;
|
||||
friend class DSLVar;
|
||||
friend class DSLVarBase;
|
||||
friend class DSLWriter;
|
||||
};
|
||||
|
||||
|
@ -21,12 +21,12 @@ enum class VariableStorage : int8_t;
|
||||
|
||||
namespace dsl {
|
||||
|
||||
class DSLVar {
|
||||
class DSLVarBase {
|
||||
public:
|
||||
/**
|
||||
* Creates an empty, unpopulated DSLVar. Can be replaced with a real DSLVar later via `swap`.
|
||||
* Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`.
|
||||
*/
|
||||
DSLVar() : fType(kVoid_Type), fDeclared(true) {}
|
||||
DSLVarBase() : fType(kVoid_Type), fDeclared(true) {}
|
||||
|
||||
/**
|
||||
* Constructs a new variable with the specified type and name. The name is used (in mangled
|
||||
@ -34,26 +34,18 @@ public:
|
||||
* name conflicts and the variable's name is only important when debugging shaders, the name
|
||||
* parameter is optional.
|
||||
*/
|
||||
DSLVar(DSLType type, skstd::string_view name = "var",
|
||||
DSLExpression initialValue = DSLExpression());
|
||||
DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue);
|
||||
|
||||
DSLVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression())
|
||||
: DSLVar(type, skstd::string_view(name), std::move(initialValue)) {}
|
||||
DSLVarBase(DSLType type, DSLExpression initialValue);
|
||||
|
||||
DSLVar(DSLType type, DSLExpression initialValue);
|
||||
DSLVarBase(DSLModifiers modifiers, DSLType type, skstd::string_view name,
|
||||
DSLExpression initialValue);
|
||||
|
||||
DSLVar(DSLModifiers modifiers, DSLType type, skstd::string_view name = "var",
|
||||
DSLExpression initialValue = DSLExpression());
|
||||
DSLVarBase(DSLModifiers modifiers, DSLType type, DSLExpression initialValue);
|
||||
|
||||
DSLVar(DSLModifiers modifiers, DSLType type, const char* name,
|
||||
DSLExpression initialValue = DSLExpression())
|
||||
: DSLVar(modifiers, type, skstd::string_view(name), std::move(initialValue)) {}
|
||||
DSLVarBase(DSLVarBase&&) = default;
|
||||
|
||||
DSLVar(DSLModifiers modifiers, DSLType type, DSLExpression initialValue);
|
||||
|
||||
DSLVar(DSLVar&&) = default;
|
||||
|
||||
~DSLVar();
|
||||
virtual ~DSLVarBase();
|
||||
|
||||
skstd::string_view name() const {
|
||||
return fName;
|
||||
@ -63,7 +55,7 @@ public:
|
||||
return fModifiers;
|
||||
}
|
||||
|
||||
void swap(DSLVar& other);
|
||||
virtual VariableStorage storage() const = 0;
|
||||
|
||||
DSLExpression x() {
|
||||
return DSLExpression(*this).x();
|
||||
@ -101,24 +93,6 @@ public:
|
||||
return DSLExpression(*this).field(name);
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator=(DSLVar& var) {
|
||||
return this->operator=(DSLExpression(var));
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator=(DSLExpression expr);
|
||||
|
||||
DSLPossibleExpression operator=(int expr) {
|
||||
return this->operator=(DSLExpression(expr));
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator=(float expr) {
|
||||
return this->operator=(DSLExpression(expr));
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator=(double expr) {
|
||||
return this->operator=(DSLExpression(expr));
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator[](DSLExpression&& index);
|
||||
|
||||
DSLPossibleExpression operator++() {
|
||||
@ -137,18 +111,16 @@ public:
|
||||
return DSLExpression(*this)--;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Constructs a reference to a variable that already exists in the symbol table. This is used
|
||||
* internally to reference built-in vars.
|
||||
*/
|
||||
DSLVar(const char* name);
|
||||
protected:
|
||||
DSLPossibleExpression assign(DSLExpression other);
|
||||
|
||||
void swap(DSLVarBase& other);
|
||||
|
||||
DSLModifiers fModifiers;
|
||||
// We only need to keep track of the type here so that we can create the SkSL::Variable. For
|
||||
// predefined variables this field is unnecessary, so we don't bother tracking it and just set
|
||||
// it to kVoid; in other words, you shouldn't generally be relying on this field to be correct.
|
||||
// If you need to determine the variable's type, look at DSLWriter::Var(...).type() instead.
|
||||
// If you need to determine the variable's type, look at DSLWriter::Var(...)->type() instead.
|
||||
DSLType fType;
|
||||
int fUniformHandle = -1;
|
||||
std::unique_ptr<SkSL::Statement> fDeclaration;
|
||||
@ -156,11 +128,8 @@ private:
|
||||
skstd::string_view fRawName; // for error reporting
|
||||
skstd::string_view fName;
|
||||
DSLExpression fInitialValue;
|
||||
VariableStorage fStorage;
|
||||
bool fDeclared = false;
|
||||
|
||||
friend DSLVar sk_SampleCoord();
|
||||
|
||||
friend class DSLCore;
|
||||
friend class DSLExpression;
|
||||
friend class DSLFunction;
|
||||
@ -169,6 +138,140 @@ private:
|
||||
friend class ::SkSL::SPIRVCodeGenerator;
|
||||
};
|
||||
|
||||
/**
|
||||
* A local variable.
|
||||
*/
|
||||
class DSLVar : public DSLVarBase {
|
||||
public:
|
||||
DSLVar() = default;
|
||||
|
||||
DSLVar(DSLType type, skstd::string_view name = "var",
|
||||
DSLExpression initialValue = DSLExpression())
|
||||
: INHERITED(type, name, std::move(initialValue)) {}
|
||||
|
||||
DSLVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression())
|
||||
: DSLVar(type, skstd::string_view(name), std::move(initialValue)) {}
|
||||
|
||||
DSLVar(DSLType type, DSLExpression initialValue)
|
||||
: INHERITED(type, std::move(initialValue)) {}
|
||||
|
||||
DSLVar(DSLModifiers modifiers, DSLType type, skstd::string_view name = "var",
|
||||
DSLExpression initialValue = DSLExpression())
|
||||
: INHERITED(modifiers, type, name, std::move(initialValue)) {}
|
||||
|
||||
DSLVar(DSLModifiers modifiers, DSLType type, const char* name,
|
||||
DSLExpression initialValue = DSLExpression())
|
||||
: DSLVar(modifiers, type, skstd::string_view(name), std::move(initialValue)) {}
|
||||
|
||||
DSLVar(DSLVar&&) = default;
|
||||
|
||||
VariableStorage storage() const override;
|
||||
|
||||
void swap(DSLVar& other);
|
||||
|
||||
DSLPossibleExpression operator=(DSLExpression expr);
|
||||
|
||||
DSLPossibleExpression operator=(DSLVar& param) {
|
||||
return this->operator=(DSLExpression(param));
|
||||
}
|
||||
|
||||
template<class Param>
|
||||
DSLPossibleExpression operator=(Param& param) {
|
||||
return this->operator=(DSLExpression(param));
|
||||
}
|
||||
|
||||
private:
|
||||
using INHERITED = DSLVarBase;
|
||||
};
|
||||
|
||||
/**
|
||||
* A global variable.
|
||||
*/
|
||||
class DSLGlobalVar : public DSLVarBase {
|
||||
public:
|
||||
DSLGlobalVar() = default;
|
||||
|
||||
DSLGlobalVar(DSLType type, skstd::string_view name = "var",
|
||||
DSLExpression initialValue = DSLExpression())
|
||||
: INHERITED(type, name, std::move(initialValue)) {}
|
||||
|
||||
DSLGlobalVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression())
|
||||
: DSLGlobalVar(type, skstd::string_view(name), std::move(initialValue)) {}
|
||||
|
||||
DSLGlobalVar(DSLType type, DSLExpression initialValue)
|
||||
: INHERITED(type, std::move(initialValue)) {}
|
||||
|
||||
DSLGlobalVar(DSLModifiers modifiers, DSLType type, skstd::string_view name = "var",
|
||||
DSLExpression initialValue = DSLExpression())
|
||||
: INHERITED(modifiers, type, name, std::move(initialValue)) {}
|
||||
|
||||
DSLGlobalVar(DSLModifiers modifiers, DSLType type, const char* name,
|
||||
DSLExpression initialValue = DSLExpression())
|
||||
: DSLGlobalVar(modifiers, type, skstd::string_view(name), std::move(initialValue)) {}
|
||||
|
||||
DSLGlobalVar(const char* name);
|
||||
|
||||
DSLGlobalVar(DSLGlobalVar&&) = default;
|
||||
|
||||
VariableStorage storage() const override;
|
||||
|
||||
void swap(DSLGlobalVar& other);
|
||||
|
||||
DSLPossibleExpression operator=(DSLExpression expr);
|
||||
|
||||
DSLPossibleExpression operator=(DSLGlobalVar& param) {
|
||||
return this->operator=(DSLExpression(param));
|
||||
}
|
||||
|
||||
template<class Param>
|
||||
DSLPossibleExpression operator=(Param& param) {
|
||||
return this->operator=(DSLExpression(param));
|
||||
}
|
||||
|
||||
private:
|
||||
using INHERITED = DSLVarBase;
|
||||
};
|
||||
|
||||
/**
|
||||
* A function parameter.
|
||||
*/
|
||||
class DSLParameter : public DSLVarBase {
|
||||
public:
|
||||
DSLParameter() = default;
|
||||
|
||||
DSLParameter(DSLType type, skstd::string_view name = "var")
|
||||
: INHERITED(type, name, DSLExpression()) {}
|
||||
|
||||
DSLParameter(DSLType type, const char* name)
|
||||
: DSLParameter(type, skstd::string_view(name)) {}
|
||||
|
||||
DSLParameter(DSLModifiers modifiers, DSLType type, skstd::string_view name = "var")
|
||||
: INHERITED(modifiers, type, name, DSLExpression()) {}
|
||||
|
||||
DSLParameter(DSLModifiers modifiers, DSLType type, const char* name)
|
||||
: DSLParameter(modifiers, type, skstd::string_view(name)) {}
|
||||
|
||||
DSLParameter(DSLParameter&&) = default;
|
||||
|
||||
VariableStorage storage() const override;
|
||||
|
||||
void swap(DSLParameter& other);
|
||||
|
||||
DSLPossibleExpression operator=(DSLExpression expr);
|
||||
|
||||
DSLPossibleExpression operator=(DSLParameter& param) {
|
||||
return this->operator=(DSLExpression(param));
|
||||
}
|
||||
|
||||
template<class Param>
|
||||
DSLPossibleExpression operator=(Param& param) {
|
||||
return this->operator=(DSLExpression(param));
|
||||
}
|
||||
|
||||
private:
|
||||
using INHERITED = DSLVarBase;
|
||||
};
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -41,8 +41,8 @@ void GrGLConvexPolyEffect::emitCode(EmitArgs& args) {
|
||||
|
||||
using namespace SkSL::dsl;
|
||||
StartFragmentProcessor(this, &args);
|
||||
Var edgeArray(kUniform_Modifier, Array(kHalf3_Type, cpe.getEdgeCount()), "edgeArray");
|
||||
DeclareGlobal(edgeArray);
|
||||
GlobalVar edgeArray(kUniform_Modifier, Array(kHalf3_Type, cpe.getEdgeCount()), "edgeArray");
|
||||
Declare(edgeArray);
|
||||
fEdgeUniform = VarUniformHandle(edgeArray);
|
||||
Var alpha(kHalf_Type, "alpha", 1);
|
||||
Declare(alpha);
|
||||
|
@ -61,8 +61,8 @@ void GrGaussianConvolutionFragmentProcessor::Impl::emitCode(EmitArgs& args) {
|
||||
|
||||
using namespace SkSL::dsl;
|
||||
StartFragmentProcessor(this, &args);
|
||||
Var increment(kUniform_Modifier, kHalf2_Type, "Increment");
|
||||
DeclareGlobal(increment);
|
||||
GlobalVar increment(kUniform_Modifier, kHalf2_Type, "Increment");
|
||||
Declare(increment);
|
||||
fIncrementUni = VarUniformHandle(increment);
|
||||
|
||||
int width = SkGpuBlurUtils::LinearKernelWidth(ce.fRadius);
|
||||
@ -78,13 +78,13 @@ void GrGaussianConvolutionFragmentProcessor::Impl::emitCode(EmitArgs& args) {
|
||||
SkASSERT(4 * arrayCount >= width);
|
||||
}
|
||||
|
||||
Var kernel(kUniform_Modifier, Array(kHalf4_Type, arrayCount), "Kernel");
|
||||
DeclareGlobal(kernel);
|
||||
GlobalVar kernel(kUniform_Modifier, Array(kHalf4_Type, arrayCount), "Kernel");
|
||||
Declare(kernel);
|
||||
fKernelUni = VarUniformHandle(kernel);
|
||||
|
||||
|
||||
Var offsets(kUniform_Modifier, Array(kHalf4_Type, arrayCount), "Offsets");
|
||||
DeclareGlobal(offsets);
|
||||
GlobalVar offsets(kUniform_Modifier, Array(kHalf4_Type, arrayCount), "Offsets");
|
||||
Declare(offsets);
|
||||
fOffsetsUni = VarUniformHandle(offsets);
|
||||
|
||||
Var color(kHalf4_Type, "color", Half4(0));
|
||||
@ -108,8 +108,8 @@ void GrGaussianConvolutionFragmentProcessor::Impl::emitCode(EmitArgs& args) {
|
||||
break;
|
||||
}
|
||||
case LoopType::kVariableLength: {
|
||||
Var kernelWidth(kUniform_Modifier, kInt_Type, "kernelWidth");
|
||||
DeclareGlobal(kernelWidth);
|
||||
GlobalVar kernelWidth(kUniform_Modifier, kInt_Type, "kernelWidth");
|
||||
Declare(kernelWidth);
|
||||
fKernelWidthUni = VarUniformHandle(kernelWidth);
|
||||
Var i(kInt_Type, "i", 0);
|
||||
For(Declare(i), i < kernelWidth, i++,
|
||||
|
@ -665,7 +665,7 @@ std::unique_ptr<Block> IRGenerator::applyInvocationIDWorkaround(std::unique_ptr<
|
||||
fProgramElements->push_back(std::move(invokeDef));
|
||||
|
||||
using namespace SkSL::dsl;
|
||||
DSLVar loopIdx = DSLVar("sk_InvocationID");
|
||||
DSLGlobalVar loopIdx("sk_InvocationID");
|
||||
std::unique_ptr<Expression> endPrimitive = this->convertIdentifier(/*offset=*/-1,
|
||||
"EndPrimitive");
|
||||
SkASSERT(endPrimitive);
|
||||
|
@ -2049,14 +2049,14 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
// Down below, we rewrite raw references to sk_FragCoord with expressions that reference
|
||||
// DEVICE_FRAGCOORDS_BUILTIN. This is a fake variable that means we need to directly access
|
||||
// the fragcoord; do so now.
|
||||
dsl::DSLVar fragCoord("sk_FragCoord");
|
||||
dsl::DSLGlobalVar fragCoord("sk_FragCoord");
|
||||
return this->getLValue(*dsl::DSLExpression(fragCoord).release(), out)->load(out);
|
||||
}
|
||||
if (ref.variable()->modifiers().fLayout.fBuiltin == DEVICE_CLOCKWISE_BUILTIN) {
|
||||
// Down below, we rewrite raw references to sk_Clockwise with expressions that reference
|
||||
// DEVICE_CLOCKWISE_BUILTIN. This is a fake variable that means we need to directly
|
||||
// access front facing; do so now.
|
||||
dsl::DSLVar clockwise("sk_Clockwise");
|
||||
dsl::DSLGlobalVar clockwise("sk_Clockwise");
|
||||
return this->getLValue(*dsl::DSLExpression(clockwise).release(), out)->load(out);
|
||||
}
|
||||
|
||||
@ -2089,7 +2089,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
fProgram.fPool->detachFromThread();
|
||||
}
|
||||
}
|
||||
DSLVar deviceCoord(DEVICE_COORDS_NAME);
|
||||
DSLGlobalVar deviceCoord(DEVICE_COORDS_NAME);
|
||||
std::unique_ptr<Expression> rtFlipSkSLExpr = rtFlip.release();
|
||||
DSLExpression x = DSLExpression(rtFlipSkSLExpr->clone()).x();
|
||||
DSLExpression y = DSLExpression(std::move(rtFlipSkSLExpr)).y();
|
||||
@ -2127,7 +2127,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
fProgram.fPool->detachFromThread();
|
||||
}
|
||||
}
|
||||
DSLVar deviceClockwise(DEVICE_CLOCKWISE_NAME);
|
||||
DSLGlobalVar deviceClockwise(DEVICE_CLOCKWISE_NAME);
|
||||
// FrontFacing in Vulkan is defined in terms of a top-down render target. In skia,
|
||||
// we use the default convention of "counter-clockwise face is front".
|
||||
return this->writeExpression(*dsl::Bool(Select(rtFlip.y() > 0,
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "include/private/SkSLDefines.h"
|
||||
#include "include/sksl/DSLSymbols.h"
|
||||
#include "include/sksl/DSLVar.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
@ -90,12 +91,12 @@ public:
|
||||
return success ? std::move(result) : nullptr;
|
||||
}
|
||||
|
||||
static DSLVar sk_FragColor() {
|
||||
return DSLVar("sk_FragColor");
|
||||
static DSLGlobalVar sk_FragColor() {
|
||||
return DSLGlobalVar("sk_FragColor");
|
||||
}
|
||||
|
||||
static DSLVar sk_FragCoord() {
|
||||
return DSLVar("sk_FragCoord");
|
||||
static DSLGlobalVar sk_FragCoord() {
|
||||
return DSLGlobalVar("sk_FragCoord");
|
||||
}
|
||||
|
||||
static DSLExpression sk_Position() {
|
||||
@ -128,20 +129,15 @@ public:
|
||||
if (var.fDeclared) {
|
||||
DSLWriter::ReportError("error: variable has already been declared\n", &pos);
|
||||
}
|
||||
if (var.fStorage == SkSL::Variable::Storage::kGlobal) {
|
||||
DSLWriter::ReportError("error: this variable must be declared with DeclareGlobal\n",
|
||||
&pos);
|
||||
}
|
||||
var.fDeclared = true;
|
||||
return DSLWriter::Declaration(var);
|
||||
}
|
||||
|
||||
static void DeclareGlobal(DSLVar& var, PositionInfo pos) {
|
||||
static void Declare(DSLGlobalVar& var, PositionInfo pos) {
|
||||
if (var.fDeclared) {
|
||||
DSLWriter::ReportError("error: variable has already been declared\n", &pos);
|
||||
}
|
||||
var.fDeclared = true;
|
||||
var.fStorage = SkSL::Variable::Storage::kGlobal;
|
||||
std::unique_ptr<SkSL::Statement> stmt = DSLWriter::Declaration(var);
|
||||
if (stmt) {
|
||||
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::GlobalVarDeclaration>(
|
||||
@ -179,7 +175,7 @@ public:
|
||||
ifTrue.release(), ifFalse.releaseIfValid());
|
||||
}
|
||||
|
||||
static DSLVar InterfaceBlock(DSLModifiers modifiers, skstd::string_view typeName,
|
||||
static DSLGlobalVar InterfaceBlock(DSLModifiers modifiers, skstd::string_view typeName,
|
||||
SkTArray<DSLField> fields, skstd::string_view varName,
|
||||
int arraySize, PositionInfo pos) {
|
||||
// We need to create a new struct type for the interface block, but we don't want it in the
|
||||
@ -194,7 +190,7 @@ public:
|
||||
const SkSL::Type* structType = DSLWriter::SymbolTable()->takeOwnershipOfSymbol(
|
||||
SkSL::Type::MakeStructType(/*offset=*/-1, String(typeName), std::move(skslFields)));
|
||||
DSLType varType = arraySize > 0 ? Array(structType, arraySize) : DSLType(structType);
|
||||
DSLVar var(modifiers, varType, !varName.empty() ? varName : typeName);
|
||||
DSLGlobalVar var(modifiers, varType, !varName.empty() ? varName : typeName);
|
||||
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::InterfaceBlock>(/*offset=*/-1,
|
||||
DSLWriter::Var(var), String(typeName), String(varName), arraySize,
|
||||
DSLWriter::SymbolTable()));
|
||||
@ -276,11 +272,11 @@ std::unique_ptr<SkSL::Program> ReleaseProgram() {
|
||||
return DSLCore::ReleaseProgram();
|
||||
}
|
||||
|
||||
DSLVar sk_FragColor() {
|
||||
DSLGlobalVar sk_FragColor() {
|
||||
return DSLCore::sk_FragColor();
|
||||
}
|
||||
|
||||
DSLVar sk_FragCoord() {
|
||||
DSLGlobalVar sk_FragCoord() {
|
||||
return DSLCore::sk_FragCoord();
|
||||
}
|
||||
|
||||
@ -312,8 +308,8 @@ DSLStatement Declare(DSLVar& var, PositionInfo pos) {
|
||||
return DSLCore::Declare(var, pos);
|
||||
}
|
||||
|
||||
void DeclareGlobal(DSLVar& var, PositionInfo pos) {
|
||||
return DSLCore::DeclareGlobal(var, pos);
|
||||
void Declare(DSLGlobalVar& var, PositionInfo pos) {
|
||||
return DSLCore::Declare(var, pos);
|
||||
}
|
||||
|
||||
DSLStatement Discard() {
|
||||
@ -336,9 +332,9 @@ DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse, P
|
||||
pos);
|
||||
}
|
||||
|
||||
DSLVar InterfaceBlock(DSLModifiers modifiers, skstd::string_view typeName,
|
||||
SkTArray<DSLField> fields, skstd::string_view varName, int arraySize,
|
||||
PositionInfo pos) {
|
||||
DSLGlobalVar InterfaceBlock(DSLModifiers modifiers, skstd::string_view typeName,
|
||||
SkTArray<DSLField> fields, skstd::string_view varName, int arraySize,
|
||||
PositionInfo pos) {
|
||||
return DSLCore::InterfaceBlock(modifiers, typeName, std::move(fields), varName, arraySize, pos);
|
||||
}
|
||||
|
||||
|
@ -67,17 +67,13 @@ DSLExpression::DSLExpression(bool value)
|
||||
/*offset=*/-1,
|
||||
value)) {}
|
||||
|
||||
DSLExpression::DSLExpression(DSLVar& var)
|
||||
: fExpression(std::make_unique<SkSL::VariableReference>(
|
||||
/*offset=*/-1,
|
||||
DSLWriter::Var(var),
|
||||
SkSL::VariableReference::RefKind::kRead)) {}
|
||||
DSLExpression::DSLExpression(DSLVarBase& var) {
|
||||
fExpression = std::make_unique<SkSL::VariableReference>(/*offset=*/-1, DSLWriter::Var(var),
|
||||
SkSL::VariableReference::RefKind::kRead);
|
||||
}
|
||||
|
||||
DSLExpression::DSLExpression(DSLVar&& var)
|
||||
: fExpression(std::make_unique<SkSL::VariableReference>(
|
||||
/*offset=*/-1,
|
||||
DSLWriter::Var(var),
|
||||
SkSL::VariableReference::RefKind::kRead)) {}
|
||||
DSLExpression::DSLExpression(DSLVarBase&& var)
|
||||
: DSLExpression(var) {}
|
||||
|
||||
DSLExpression::DSLExpression(DSLPossibleExpression expr, PositionInfo pos) {
|
||||
DSLWriter::ReportErrors(pos);
|
||||
|
@ -19,7 +19,7 @@ namespace SkSL {
|
||||
namespace dsl {
|
||||
|
||||
void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
|
||||
SkTArray<DSLVar*> params) {
|
||||
SkTArray<DSLParameter*> params) {
|
||||
// Conservatively assume all user-defined functions have side effects.
|
||||
if (!DSLWriter::IsModule()) {
|
||||
modifiers.fModifiers.fFlags |= Modifiers::kHasSideEffects_Flag;
|
||||
@ -39,23 +39,13 @@ void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd:
|
||||
return type == *DSLWriter::Context().fTypes.fHalf4 ||
|
||||
type == *DSLWriter::Context().fTypes.fFloat4;
|
||||
};
|
||||
for (DSLVar* param : params) {
|
||||
// This counts as declaring the variable; make sure it hasn't been previously declared and
|
||||
// then kill its pending declaration statement. Otherwise the statement will hang around
|
||||
// until after the Var is destroyed, which is probably after the End() call and therefore
|
||||
// after the Pool's destruction. Freeing a pooled object after the Pool's destruction is a
|
||||
// Bad Thing.
|
||||
for (DSLParameter* param : params) {
|
||||
if (param->fDeclared) {
|
||||
DSLWriter::ReportError("error: using an already-declared variable as a function "
|
||||
"parameter\n");
|
||||
}
|
||||
if (param->fInitialValue.valid()) {
|
||||
DSLWriter::ReportError("error: variables used as function parameters cannot have "
|
||||
"initial values\n");
|
||||
param->fInitialValue.release();
|
||||
DSLWriter::ReportError("error: parameter has already been used in another function\n");
|
||||
}
|
||||
SkASSERT(!param->fInitialValue.valid());
|
||||
SkASSERT(!param->fDeclaration);
|
||||
param->fDeclared = true;
|
||||
param->fStorage = SkSL::VariableStorage::kParameter;
|
||||
SkSL::ProgramKind kind = DSLWriter::Context().fConfig->fKind;
|
||||
if (isMain && (kind == ProgramKind::kRuntimeColorFilter ||
|
||||
kind == ProgramKind::kRuntimeShader ||
|
||||
@ -70,12 +60,11 @@ void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd:
|
||||
param->fModifiers.fModifiers.fLayout.fBuiltin = SK_INPUT_COLOR_BUILTIN;
|
||||
}
|
||||
}
|
||||
std::unique_ptr<SkSL::Variable> paramVar = DSLWriter::ParameterVar(*param);
|
||||
std::unique_ptr<SkSL::Variable> paramVar = DSLWriter::CreateParameterVar(*param);
|
||||
if (!paramVar) {
|
||||
return;
|
||||
}
|
||||
paramVars.push_back(std::move(paramVar));
|
||||
param->fDeclaration = nullptr;
|
||||
}
|
||||
SkASSERT(paramVars.size() == params.size());
|
||||
fDecl = SkSL::FunctionDeclaration::Convert(DSLWriter::Context(),
|
||||
|
@ -35,7 +35,7 @@ bool IsType(skstd::string_view name) {
|
||||
return s && s->is<Type>();
|
||||
}
|
||||
|
||||
void AddToSymbolTable(DSLVar& var) {
|
||||
void AddToSymbolTable(DSLVarBase& var) {
|
||||
CurrentSymbolTable()->addWithoutOwnership(DSLWriter::Var(var));
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,89 @@ namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
|
||||
DSLVar::DSLVar(const char* name)
|
||||
: fType(kVoid_Type)
|
||||
DSLVarBase::DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue)
|
||||
: DSLVarBase(DSLModifiers(), std::move(type), name, std::move(initialValue)) {}
|
||||
|
||||
DSLVarBase::DSLVarBase(DSLType type, DSLExpression initialValue)
|
||||
: DSLVarBase(type, "var", std::move(initialValue)) {}
|
||||
|
||||
DSLVarBase::DSLVarBase(DSLModifiers modifiers, DSLType type, DSLExpression initialValue)
|
||||
: DSLVarBase(modifiers, type, "var", std::move(initialValue)) {}
|
||||
|
||||
DSLVarBase::DSLVarBase(DSLModifiers modifiers, DSLType type, skstd::string_view name,
|
||||
DSLExpression initialValue)
|
||||
: fModifiers(std::move(modifiers))
|
||||
, fType(std::move(type))
|
||||
, fRawName(name)
|
||||
, fName(name)
|
||||
, fDeclared(true) {
|
||||
, fName(fType.skslType().isOpaque() ? name : DSLWriter::Name(name))
|
||||
, fInitialValue(std::move(initialValue))
|
||||
, fDeclared(DSLWriter::MarkVarsDeclared()) {
|
||||
if (fModifiers.fModifiers.fFlags & Modifiers::kUniform_Flag) {
|
||||
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
if (DSLWriter::InFragmentProcessor()) {
|
||||
const SkSL::Type& skslType = type.skslType();
|
||||
GrSLType grslType;
|
||||
int count;
|
||||
if (skslType.isArray()) {
|
||||
SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(),
|
||||
skslType.componentType(),
|
||||
&grslType));
|
||||
count = skslType.columns();
|
||||
SkASSERT(count > 0);
|
||||
} else {
|
||||
SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(), skslType,
|
||||
&grslType));
|
||||
count = 0;
|
||||
}
|
||||
const char* name;
|
||||
SkASSERT(DSLWriter::CurrentEmitArgs());
|
||||
fUniformHandle = DSLWriter::CurrentEmitArgs()->fUniformHandler->addUniformArray(
|
||||
&DSLWriter::CurrentEmitArgs()->fFp,
|
||||
kFragment_GrShaderFlag,
|
||||
grslType,
|
||||
String(this->name()).c_str(),
|
||||
count,
|
||||
&name).toIndex();
|
||||
fName = name;
|
||||
}
|
||||
#endif // SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
}
|
||||
}
|
||||
|
||||
DSLVarBase::~DSLVarBase() {
|
||||
if (fDeclaration && !fDeclared) {
|
||||
DSLWriter::ReportError(String::printf("error: variable '%.*s' was destroyed without being "
|
||||
"declared\n",
|
||||
(int)fRawName.length(),
|
||||
fRawName.data()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void DSLVarBase::swap(DSLVarBase& other) {
|
||||
SkASSERT(this->storage() == other.storage());
|
||||
std::swap(fModifiers, other.fModifiers);
|
||||
std::swap(fType, other.fType);
|
||||
std::swap(fUniformHandle, other.fUniformHandle);
|
||||
std::swap(fDeclaration, other.fDeclaration);
|
||||
std::swap(fVar, other.fVar);
|
||||
std::swap(fRawName, other.fRawName);
|
||||
std::swap(fName, other.fName);
|
||||
std::swap(fInitialValue.fExpression, other.fInitialValue.fExpression);
|
||||
std::swap(fDeclared, other.fDeclared);
|
||||
}
|
||||
|
||||
void DSLVar::swap(DSLVar& other) {
|
||||
INHERITED::swap(other);
|
||||
}
|
||||
|
||||
VariableStorage DSLVar::storage() const {
|
||||
return VariableStorage::kLocal;
|
||||
}
|
||||
|
||||
DSLGlobalVar::DSLGlobalVar(const char* name)
|
||||
: INHERITED(kVoid_Type, name, DSLExpression()) {
|
||||
fName = name;
|
||||
DSLWriter::MarkDeclared(*this);
|
||||
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
if (!strcmp(name, "sk_SampleCoord")) {
|
||||
fName = DSLWriter::CurrentEmitArgs()->fSampleCoord;
|
||||
@ -57,88 +135,44 @@ DSLVar::DSLVar(const char* name)
|
||||
fVar = &result->as<SkSL::Variable>();
|
||||
}
|
||||
|
||||
DSLVar::DSLVar(DSLType type, skstd::string_view name, DSLExpression initialValue)
|
||||
: DSLVar(DSLModifiers(), std::move(type), name, std::move(initialValue)) {}
|
||||
|
||||
DSLVar::DSLVar(DSLType type, DSLExpression initialValue)
|
||||
: DSLVar(type, "var", std::move(initialValue)) {}
|
||||
|
||||
DSLVar::DSLVar(DSLModifiers modifiers, DSLType type, DSLExpression initialValue)
|
||||
: DSLVar(modifiers, type, "var", std::move(initialValue)) {}
|
||||
|
||||
DSLVar::DSLVar(DSLModifiers modifiers, DSLType type, skstd::string_view name,
|
||||
DSLExpression initialValue)
|
||||
: fModifiers(std::move(modifiers))
|
||||
, fType(std::move(type))
|
||||
, fRawName(name)
|
||||
, fName(fType.skslType().isOpaque() ? name : DSLWriter::Name(name))
|
||||
, fInitialValue(std::move(initialValue))
|
||||
, fStorage(Variable::Storage::kLocal)
|
||||
, fDeclared(DSLWriter::MarkVarsDeclared()) {
|
||||
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
if (fModifiers.fModifiers.fFlags & Modifiers::kUniform_Flag) {
|
||||
fStorage = Variable::Storage::kGlobal;
|
||||
if (DSLWriter::InFragmentProcessor()) {
|
||||
const SkSL::Type& skslType = type.skslType();
|
||||
GrSLType grslType;
|
||||
int count;
|
||||
if (skslType.isArray()) {
|
||||
SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(),
|
||||
skslType.componentType(),
|
||||
&grslType));
|
||||
count = skslType.columns();
|
||||
SkASSERT(count > 0);
|
||||
} else {
|
||||
SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(), skslType,
|
||||
&grslType));
|
||||
count = 0;
|
||||
}
|
||||
const char* name;
|
||||
SkASSERT(DSLWriter::CurrentEmitArgs());
|
||||
fUniformHandle = DSLWriter::CurrentEmitArgs()->fUniformHandler->addUniformArray(
|
||||
&DSLWriter::CurrentEmitArgs()->fFp,
|
||||
kFragment_GrShaderFlag,
|
||||
grslType,
|
||||
String(this->name()).c_str(),
|
||||
count,
|
||||
&name).toIndex();
|
||||
fName = name;
|
||||
}
|
||||
}
|
||||
#endif // SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
void DSLGlobalVar::swap(DSLGlobalVar& other) {
|
||||
INHERITED::swap(other);
|
||||
}
|
||||
|
||||
DSLVar::~DSLVar() {
|
||||
if (!fDeclared) {
|
||||
DSLWriter::ReportError(String::printf("error: variable '%.*s' was destroyed without being "
|
||||
"declared\n",
|
||||
(int)fRawName.length(),
|
||||
fRawName.data()).c_str());
|
||||
}
|
||||
VariableStorage DSLGlobalVar::storage() const {
|
||||
return VariableStorage::kGlobal;
|
||||
}
|
||||
|
||||
void DSLVar::swap(DSLVar& other) {
|
||||
std::swap(fModifiers, other.fModifiers);
|
||||
std::swap(fType, other.fType);
|
||||
std::swap(fUniformHandle, other.fUniformHandle);
|
||||
std::swap(fDeclaration, other.fDeclaration);
|
||||
std::swap(fVar, other.fVar);
|
||||
std::swap(fRawName, other.fRawName);
|
||||
std::swap(fName, other.fName);
|
||||
std::swap(fInitialValue.fExpression, other.fInitialValue.fExpression);
|
||||
std::swap(fStorage, other.fStorage);
|
||||
std::swap(fDeclared, other.fDeclared);
|
||||
void DSLParameter::swap(DSLParameter& other) {
|
||||
INHERITED::swap(other);
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLVar::operator[](DSLExpression&& index) {
|
||||
VariableStorage DSLParameter::storage() const {
|
||||
return VariableStorage::kParameter;
|
||||
}
|
||||
|
||||
|
||||
DSLPossibleExpression DSLVarBase::operator[](DSLExpression&& index) {
|
||||
return DSLExpression(*this)[std::move(index)];
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLVar::operator=(DSLExpression expr) {
|
||||
DSLPossibleExpression DSLVarBase::assign(DSLExpression expr) {
|
||||
return DSLWriter::ConvertBinary(DSLExpression(*this).release(), SkSL::Token::Kind::TK_EQ,
|
||||
expr.release());
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLVar::operator=(DSLExpression expr) {
|
||||
return this->assign(std::move(expr));
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLGlobalVar::operator=(DSLExpression expr) {
|
||||
return this->assign(std::move(expr));
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLParameter::operator=(DSLExpression expr) {
|
||||
return this->assign(std::move(expr));
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -25,8 +25,8 @@ void EndFragmentProcessor() {
|
||||
DSLWriter::EndFragmentProcessor();
|
||||
}
|
||||
|
||||
DSLVar sk_SampleCoord() {
|
||||
return DSLVar("sk_SampleCoord");
|
||||
DSLGlobalVar sk_SampleCoord() {
|
||||
return DSLGlobalVar("sk_SampleCoord");
|
||||
}
|
||||
|
||||
DSLExpression SampleChild(int index, DSLExpression sampleExpr) {
|
||||
@ -58,7 +58,7 @@ DSLExpression SampleChild(int index, DSLExpression sampleExpr) {
|
||||
code.c_str(), DSLWriter::Context().fTypes.fHalf4.get()));
|
||||
}
|
||||
|
||||
GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLVar& var) {
|
||||
GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var) {
|
||||
return DSLWriter::VarUniformHandle(var);
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,11 @@ void StartFragmentProcessor(GrGLSLFragmentProcessor* processor,
|
||||
|
||||
void EndFragmentProcessor();
|
||||
|
||||
DSLVar sk_SampleCoord();
|
||||
DSLGlobalVar sk_SampleCoord();
|
||||
|
||||
DSLExpression SampleChild(int index, DSLExpression coords = DSLExpression());
|
||||
|
||||
GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLVar& var);
|
||||
GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var);
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
|
@ -123,7 +123,7 @@ void DSLWriter::EndFragmentProcessor() {
|
||||
IRGenerator().popSymbolTable();
|
||||
}
|
||||
|
||||
GrGLSLUniformHandler::UniformHandle DSLWriter::VarUniformHandle(const DSLVar& var) {
|
||||
GrGLSLUniformHandler::UniformHandle DSLWriter::VarUniformHandle(const DSLGlobalVar& var) {
|
||||
return GrGLSLUniformHandler::UniformHandle(var.fUniformHandle);
|
||||
}
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
@ -219,11 +219,11 @@ void DSLWriter::ReportError(const char* msg, PositionInfo* info) {
|
||||
}
|
||||
}
|
||||
|
||||
const SkSL::Variable* DSLWriter::Var(DSLVar& var) {
|
||||
const SkSL::Variable* DSLWriter::Var(DSLVarBase& var) {
|
||||
if (!var.fVar) {
|
||||
if (var.fStorage != SkSL::VariableStorage::kParameter) {
|
||||
if (var.storage() != SkSL::VariableStorage::kParameter) {
|
||||
DSLWriter::IRGenerator().checkVarDeclaration(/*offset=*/-1, var.fModifiers.fModifiers,
|
||||
&var.fType.skslType(), var.fStorage);
|
||||
&var.fType.skslType(), var.storage());
|
||||
}
|
||||
std::unique_ptr<SkSL::Variable> skslvar = DSLWriter::IRGenerator().convertVar(
|
||||
/*offset=*/-1,
|
||||
@ -232,7 +232,7 @@ const SkSL::Variable* DSLWriter::Var(DSLVar& var) {
|
||||
var.fName,
|
||||
/*isArray=*/false,
|
||||
/*arraySize=*/nullptr,
|
||||
var.fStorage);
|
||||
var.storage());
|
||||
SkSL::Variable* varPtr = skslvar.get();
|
||||
// We can't call VarDeclaration::Convert directly here, because the IRGenerator has special
|
||||
// treatment for sk_FragColor that we want to preserve in DSL.
|
||||
@ -247,16 +247,16 @@ const SkSL::Variable* DSLWriter::Var(DSLVar& var) {
|
||||
return var.fVar;
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Variable> DSLWriter::ParameterVar(DSLVar& var) {
|
||||
std::unique_ptr<SkSL::Variable> DSLWriter::CreateParameterVar(DSLParameter& var) {
|
||||
// This should only be called on undeclared parameter variables, but we allow the creation to go
|
||||
// ahead regardless so we don't have to worry about null pointers potentially sneaking in and
|
||||
// breaking things. DSLFunction is responsible for reporting errors for invalid parameters.
|
||||
return DSLWriter::IRGenerator().convertVar(/*offset=*/-1, var.fModifiers.fModifiers,
|
||||
&var.fType.skslType(), var.fName, /*isArray=*/false,
|
||||
/*arraySize=*/nullptr, var.fStorage);
|
||||
/*arraySize=*/nullptr, var.storage());
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Statement> DSLWriter::Declaration(DSLVar& var) {
|
||||
std::unique_ptr<SkSL::Statement> DSLWriter::Declaration(DSLVarBase& var) {
|
||||
Var(var);
|
||||
if (!var.fDeclaration) {
|
||||
// We should have already reported an error before ending up here, just clean up the
|
||||
@ -267,7 +267,7 @@ std::unique_ptr<SkSL::Statement> DSLWriter::Declaration(DSLVar& var) {
|
||||
return std::move(var.fDeclaration);
|
||||
}
|
||||
|
||||
void DSLWriter::MarkDeclared(DSLVar& var) {
|
||||
void DSLWriter::MarkDeclared(DSLVarBase& var) {
|
||||
SkASSERT(!var.fDeclared);
|
||||
var.fDeclared = true;
|
||||
}
|
||||
|
@ -37,6 +37,9 @@ class Variable;
|
||||
|
||||
namespace dsl {
|
||||
|
||||
class DSLGlobalVar;
|
||||
class DSLParameter;
|
||||
class DSLVar;
|
||||
class ErrorHandler;
|
||||
|
||||
/**
|
||||
@ -109,25 +112,26 @@ public:
|
||||
static const SkSL::Modifiers* Modifiers(const SkSL::Modifiers& modifiers);
|
||||
|
||||
/**
|
||||
* Returns the SkSL variable corresponding to a (non-parameter) DSLVar.
|
||||
* Returns the SkSL variable corresponding to a DSL var.
|
||||
*/
|
||||
static const SkSL::Variable* Var(DSLVar& var);
|
||||
static const SkSL::Variable* Var(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* Creates an SkSL variable corresponding to a parameter DSLVar.
|
||||
* Creates an SkSL variable corresponding to a DSLParameter.
|
||||
*/
|
||||
static std::unique_ptr<SkSL::Variable> ParameterVar(DSLVar& var);
|
||||
static std::unique_ptr<SkSL::Variable> CreateParameterVar(DSLParameter& var);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the SkSL declaration corresponding to a DSLVar.
|
||||
*/
|
||||
static std::unique_ptr<SkSL::Statement> Declaration(DSLVar& var);
|
||||
static std::unique_ptr<SkSL::Statement> Declaration(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* For use in testing only: marks the variable as having been declared, so that it can be
|
||||
* destroyed without generating errors.
|
||||
*/
|
||||
static void MarkDeclared(DSLVar& var);
|
||||
static void MarkDeclared(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* Returns the (possibly mangled) final name that should be used for an entity with the given
|
||||
@ -168,7 +172,7 @@ public:
|
||||
*/
|
||||
static void EndFragmentProcessor();
|
||||
|
||||
static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLVar& var);
|
||||
static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var);
|
||||
#else
|
||||
static bool InFragmentProcessor() {
|
||||
return false;
|
||||
|
@ -118,7 +118,7 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// Local coords
|
||||
{
|
||||
effect.start();
|
||||
Var p(kFloat2_Type, "p");
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kHalf4_Type, "main", p).define(
|
||||
Return(Half4(Half2(p - 0.5), 0, 1))
|
||||
);
|
||||
@ -129,9 +129,9 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// Use of a simple uniform. (Draw twice with two values to ensure it's updated).
|
||||
{
|
||||
effect.start();
|
||||
Var gColor(kUniform_Modifier, kFloat4_Type);
|
||||
DeclareGlobal(gColor);
|
||||
Var p(kFloat2_Type, "p");
|
||||
GlobalVar gColor(kUniform_Modifier, kFloat4_Type);
|
||||
Declare(gColor);
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kHalf4_Type, "main", p).define(
|
||||
Return(Half4(gColor))
|
||||
);
|
||||
@ -145,9 +145,9 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// Same, with integer uniforms
|
||||
{
|
||||
effect.start();
|
||||
Var gColor(kUniform_Modifier, kInt4_Type);
|
||||
DeclareGlobal(gColor);
|
||||
Var p(kFloat2_Type, "p");
|
||||
GlobalVar gColor(kUniform_Modifier, kInt4_Type);
|
||||
Declare(gColor);
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kHalf4_Type, "main", p).define(
|
||||
Return(Half4(gColor) / 255)
|
||||
);
|
||||
@ -163,7 +163,7 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// make sure we're not saturating unexpectedly.
|
||||
{
|
||||
effect.start();
|
||||
Var p(kFloat2_Type, "p");
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kHalf4_Type, "main", p).define(
|
||||
Return(Half4(0.498 * (Half2(Swizzle(sk_FragCoord(), X, Y)) - 0.5), 0, 1))
|
||||
);
|
||||
@ -175,7 +175,7 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// Runtime effects should use relaxed precision rules by default
|
||||
{
|
||||
effect.start();
|
||||
Var p(kFloat2_Type, "p");
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kHalf4_Type, "main", p).define(
|
||||
Return(Float4(p - 0.5, 0, 1))
|
||||
);
|
||||
@ -186,7 +186,7 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// ... and support *returning* float4, not just half4
|
||||
{
|
||||
effect.start();
|
||||
Var p(kFloat2_Type, "p");
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kFloat4_Type, "main", p).define(
|
||||
Return(Float4(p - 0.5, 0, 1))
|
||||
);
|
||||
@ -207,7 +207,7 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
} errorHandler;
|
||||
effect.start();
|
||||
SetErrorHandler(&errorHandler);
|
||||
Var p(kFloat2_Type, "p");
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kHalf4_Type, "main", p).define(
|
||||
Return(1) // Error, type mismatch
|
||||
);
|
||||
@ -218,7 +218,7 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// Mutating coords should work. (skbug.com/10918)
|
||||
{
|
||||
effect.start();
|
||||
Var p(kFloat2_Type, "p");
|
||||
Parameter p(kFloat2_Type, "p");
|
||||
Function(kFloat4_Type, "main", p).define(
|
||||
p -= 0.5,
|
||||
Return(Float4(p, 0, 1))
|
||||
@ -228,12 +228,12 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
}
|
||||
{
|
||||
effect.start();
|
||||
Var p1(kInOut_Modifier, kFloat2_Type, "p");
|
||||
Parameter p1(kInOut_Modifier, kFloat2_Type, "p");
|
||||
Function moveCoords(kVoid_Type, "moveCoords", p1);
|
||||
moveCoords.define(
|
||||
p1 -= 0.5
|
||||
);
|
||||
Var p2(kFloat2_Type, "p");
|
||||
Parameter p2(kFloat2_Type, "p");
|
||||
Function(kFloat4_Type, "main", p2).define(
|
||||
moveCoords(p2),
|
||||
Return(Float4(p2, 0, 1))
|
||||
@ -249,9 +249,9 @@ static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext
|
||||
// Sampling a null child should return the paint color
|
||||
{
|
||||
effect.start();
|
||||
Var child(kUniform_Modifier, kShader_Type, "child");
|
||||
DeclareGlobal(child);
|
||||
Var p2(kFloat2_Type, "p");
|
||||
GlobalVar child(kUniform_Modifier, kShader_Type, "child");
|
||||
Declare(child);
|
||||
Parameter p2(kFloat2_Type, "p");
|
||||
Function(kFloat4_Type, "main", p2).define(
|
||||
Return(Sample(child, p2))
|
||||
);
|
||||
|
@ -19,7 +19,7 @@ void StartDSL(const sk_gpu_test::ContextInfo ctxInfo);
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLImportOnly, r, ctxInfo) {
|
||||
StartDSL(ctxInfo);
|
||||
Var x(kInt_Type);
|
||||
Parameter x(kInt_Type);
|
||||
Function(kInt_Type, "test", x).define(
|
||||
If(x >= 0,
|
||||
Block(Return(x)),
|
||||
|
@ -1318,17 +1318,17 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare, r, ctxInfo) {
|
||||
|
||||
{
|
||||
Var e(kUniform_Modifier, kInt_Type, "e");
|
||||
ExpectError error(r, "error: this variable must be declared with DeclareGlobal\n");
|
||||
ExpectError error(r, "error: 'uniform' is not permitted here\n");
|
||||
Declare(e).release();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclareGlobal, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared());
|
||||
Var x(kInt_Type, "x", 0);
|
||||
DeclareGlobal(x);
|
||||
Var y(kUniform_Modifier, kFloat2_Type, "y");
|
||||
DeclareGlobal(y);
|
||||
DSLGlobalVar x(kInt_Type, "x", 0);
|
||||
Declare(x);
|
||||
DSLGlobalVar y(kUniform_Modifier, kFloat2_Type, "y");
|
||||
Declare(y);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "int x = 0;");
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1], "uniform float2 y;");
|
||||
@ -1387,7 +1387,7 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFor, r, ctxInfo) {
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared());
|
||||
Var coords(kFloat2_Type, "coords");
|
||||
Parameter coords(kFloat2_Type, "coords");
|
||||
DSLFunction(kVoid_Type, "main", coords).define(
|
||||
sk_FragColor() = Half4(coords, 0, 1)
|
||||
);
|
||||
@ -1397,7 +1397,7 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
|
||||
{
|
||||
DSLWriter::Reset();
|
||||
Var x(kFloat_Type, "x");
|
||||
DSLParameter x(kFloat_Type, "x");
|
||||
DSLFunction sqr(kFloat_Type, "sqr", x);
|
||||
sqr.define(
|
||||
Return(x * x)
|
||||
@ -1409,8 +1409,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
|
||||
{
|
||||
DSLWriter::Reset();
|
||||
Var x(kFloat2_Type, "x");
|
||||
Var y(kFloat2_Type, "y");
|
||||
DSLParameter x(kFloat2_Type, "x");
|
||||
DSLParameter y(kFloat2_Type, "y");
|
||||
DSLFunction dot(kFloat2_Type, "dot", x, y);
|
||||
dot.define(
|
||||
Return(x * x + y * y)
|
||||
@ -1424,8 +1424,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
|
||||
{
|
||||
DSLWriter::Reset();
|
||||
Var x(kFloat_Type, "x");
|
||||
Var y(kFloat_Type, "y");
|
||||
DSLParameter x(kFloat_Type, "x");
|
||||
DSLParameter y(kFloat_Type, "y");
|
||||
DSLFunction pair(kFloat2_Type, "pair", x, y);
|
||||
pair.define(
|
||||
Return(Float2(x, y))
|
||||
@ -1479,28 +1479,11 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
}
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: using an already-declared variable as a function parameter\n");
|
||||
ExpectError error(r, "error: parameter has already been used in another function\n");
|
||||
DSLWriter::Reset();
|
||||
DSLVar p(kFloat_Type);
|
||||
Declare(p).release();
|
||||
DSLFunction(kVoid_Type, "broken", p).define(
|
||||
DSLParameter p(kFloat_Type);
|
||||
DSLFunction(kVoid_Type, "ok", p).define(
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: variable has already been declared\n");
|
||||
DSLWriter::Reset();
|
||||
DSLVar p(kFloat_Type);
|
||||
DSLFunction(kVoid_Type, "broken", p).define(
|
||||
);
|
||||
Declare(p).release();
|
||||
}
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: variables used as function parameters cannot have initial "
|
||||
"values\n");
|
||||
DSLWriter::Reset();
|
||||
DSLVar p(kFloat_Type, 1);
|
||||
DSLFunction(kVoid_Type, "broken", p).define(
|
||||
);
|
||||
}
|
||||
@ -1526,23 +1509,23 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIf, r, ctxInfo) {
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInterfaceBlock, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
DSLVar intf = InterfaceBlock(kUniform_Modifier, "InterfaceBlock1",
|
||||
{ Field(kFloat_Type, "a"), Field(kInt_Type, "b") });
|
||||
DSLGlobalVar intf = InterfaceBlock(kUniform_Modifier, "InterfaceBlock1",
|
||||
{ Field(kFloat_Type, "a"), Field(kInt_Type, "b") });
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements().back(),
|
||||
"uniform InterfaceBlock1 { float a; int b; };");
|
||||
EXPECT_EQUAL(intf.field("a"), "InterfaceBlock1.a");
|
||||
|
||||
DSLVar intf2 = InterfaceBlock(kUniform_Modifier, "InterfaceBlock2",
|
||||
{ Field(kFloat2_Type, "x"), Field(kHalf2x2_Type, "y") },
|
||||
DSLGlobalVar intf2 = InterfaceBlock(kUniform_Modifier, "InterfaceBlock2",
|
||||
{ Field(kFloat2_Type, "x"), Field(kHalf2x2_Type, "y") },
|
||||
"blockVar");
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements().back(),
|
||||
"uniform InterfaceBlock2 { float2 x; half2x2 y; } blockVar;");
|
||||
EXPECT_EQUAL(intf2.field("x"), "blockVar.x");
|
||||
|
||||
DSLVar intf3 = InterfaceBlock(kUniform_Modifier, "InterfaceBlock3", { Field(kFloat_Type, "z") },
|
||||
"arrayVar", 4);
|
||||
DSLGlobalVar intf3 = InterfaceBlock(kUniform_Modifier, "InterfaceBlock3",
|
||||
{ Field(kFloat_Type, "z") },"arrayVar", 4);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 3);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements().back(),
|
||||
"uniform InterfaceBlock3 { float z; } arrayVar[4];");
|
||||
@ -1843,8 +1826,9 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLayout, r, ctxInfo) {
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: 'srgb_unpremul' is only permitted in runtime effects\n");
|
||||
Var v(DSLModifiers(DSLLayout().srgbUnpremul(), kUniform_Modifier), kHalf4_Type, "v");
|
||||
DeclareGlobal(v);
|
||||
DSLGlobalVar v(DSLModifiers(DSLLayout().srgbUnpremul(), kUniform_Modifier), kHalf4_Type,
|
||||
"v");
|
||||
Declare(v);
|
||||
}
|
||||
|
||||
{
|
||||
@ -1909,7 +1893,7 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLayout, r, ctxInfo) {
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSampleShader, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), default_settings(),
|
||||
SkSL::ProgramKind::kRuntimeShader);
|
||||
DSLVar shader(kUniform_Modifier, kShader_Type, "shader");
|
||||
DSLGlobalVar shader(kUniform_Modifier, kShader_Type, "shader");
|
||||
EXPECT_EQUAL(Sample(shader, Float2(0, 0)), "sample(shader, float2(0.0, 0.0))");
|
||||
|
||||
{
|
||||
@ -1966,8 +1950,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWrapper, r, ctxInfo) {
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLRTAdjust, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared(),
|
||||
SkSL::ProgramKind::kVertex);
|
||||
DSLVar rtAdjust(kUniform_Modifier, kFloat4_Type, "sk_RTAdjust");
|
||||
DeclareGlobal(rtAdjust);
|
||||
DSLGlobalVar rtAdjust(kUniform_Modifier, kFloat4_Type, "sk_RTAdjust");
|
||||
Declare(rtAdjust);
|
||||
DSLFunction(kVoid_Type, "main").define(
|
||||
sk_Position() = Half4(0)
|
||||
);
|
||||
@ -1982,7 +1966,7 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLRTAdjust, r, ctxInfo) {
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInlining, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared());
|
||||
DSLVar x(kFloat_Type, "x");
|
||||
DSLParameter x(kFloat_Type, "x");
|
||||
DSLFunction sqr(kFloat_Type, "sqr", x);
|
||||
sqr.define(
|
||||
Return(x * x)
|
||||
|
Loading…
Reference in New Issue
Block a user