Work around For and While loop bugs on Intel Mac OSX
Condition calculation in for and while loops has bug on Intel Mac. Work
around it by converting "CONDITION" to "CONDITION && true".
This CL also adds previous SH_EMULATE_ABS_INT_FUNCTION workaround to
the ANGLE GL back-end on OSX
BUG=chromium:644669
TEST=deqp/functional/gles3/shaderloop_for/while.html
Change-Id: I910f662b054f259fcb601b9938841b3a2d066840
Reviewed-on: https://chromium-review.googlesource.com/381678
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Qiankun Miao <qiankun.miao@intel.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler.gypi b/src/compiler.gypi
index a0f8e80..8d754ee 100644
--- a/src/compiler.gypi
+++ b/src/compiler.gypi
@@ -22,6 +22,8 @@
'../include/GLSLANG/ShaderVars.h',
'../include/KHR/khrplatform.h',
'../include/angle_gl.h',
+ 'compiler/translator/AddAndTrueToLoopCondition.cpp',
+ 'compiler/translator/AddAndTrueToLoopCondition.h',
'compiler/translator/BaseTypes.h',
'compiler/translator/BuiltInFunctionEmulator.cpp',
'compiler/translator/BuiltInFunctionEmulator.h',
diff --git a/src/compiler/translator/AddAndTrueToLoopCondition.cpp b/src/compiler/translator/AddAndTrueToLoopCondition.cpp
new file mode 100644
index 0000000..0177fea
--- /dev/null
+++ b/src/compiler/translator/AddAndTrueToLoopCondition.cpp
@@ -0,0 +1,59 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/AddAndTrueToLoopCondition.h"
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An AST traverser that rewrites for and while loops by replacing "condition" with
+// "condition && true" to work around condition bug on Intel Mac.
+class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
+{
+ public:
+ AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitLoop(Visit, TIntermLoop *loop) override
+ {
+ // do-while loop doesn't have this bug.
+ if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile)
+ {
+ return true;
+ }
+
+ // For loop may not have a condition.
+ if (loop->getCondition() == nullptr)
+ {
+ return true;
+ }
+
+ // Constant true.
+ TConstantUnion *trueConstant = new TConstantUnion();
+ trueConstant->setBConst(true);
+ TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, TType(EbtBool));
+
+ // CONDITION && true.
+ TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
+ loop->setCondition(andOp);
+
+ return true;
+ }
+};
+
+} // anonymous namespace
+
+void AddAndTrueToLoopCondition(TIntermNode *root)
+{
+ AddAndTrueToLoopConditionTraverser traverser;
+ root->traverse(&traverser);
+}
+
+} // namespace sh
diff --git a/src/compiler/translator/AddAndTrueToLoopCondition.h b/src/compiler/translator/AddAndTrueToLoopCondition.h
new file mode 100644
index 0000000..34debe0
--- /dev/null
+++ b/src/compiler/translator/AddAndTrueToLoopCondition.h
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Rewrite condition in for and while loops to work around driver bug on Intel Mac.
+
+#ifndef COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
+#define COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
+
+class TIntermNode;
+namespace sh
+{
+
+void AddAndTrueToLoopCondition(TIntermNode *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index ddeb05a..62e2c17 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -4,6 +4,7 @@
// found in the LICENSE file.
//
+#include "compiler/translator/AddAndTrueToLoopCondition.h"
#include "compiler/translator/Cache.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/CallDAG.h"
@@ -331,6 +332,9 @@
if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
RewriteDoWhile(root, getTemporaryIndex());
+ if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION))
+ sh::AddAndTrueToLoopCondition(root);
+
if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
{
UnfoldShortCircuitAST unfoldShortCircuit;
diff --git a/src/libANGLE/renderer/gl/ShaderGL.cpp b/src/libANGLE/renderer/gl/ShaderGL.cpp
index 8891aa7..0081fcd 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.cpp
+++ b/src/libANGLE/renderer/gl/ShaderGL.cpp
@@ -55,6 +55,16 @@
options |= SH_REWRITE_DO_WHILE_LOOPS;
}
+ if (mWorkarounds.emulateAbsIntFunction)
+ {
+ options |= SH_EMULATE_ABS_INT_FUNCTION;
+ }
+
+ if (mWorkarounds.addAndTrueToLoopCondition)
+ {
+ options |= SH_ADD_AND_TRUE_TO_LOOP_CONDITION;
+ }
+
return options;
}
diff --git a/src/libANGLE/renderer/gl/WorkaroundsGL.h b/src/libANGLE/renderer/gl/WorkaroundsGL.h
index 37a4f2b..c8e066d 100644
--- a/src/libANGLE/renderer/gl/WorkaroundsGL.h
+++ b/src/libANGLE/renderer/gl/WorkaroundsGL.h
@@ -21,7 +21,9 @@
doWhileGLSLCausesGPUHang(false),
finishDoesNotCauseQueriesToBeAvailable(false),
alwaysCallUseProgramAfterLink(false),
- unpackOverlappingRowsSeparatelyUnpackBuffer(false)
+ unpackOverlappingRowsSeparatelyUnpackBuffer(false),
+ emulateAbsIntFunction(false),
+ addAndTrueToLoopCondition(false)
{
}
@@ -70,6 +72,14 @@
// During initialization, assign the current vertex attributes to the spec-mandated defaults.
bool initializeCurrentVertexAttributes;
+
+ // abs(i) where i is an integer returns unexpected result on Intel Mac.
+ // Emulate abs(i) with i * sign(i).
+ bool emulateAbsIntFunction;
+
+ // On Intel Mac, calculation of loop conditions in for and while loop has bug.
+ // Add "&& true" to the end of the condition expression to work around the bug.
+ bool addAndTrueToLoopCondition;
};
}
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index 05dbdab..50b806a 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -881,6 +881,10 @@
workarounds->rgba4IsNotSupportedForColorRendering =
functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_INTEL;
+ workarounds->emulateAbsIntFunction = vendor == VENDOR_ID_INTEL;
+
+ workarounds->addAndTrueToLoopCondition = vendor == VENDOR_ID_INTEL;
+
workarounds->doesSRGBClearsOnLinearFramebufferAttachments =
functions->standard == STANDARD_GL_DESKTOP &&
(vendor == VENDOR_ID_INTEL || vendor == VENDOR_ID_AMD);