summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp')
-rwxr-xr-xgfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp187
1 files changed, 88 insertions, 99 deletions
diff --git a/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
index 5afa0d308..775c5d871 100755
--- a/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ b/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -3,10 +3,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Scalarize vector and matrix constructor args, so that vectors built from components don't have
-// matrix arguments, and matrices built from components don't have vector arguments. This avoids
-// driver bugs around vector and matrix constructors.
-//
#include "common/debug.h"
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
@@ -15,10 +11,6 @@
#include "angle_gl.h"
#include "common/angleutils.h"
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
namespace
{
@@ -45,9 +37,23 @@ bool ContainsVectorNode(const TIntermSequence &sequence)
return false;
}
+TIntermConstantUnion *ConstructIndexNode(int index)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setIConst(index);
+
+ TType type(EbtInt, EbpUndefined, EvqConst, 1);
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+ return node;
+}
+
TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
{
- return new TIntermBinary(EOpIndexDirect, symbolNode, TIntermTyped::CreateIndexNode(index));
+ TIntermBinary *binary = new TIntermBinary(EOpIndexDirect);
+ binary->setLeft(symbolNode);
+ TIntermConstantUnion *indexNode = ConstructIndexNode(index);
+ binary->setRight(indexNode);
+ return binary;
}
TIntermBinary *ConstructMatrixIndexBinaryNode(
@@ -56,53 +62,40 @@ TIntermBinary *ConstructMatrixIndexBinaryNode(
TIntermBinary *colVectorNode =
ConstructVectorIndexBinaryNode(symbolNode, colIndex);
- return new TIntermBinary(EOpIndexDirect, colVectorNode,
- TIntermTyped::CreateIndexNode(rowIndex));
+ TIntermBinary *binary = new TIntermBinary(EOpIndexDirect);
+ binary->setLeft(colVectorNode);
+ TIntermConstantUnion *rowIndexNode = ConstructIndexNode(rowIndex);
+ binary->setRight(rowIndexNode);
+ return binary;
}
-class ScalarizeArgsTraverser : public TIntermTraverser
-{
- public:
- ScalarizeArgsTraverser(sh::GLenum shaderType,
- bool fragmentPrecisionHigh,
- unsigned int *temporaryIndex)
- : TIntermTraverser(true, false, false),
- mShaderType(shaderType),
- mFragmentPrecisionHigh(fragmentPrecisionHigh)
- {
- useTemporaryIndex(temporaryIndex);
- }
-
- protected:
- bool visitAggregate(Visit visit, TIntermAggregate *node) override;
- bool visitBlock(Visit visit, TIntermBlock *node) override;
-
- private:
- void scalarizeArgs(TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix);
-
- // If we have the following code:
- // mat4 m(0);
- // vec4 v(1, m);
- // We will rewrite to:
- // mat4 m(0);
- // mat4 s0 = m;
- // vec4 v(1, s0[0][0], s0[0][1], s0[0][2]);
- // This function is to create nodes for "mat4 s0 = m;" and insert it to the code sequence. This
- // way the possible side effects of the constructor argument will only be evaluated once.
- void createTempVariable(TIntermTyped *original);
-
- std::vector<TIntermSequence> mBlockStack;
-
- sh::GLenum mShaderType;
- bool mFragmentPrecisionHigh;
-};
+} // namespace anonymous
-bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+bool ScalarizeVecAndMatConstructorArgs::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (visit == PreVisit)
{
switch (node->getOp())
{
+ case EOpSequence:
+ mSequenceStack.push_back(TIntermSequence());
+ {
+ for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+ iter != node->getSequence()->end(); ++iter)
+ {
+ TIntermNode *child = *iter;
+ ASSERT(child != NULL);
+ child->traverse(this);
+ mSequenceStack.back().push_back(child);
+ }
+ }
+ if (mSequenceStack.back().size() > node->getSequence()->size())
+ {
+ node->getSequence()->clear();
+ *(node->getSequence()) = mSequenceStack.back();
+ }
+ mSequenceStack.pop_back();
+ return false;
case EOpConstructVec2:
case EOpConstructVec3:
case EOpConstructVec4:
@@ -134,29 +127,8 @@ bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
return true;
}
-bool ScalarizeArgsTraverser::visitBlock(Visit visit, TIntermBlock *node)
-{
- mBlockStack.push_back(TIntermSequence());
- {
- for (TIntermNode *child : *node->getSequence())
- {
- ASSERT(child != nullptr);
- child->traverse(this);
- mBlockStack.back().push_back(child);
- }
- }
- if (mBlockStack.back().size() > node->getSequence()->size())
- {
- node->getSequence()->clear();
- *(node->getSequence()) = mBlockStack.back();
- }
- mBlockStack.pop_back();
- return false;
-}
-
-void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
- bool scalarizeVector,
- bool scalarizeMatrix)
+void ScalarizeVecAndMatConstructorArgs::scalarizeArgs(
+ TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix)
{
ASSERT(aggregate);
int size = 0;
@@ -207,10 +179,12 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
ASSERT(size > 0);
TIntermTyped *node = original[ii]->getAsTyped();
ASSERT(node);
- createTempVariable(node);
+ TString varName = createTempVariable(node);
if (node->isScalar())
{
- sequence->push_back(createTempSymbol(node->getType()));
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
+ sequence->push_back(symbolNode);
size--;
}
else if (node->isVector())
@@ -221,7 +195,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
size -= repeat;
for (int index = 0; index < repeat; ++index)
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
TIntermBinary *newNode = ConstructVectorIndexBinaryNode(
symbolNode, index);
sequence->push_back(newNode);
@@ -229,7 +204,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
}
else
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
sequence->push_back(symbolNode);
size -= node->getNominalSize();
}
@@ -244,7 +220,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
size -= repeat;
while (repeat > 0)
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
TIntermBinary *newNode = ConstructMatrixIndexBinaryNode(
symbolNode, colIndex, rowIndex);
sequence->push_back(newNode);
@@ -259,7 +236,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
}
else
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
sequence->push_back(symbolNode);
size -= node->getCols() * node->getRows();
}
@@ -267,13 +245,29 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
}
}
-void ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
+TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *original)
{
- ASSERT(original);
- nextTemporaryIndex();
- TIntermDeclaration *decl = createTempInitDeclaration(original);
+ TString tempVarName = "_webgl_tmp_";
+ if (original->isScalar())
+ {
+ tempVarName += "scalar_";
+ }
+ else if (original->isVector())
+ {
+ tempVarName += "vec_";
+ }
+ else
+ {
+ ASSERT(original->isMatrix());
+ tempVarName += "mat_";
+ }
+ tempVarName += Str(mTempVarCount).c_str();
+ mTempVarCount++;
+ ASSERT(original);
TType type = original->getType();
+ type.setQualifier(EvqTemporary);
+
if (mShaderType == GL_FRAGMENT_SHADER &&
type.getBasicType() == EbtFloat &&
type.getPrecision() == EbpUndefined)
@@ -281,26 +275,21 @@ void ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
// We use the highest available precision for the temporary variable
// to avoid computing the actual precision using the rules defined
// in GLSL ES 1.0 Section 4.5.2.
- TIntermBinary *init = decl->getSequence()->at(0)->getAsBinaryNode();
- init->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
- init->getLeft()->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh
- : EbpMedium);
+ type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
}
- ASSERT(mBlockStack.size() > 0);
- TIntermSequence &sequence = mBlockStack.back();
- sequence.push_back(decl);
-}
+ TIntermBinary *init = new TIntermBinary(EOpInitialize);
+ TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
+ init->setLeft(symbolNode);
+ init->setRight(original);
+ init->setType(type);
-} // namespace anonymous
+ TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration);
+ decl->getSequence()->push_back(init);
-void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
- sh::GLenum shaderType,
- bool fragmentPrecisionHigh,
- unsigned int *temporaryIndex)
-{
- ScalarizeArgsTraverser scalarizer(shaderType, fragmentPrecisionHigh, temporaryIndex);
- root->traverse(&scalarizer);
-}
+ ASSERT(mSequenceStack.size() > 0);
+ TIntermSequence &sequence = mSequenceStack.back();
+ sequence.push_back(decl);
-} // namespace sh
+ return tempVarName;
+}