Add basic support for assigning arrays in HLSL output
Implement support for assignments where the return value of the assignment
is not used in another part of the expression.
TEST=WebGL conformance tests
BUG=angleproject:960
Change-Id: Ibf9d71a75d27d139d2aabb5162ab04a0974321d3
Reviewed-on: https://chromium-review.googlesource.com/263222
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index ffc6cf3..c3240f5 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -345,6 +345,14 @@
out << eqFunction->functionDefinition << "\n";
}
}
+ if (!mArrayAssignmentFunctions.empty())
+ {
+ out << "\n// Assignment functions\n\n";
+ for (const auto &assignmentFunction : mArrayAssignmentFunctions)
+ {
+ out << assignmentFunction.functionDefinition << "\n";
+ }
+ }
if (mUsesDiscardRewriting)
{
@@ -1443,7 +1451,8 @@
case EOpAssign:
if (node->getLeft()->isArray())
{
- UNIMPLEMENTED();
+ const TString &functionName = addArrayAssignmentFunction(node->getType());
+ outputTriplet(visit, (functionName + "(").c_str(), ", ", ")");
}
else
{
@@ -3022,7 +3031,7 @@
const TString &typeName = TypeString(type);
- ArrayEqualityFunction *function = new ArrayEqualityFunction();
+ ArrayHelperFunction *function = new ArrayHelperFunction();
function->type = type;
TInfoSinkBase fnNameOut;
@@ -3061,4 +3070,42 @@
return function->functionName;
}
+TString OutputHLSL::addArrayAssignmentFunction(const TType& type)
+{
+ for (const auto &assignFunction : mArrayAssignmentFunctions)
+ {
+ if (assignFunction.type == type)
+ {
+ return assignFunction.functionName;
+ }
+ }
+
+ const TString &typeName = TypeString(type);
+
+ ArrayHelperFunction function;
+ function.type = type;
+
+ TInfoSinkBase fnNameOut;
+ fnNameOut << "angle_assign_" << type.getArraySize() << "_" << typeName;
+ function.functionName = fnNameOut.c_str();
+
+ TInfoSinkBase fnOut;
+
+ fnOut << "void " << function.functionName << "(out "
+ << typeName << " a[" << type.getArraySize() << "], "
+ << typeName << " b[" << type.getArraySize() << "])\n"
+ << "{\n"
+ " for (int i = 0; i < " << type.getArraySize() << "; ++i)\n"
+ " {\n"
+ " a[i] = b[i];\n"
+ " }\n"
+ "}\n";
+
+ function.functionDefinition = fnOut.c_str();
+
+ mArrayAssignmentFunctions.push_back(function);
+
+ return function.functionName;
+}
+
}
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index 4083376..51da877 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -89,6 +89,7 @@
// Returns the function name
TString addStructEqualityFunction(const TStructure &structure);
TString addArrayEqualityFunction(const TType &type);
+ TString addArrayAssignmentFunction(const TType &type);
sh::GLenum mShaderType;
int mShaderVersion;
@@ -186,31 +187,33 @@
// these static globals after we initialize our other globals.
std::vector<std::pair<TIntermSymbol*, TIntermTyped*>> mDeferredGlobalInitializers;
- struct EqualityFunction
+ struct HelperFunction
{
TString functionName;
TString functionDefinition;
- virtual ~EqualityFunction() {}
+ virtual ~HelperFunction() {}
};
// A list of all equality comparison functions. It's important to preserve the order at
// which we add the functions, since nested structures call each other recursively, and
// structure equality functions may need to call array equality functions and vice versa.
// The ownership of the pointers is maintained by the type-specific arrays.
- std::vector<EqualityFunction*> mEqualityFunctions;
+ std::vector<HelperFunction*> mEqualityFunctions;
- struct StructEqualityFunction : public EqualityFunction
+ struct StructEqualityFunction : public HelperFunction
{
const TStructure *structure;
};
std::vector<StructEqualityFunction*> mStructEqualityFunctions;
- struct ArrayEqualityFunction : public EqualityFunction
+ struct ArrayHelperFunction : public HelperFunction
{
TType type;
};
- std::vector<ArrayEqualityFunction*> mArrayEqualityFunctions;
+ std::vector<ArrayHelperFunction*> mArrayEqualityFunctions;
+
+ std::vector<ArrayHelperFunction> mArrayAssignmentFunctions;
};
}