Improve Metal support for out parameters.
We now insert helper functions which defer the assignment of out-
parameters back into their original variables to the end of the
function call. This allows us to match the semantics listed the GLSL
spec in section 6.1.1:
"All arguments are evaluated at call time, exactly once, in order, from
left to right. [...] Evaluation of an out parameter results in an
l-value that is used to copy out a value when the function returns.
Evaluation of an inout parameter results in both a value and an l-value;
the value is copied to the formal parameter at call time and the lvalue
is used to copy out a value when the function returns."
This technique also allows us to support swizzled out-parameters in
Metal, by reading the swizzle into a temp variable, calling the original
function, and then re-assigning the result back into the original
swizzle expression.
At present, we don't deduplicate these helper functions, so in theory
there could be a fair amount of redundant code generated if a function
with out parameters is called many times in a row. The cost of properly
deduplicating them is probably larger than the benefit in the 99% case.
Change-Id: Iefc922ac9e2b24ef2ff1e9dacb17a735a75ec8ea
Bug: skia:10855, skia:11052
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/341162
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLMetalCodeGenerator.h b/src/sksl/SkSLMetalCodeGenerator.h
index e6b1dae..1f49b63 100644
--- a/src/sksl/SkSLMetalCodeGenerator.h
+++ b/src/sksl/SkSLMetalCodeGenerator.h
@@ -178,6 +178,11 @@
void writeFunctionStart(const FunctionDeclaration& f);
+ void writeFunctionRequirementParams(const FunctionDeclaration& f,
+ const char*& separator);
+
+ void writeFunctionRequirementArgs(const FunctionDeclaration& f, const char*& separator);
+
bool writeFunctionDeclaration(const FunctionDeclaration& f);
void writeFunction(const FunctionDefinition& f);
@@ -204,7 +209,9 @@
void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
- String getOutParamHelper(const FunctionDeclaration& function, const ExpressionArray& arguments);
+ String getOutParamHelper(const FunctionCall& c,
+ const ExpressionArray& arguments,
+ const SkTArray<VariableReference*>& outVars);
String getInverseHack(const Expression& mat);
@@ -284,7 +291,6 @@
int fPaddingCount = 0;
const char* fLineEnding;
const Context& fContext;
- StringStream fHeader;
String fFunctionHeader;
StringStream fExtraFunctions;
Program::Kind fProgramKind;
@@ -305,6 +311,8 @@
int fUniformBuffer = -1;
String fRTHeightName;
const FunctionDeclaration* fCurrentFunction = nullptr;
+ int fSwizzleHelperCount = 0;
+ bool fIgnoreVariableReferenceModifiers = false;
using INHERITED = CodeGenerator;
};