summaryrefslogtreecommitdiffstats
path: root/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp')
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp93
1 files changed, 68 insertions, 25 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
index 886f693..767d0bf 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
@@ -17,6 +17,17 @@ bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) {
return false;
}
+void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) {
+ for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) {
+ if (i->index.id == symbol->getId()) {
+ ASSERT(i->loop != NULL);
+ i->loop->setUnrollFlag(true);
+ return;
+ }
+ }
+ UNREACHABLE();
+}
+
// Traverses a node to check if it represents a constant index expression.
// Definition:
// constant-index-expressions are a superset of constant-expressions.
@@ -42,18 +53,46 @@ public:
IsLoopIndex(symbol, mLoopStack);
}
}
- virtual void visitConstantUnion(TIntermConstantUnion*) {}
- virtual bool visitBinary(Visit, TIntermBinary*) { return true; }
- virtual bool visitUnary(Visit, TIntermUnary*) { return true; }
- virtual bool visitSelection(Visit, TIntermSelection*) { return true; }
- virtual bool visitAggregate(Visit, TIntermAggregate*) { return true; }
- virtual bool visitLoop(Visit, TIntermLoop*) { return true; }
- virtual bool visitBranch(Visit, TIntermBranch*) { return true; }
private:
bool mValid;
const TLoopStack& mLoopStack;
};
+
+// Traverses a node to check if it uses a loop index.
+// If an int loop index is used in its body as a sampler array index,
+// mark the loop for unroll.
+class ValidateLoopIndexExpr : public TIntermTraverser {
+public:
+ ValidateLoopIndexExpr(TLoopStack& stack)
+ : mUsesFloatLoopIndex(false),
+ mUsesIntLoopIndex(false),
+ mLoopStack(stack) {}
+
+ bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; }
+ bool usesIntLoopIndex() const { return mUsesIntLoopIndex; }
+
+ virtual void visitSymbol(TIntermSymbol* symbol) {
+ if (IsLoopIndex(symbol, mLoopStack)) {
+ switch (symbol->getBasicType()) {
+ case EbtFloat:
+ mUsesFloatLoopIndex = true;
+ break;
+ case EbtInt:
+ mUsesIntLoopIndex = true;
+ MarkLoopForUnroll(symbol, mLoopStack);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+
+private:
+ bool mUsesFloatLoopIndex;
+ bool mUsesIntLoopIndex;
+ TLoopStack& mLoopStack;
+};
} // namespace
ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
@@ -64,14 +103,6 @@ ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
{
}
-void ValidateLimitations::visitSymbol(TIntermSymbol*)
-{
-}
-
-void ValidateLimitations::visitConstantUnion(TIntermConstantUnion*)
-{
-}
-
bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
{
// Check if loop index is modified in the loop body.
@@ -80,7 +111,28 @@ bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
// Check indexing.
switch (node->getOp()) {
case EOpIndexDirect:
+ validateIndexing(node);
+ break;
case EOpIndexIndirect:
+#if defined(__APPLE__)
+ // Loop unrolling is a work-around for a Mac Cg compiler bug where it
+ // crashes when a sampler array's index is also the loop index.
+ // Once Apple fixes this bug, we should remove the code in this CL.
+ // See http://codereview.appspot.com/4331048/.
+ if ((node->getLeft() != NULL) && (node->getRight() != NULL) &&
+ (node->getLeft()->getAsSymbolNode())) {
+ TIntermSymbol* symbol = node->getLeft()->getAsSymbolNode();
+ if (IsSampler(symbol->getBasicType()) && symbol->isArray()) {
+ ValidateLoopIndexExpr validate(mLoopStack);
+ node->getRight()->traverse(&validate);
+ if (validate.usesFloatLoopIndex()) {
+ error(node->getLine(),
+ "sampler array index is float loop index",
+ "for");
+ }
+ }
+ }
+#endif
validateIndexing(node);
break;
default: break;
@@ -96,11 +148,6 @@ bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
return true;
}
-bool ValidateLimitations::visitSelection(Visit, TIntermSelection*)
-{
- return true;
-}
-
bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node)
{
switch (node->getOp()) {
@@ -120,6 +167,7 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
TLoopInfo info;
memset(&info, 0, sizeof(TLoopInfo));
+ info.loop = node;
if (!validateForLoopHeader(node, &info))
return false;
@@ -134,11 +182,6 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
return false;
}
-bool ValidateLimitations::visitBranch(Visit, TIntermBranch*)
-{
- return true;
-}
-
void ValidateLimitations::error(TSourceLoc loc,
const char *reason, const char* token)
{