Commit 1269076c by Olli Etuaho

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/263222Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 0d91328b
...@@ -345,6 +345,14 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) ...@@ -345,6 +345,14 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator)
out << eqFunction->functionDefinition << "\n"; out << eqFunction->functionDefinition << "\n";
} }
} }
if (!mArrayAssignmentFunctions.empty())
{
out << "\n// Assignment functions\n\n";
for (const auto &assignmentFunction : mArrayAssignmentFunctions)
{
out << assignmentFunction.functionDefinition << "\n";
}
}
if (mUsesDiscardRewriting) if (mUsesDiscardRewriting)
{ {
...@@ -1443,7 +1451,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1443,7 +1451,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
case EOpAssign: case EOpAssign:
if (node->getLeft()->isArray()) if (node->getLeft()->isArray())
{ {
UNIMPLEMENTED(); const TString &functionName = addArrayAssignmentFunction(node->getType());
outputTriplet(visit, (functionName + "(").c_str(), ", ", ")");
} }
else else
{ {
...@@ -3022,7 +3031,7 @@ TString OutputHLSL::addArrayEqualityFunction(const TType& type) ...@@ -3022,7 +3031,7 @@ TString OutputHLSL::addArrayEqualityFunction(const TType& type)
const TString &typeName = TypeString(type); const TString &typeName = TypeString(type);
ArrayEqualityFunction *function = new ArrayEqualityFunction(); ArrayHelperFunction *function = new ArrayHelperFunction();
function->type = type; function->type = type;
TInfoSinkBase fnNameOut; TInfoSinkBase fnNameOut;
...@@ -3061,4 +3070,42 @@ TString OutputHLSL::addArrayEqualityFunction(const TType& type) ...@@ -3061,4 +3070,42 @@ TString OutputHLSL::addArrayEqualityFunction(const TType& type)
return function->functionName; 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;
}
} }
...@@ -89,6 +89,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -89,6 +89,7 @@ class OutputHLSL : public TIntermTraverser
// Returns the function name // Returns the function name
TString addStructEqualityFunction(const TStructure &structure); TString addStructEqualityFunction(const TStructure &structure);
TString addArrayEqualityFunction(const TType &type); TString addArrayEqualityFunction(const TType &type);
TString addArrayAssignmentFunction(const TType &type);
sh::GLenum mShaderType; sh::GLenum mShaderType;
int mShaderVersion; int mShaderVersion;
...@@ -186,31 +187,33 @@ class OutputHLSL : public TIntermTraverser ...@@ -186,31 +187,33 @@ class OutputHLSL : public TIntermTraverser
// these static globals after we initialize our other globals. // these static globals after we initialize our other globals.
std::vector<std::pair<TIntermSymbol*, TIntermTyped*>> mDeferredGlobalInitializers; std::vector<std::pair<TIntermSymbol*, TIntermTyped*>> mDeferredGlobalInitializers;
struct EqualityFunction struct HelperFunction
{ {
TString functionName; TString functionName;
TString functionDefinition; TString functionDefinition;
virtual ~EqualityFunction() {} virtual ~HelperFunction() {}
}; };
// A list of all equality comparison functions. It's important to preserve the order at // 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 // 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. // 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. // 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; const TStructure *structure;
}; };
std::vector<StructEqualityFunction*> mStructEqualityFunctions; std::vector<StructEqualityFunction*> mStructEqualityFunctions;
struct ArrayEqualityFunction : public EqualityFunction struct ArrayHelperFunction : public HelperFunction
{ {
TType type; TType type;
}; };
std::vector<ArrayEqualityFunction*> mArrayEqualityFunctions; std::vector<ArrayHelperFunction*> mArrayEqualityFunctions;
std::vector<ArrayHelperFunction> mArrayAssignmentFunctions;
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment