summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp')
-rwxr-xr-xgfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp103
1 files changed, 56 insertions, 47 deletions
diff --git a/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp b/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
index a4eeb9b7e..a664d9e2f 100755
--- a/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ b/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
@@ -14,60 +14,59 @@
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
#include "compiler/translator/IntermNode.h"
-namespace sh
+namespace
{
-namespace
+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 *constructGLFragDataNode(int index)
{
+ TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
+ TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", TType(EbtFloat, 4));
+ indexDirect->setLeft(symbol);
+ TIntermConstantUnion *indexNode = constructIndexNode(index);
+ indexDirect->setRight(indexNode);
+ return indexDirect;
+}
+
+TIntermBinary *constructGLFragDataAssignNode(int index)
+{
+ TIntermBinary *assign = new TIntermBinary(EOpAssign);
+ assign->setLeft(constructGLFragDataNode(index));
+ assign->setRight(constructGLFragDataNode(0));
+ assign->setType(TType(EbtFloat, 4));
+ return assign;
+}
class GLFragColorBroadcastTraverser : public TIntermTraverser
{
public:
- GLFragColorBroadcastTraverser(int maxDrawBuffers)
- : TIntermTraverser(true, false, false),
- mMainSequence(nullptr),
- mGLFragColorUsed(false),
- mMaxDrawBuffers(maxDrawBuffers)
+ GLFragColorBroadcastTraverser()
+ : TIntermTraverser(true, false, false), mMainSequence(nullptr), mGLFragColorUsed(false)
{
}
- void broadcastGLFragColor();
+ void broadcastGLFragColor(int maxDrawBuffers);
bool isGLFragColorUsed() const { return mGLFragColorUsed; }
protected:
void visitSymbol(TIntermSymbol *node) override;
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
-
- TIntermBinary *constructGLFragDataNode(int index) const;
- TIntermBinary *constructGLFragDataAssignNode(int index) const;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
TIntermSequence *mMainSequence;
bool mGLFragColorUsed;
- int mMaxDrawBuffers;
};
-TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
-{
- TType gl_FragDataType = TType(EbtFloat, EbpMedium, EvqFragData, 4);
- gl_FragDataType.setArraySize(mMaxDrawBuffers);
-
- TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", gl_FragDataType);
- TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index);
-
- TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
- return binary;
-}
-
-TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int index) const
-{
- TIntermTyped *fragDataIndex = constructGLFragDataNode(index);
- TIntermTyped *fragDataZero = constructGLFragDataNode(0);
-
- return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero);
-}
-
void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
{
if (node->getSymbol() == "gl_FragColor")
@@ -77,22 +76,34 @@ void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
}
}
-bool GLFragColorBroadcastTraverser::visitFunctionDefinition(Visit visit,
- TIntermFunctionDefinition *node)
+bool GLFragColorBroadcastTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{
- ASSERT(visit == PreVisit);
- if (node->getFunctionSymbolInfo()->isMain())
+ switch (node->getOp())
{
- TIntermBlock *body = node->getBody();
- ASSERT(body);
- mMainSequence = body->getSequence();
+ case EOpFunction:
+ // Function definition.
+ ASSERT(visit == PreVisit);
+ if (node->getName() == "main(")
+ {
+ TIntermSequence *sequence = node->getSequence();
+ ASSERT((sequence->size() == 1) || (sequence->size() == 2));
+ if (sequence->size() == 2)
+ {
+ TIntermAggregate *body = (*sequence)[1]->getAsAggregate();
+ ASSERT(body);
+ mMainSequence = body->getSequence();
+ }
+ }
+ break;
+ default:
+ break;
}
return true;
}
-void GLFragColorBroadcastTraverser::broadcastGLFragColor()
+void GLFragColorBroadcastTraverser::broadcastGLFragColor(int maxDrawBuffers)
{
- ASSERT(mMaxDrawBuffers > 1);
+ ASSERT(maxDrawBuffers > 1);
if (!mGLFragColorUsed)
{
return;
@@ -102,7 +113,7 @@ void GLFragColorBroadcastTraverser::broadcastGLFragColor()
// gl_FragData[1] = gl_FragData[0];
// ...
// gl_FragData[maxDrawBuffers - 1] = gl_FragData[0];
- for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex)
+ for (int colorIndex = 1; colorIndex < maxDrawBuffers; ++colorIndex)
{
mMainSequence->insert(mMainSequence->end(), constructGLFragDataAssignNode(colorIndex));
}
@@ -115,12 +126,12 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
std::vector<sh::OutputVariable> *outputVariables)
{
ASSERT(maxDrawBuffers > 1);
- GLFragColorBroadcastTraverser traverser(maxDrawBuffers);
+ GLFragColorBroadcastTraverser traverser;
root->traverse(&traverser);
if (traverser.isGLFragColorUsed())
{
traverser.updateTree();
- traverser.broadcastGLFragColor();
+ traverser.broadcastGLFragColor(maxDrawBuffers);
for (auto &var : *outputVariables)
{
if (var.name == "gl_FragColor")
@@ -133,5 +144,3 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
}
}
}
-
-} // namespace sh