Commit 09cfac60 by Qiankun Miao Committed by Commit Bot

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/381678Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Qiankun Miao <qiankun.miao@intel.com> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 930fefca
...@@ -49,7 +49,7 @@ typedef unsigned int GLenum; ...@@ -49,7 +49,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 160 #define ANGLE_SH_VERSION 161
typedef enum { typedef enum {
SH_GLES2_SPEC, SH_GLES2_SPEC,
...@@ -195,6 +195,10 @@ const ShCompileOptions SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = UINT64_C(1) < ...@@ -195,6 +195,10 @@ const ShCompileOptions SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = UINT64_C(1) <
// INTEL drivers. It works by translating texelFetchOffset into texelFetch. // INTEL drivers. It works by translating texelFetchOffset into texelFetch.
const ShCompileOptions SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = UINT64_C(1) << 24; const ShCompileOptions SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = UINT64_C(1) << 24;
// This flag works around condition bug of for and while loops in Intel Mac OSX drivers.
// Condition calculation is not correct. Rewrite it from "CONDITION" to "CONDITION && true".
const ShCompileOptions SH_ADD_AND_TRUE_TO_LOOP_CONDITION = UINT64_C(1) << 25;
// Defines alternate strategies for implementing array index clamping. // Defines alternate strategies for implementing array index clamping.
typedef enum { typedef enum {
// Use the clamp intrinsic for array index clamping. // Use the clamp intrinsic for array index clamping.
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
'../include/GLSLANG/ShaderVars.h', '../include/GLSLANG/ShaderVars.h',
'../include/KHR/khrplatform.h', '../include/KHR/khrplatform.h',
'../include/angle_gl.h', '../include/angle_gl.h',
'compiler/translator/AddAndTrueToLoopCondition.cpp',
'compiler/translator/AddAndTrueToLoopCondition.h',
'compiler/translator/BaseTypes.h', 'compiler/translator/BaseTypes.h',
'compiler/translator/BuiltInFunctionEmulator.cpp', 'compiler/translator/BuiltInFunctionEmulator.cpp',
'compiler/translator/BuiltInFunctionEmulator.h', 'compiler/translator/BuiltInFunctionEmulator.h',
......
//
// 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
//
// 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_
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "compiler/translator/AddAndTrueToLoopCondition.h"
#include "compiler/translator/Cache.h" #include "compiler/translator/Cache.h"
#include "compiler/translator/Compiler.h" #include "compiler/translator/Compiler.h"
#include "compiler/translator/CallDAG.h" #include "compiler/translator/CallDAG.h"
...@@ -331,6 +332,9 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -331,6 +332,9 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS)) if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
RewriteDoWhile(root, getTemporaryIndex()); RewriteDoWhile(root, getTemporaryIndex());
if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION))
sh::AddAndTrueToLoopCondition(root);
if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
{ {
UnfoldShortCircuitAST unfoldShortCircuit; UnfoldShortCircuitAST unfoldShortCircuit;
......
...@@ -55,6 +55,16 @@ ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sour ...@@ -55,6 +55,16 @@ ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sour
options |= SH_REWRITE_DO_WHILE_LOOPS; 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; return options;
} }
......
...@@ -21,7 +21,9 @@ struct WorkaroundsGL ...@@ -21,7 +21,9 @@ struct WorkaroundsGL
doWhileGLSLCausesGPUHang(false), doWhileGLSLCausesGPUHang(false),
finishDoesNotCauseQueriesToBeAvailable(false), finishDoesNotCauseQueriesToBeAvailable(false),
alwaysCallUseProgramAfterLink(false), alwaysCallUseProgramAfterLink(false),
unpackOverlappingRowsSeparatelyUnpackBuffer(false) unpackOverlappingRowsSeparatelyUnpackBuffer(false),
emulateAbsIntFunction(false),
addAndTrueToLoopCondition(false)
{ {
} }
...@@ -70,6 +72,14 @@ struct WorkaroundsGL ...@@ -70,6 +72,14 @@ struct WorkaroundsGL
// During initialization, assign the current vertex attributes to the spec-mandated defaults. // During initialization, assign the current vertex attributes to the spec-mandated defaults.
bool initializeCurrentVertexAttributes; 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;
}; };
} }
......
...@@ -881,6 +881,10 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround ...@@ -881,6 +881,10 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
workarounds->rgba4IsNotSupportedForColorRendering = workarounds->rgba4IsNotSupportedForColorRendering =
functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_INTEL; functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_INTEL;
workarounds->emulateAbsIntFunction = vendor == VENDOR_ID_INTEL;
workarounds->addAndTrueToLoopCondition = vendor == VENDOR_ID_INTEL;
workarounds->doesSRGBClearsOnLinearFramebufferAttachments = workarounds->doesSRGBClearsOnLinearFramebufferAttachments =
functions->standard == STANDARD_GL_DESKTOP && functions->standard == STANDARD_GL_DESKTOP &&
(vendor == VENDOR_ID_INTEL || vendor == VENDOR_ID_AMD); (vendor == VENDOR_ID_INTEL || vendor == VENDOR_ID_AMD);
......
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