Commit f52fe93d by Qiankun Miao Committed by Commit Bot

Work around unary minus operator float issue on Intel Mac 10.11

Result of -float is wrong on Intel Mac 10.11 drivers. Replace -float with 0.0 - float to work around this issue. BUG=308366 BUG=672380 Change-Id: I53bc2eda7259fff5805bec39896fc7b7a6eaf665 Reviewed-on: https://chromium-review.googlesource.com/417169Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent d0239396
......@@ -25,7 +25,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 168
#define ANGLE_SH_VERSION 169
enum ShShaderSpec
{
......@@ -203,6 +203,10 @@ const ShCompileOptions SH_EMULATE_ISNAN_FLOAT_FUNCTION = UINT64_C(1) << 27;
// layout qualifier to be considered active. The uniform block itself is also considered active.
const ShCompileOptions SH_USE_UNUSED_STANDARD_SHARED_BLOCKS = UINT64_C(1) << 28;
// This flag works around a bug in unary minus operator on float numbers on Intel
// Mac OSX 10.11 drivers. It works by translating -float into 0.0 - float.
const ShCompileOptions SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR = UINT64_C(1) << 29;
// Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy
{
......
......@@ -95,6 +95,8 @@
'compiler/translator/RewriteDoWhile.h',
'compiler/translator/RewriteTexelFetchOffset.cpp',
'compiler/translator/RewriteTexelFetchOffset.h',
'compiler/translator/RewriteUnaryMinusOperatorFloat.cpp',
'compiler/translator/RewriteUnaryMinusOperatorFloat.h',
'compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
'compiler/translator/RewriteUnaryMinusOperatorInt.h',
'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
......
//
// 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/RewriteUnaryMinusOperatorFloat.h"
#include "compiler/translator/IntermNode.h"
namespace sh
{
namespace
{
class Traverser : public TIntermTraverser
{
public:
static void Apply(TIntermNode *root);
private:
Traverser();
bool visitUnary(Visit visit, TIntermUnary *node) override;
void nextIteration();
bool mFound = false;
};
// static
void Traverser::Apply(TIntermNode *root)
{
Traverser traverser;
do
{
traverser.nextIteration();
root->traverse(&traverser);
if (traverser.mFound)
{
traverser.updateTree();
}
} while (traverser.mFound);
}
Traverser::Traverser() : TIntermTraverser(true, false, false)
{
}
void Traverser::nextIteration()
{
mFound = false;
}
bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
{
if (mFound)
{
return false;
}
// Detect if the current operator is unary minus operator.
if (node->getOp() != EOpNegative)
{
return true;
}
// Detect if the current operand is a float variable.
TIntermTyped *fValue = node->getOperand();
if (!fValue->getType().isScalarFloat())
{
return true;
}
// 0.0 - float
TIntermTyped *zero = TIntermTyped::CreateZero(fValue->getType());
zero->setLine(fValue->getLine());
TIntermBinary *sub = new TIntermBinary(EOpSub, zero, fValue);
sub->setLine(fValue->getLine());
queueReplacement(node, sub, OriginalNode::IS_DROPPED);
mFound = true;
return false;
}
} // anonymous namespace
void RewriteUnaryMinusOperatorFloat(TIntermNode *root)
{
Traverser::Apply(root);
}
} // 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 "-float" to "0.0 - float" to work around unary minus operator on float issue on Intel Mac
// OSX 10.11.
#ifndef COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_
#define COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_
class TIntermNode;
namespace sh
{
void RewriteUnaryMinusOperatorFloat(TIntermNode *root);
} // namespace sh
#endif // COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_
......@@ -12,6 +12,7 @@
#include "compiler/translator/ExtensionGLSL.h"
#include "compiler/translator/OutputGLSL.h"
#include "compiler/translator/RewriteTexelFetchOffset.h"
#include "compiler/translator/RewriteUnaryMinusOperatorFloat.h"
#include "compiler/translator/VersionGLSL.h"
namespace sh
......@@ -92,6 +93,11 @@ void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOption
sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion());
}
if ((compileOptions & SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR) != 0)
{
sh::RewriteUnaryMinusOperatorFloat(root);
}
bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
if (precisionEmulation)
......
......@@ -469,6 +469,7 @@ class TType
{
return primarySize == 1 && secondarySize == 1 && !structure;
}
bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
bool isScalarInt() const
{
return isScalar() && (type == EbtInt || type == EbtUInt);
......
......@@ -85,6 +85,11 @@ ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sour
options |= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3;
}
if (mWorkarounds.rewriteFloatUnaryMinusOperator)
{
options |= SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR;
}
return options;
}
......
......@@ -27,7 +27,8 @@ struct WorkaroundsGL
emulateIsnanFloat(false),
useUnusedBlocksWithStandardOrSharedLayout(false),
dontRemoveInvariantForFragmentInput(false),
removeInvariantAndCentroidForESSL3(false)
removeInvariantAndCentroidForESSL3(false),
rewriteFloatUnaryMinusOperator(false)
{
}
......@@ -120,6 +121,11 @@ struct WorkaroundsGL
// This flag is used to fix spec difference between GLSL 4.1 or lower and ESSL3.
bool removeInvariantAndCentroidForESSL3;
// On Intel Mac OSX 10.11 driver, using "-float" will get wrong answer. Use "0.0 - float" to
// replace "-float".
// Tracking bug: http://crbug.com/308366
bool rewriteFloatUnaryMinusOperator;
};
}
......
......@@ -928,6 +928,7 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
#if defined(ANGLE_PLATFORM_APPLE)
workarounds->doWhileGLSLCausesGPUHang = true;
workarounds->useUnusedBlocksWithStandardOrSharedLayout = true;
workarounds->rewriteFloatUnaryMinusOperator = IsIntel(vendor);
#endif
workarounds->finishDoesNotCauseQueriesToBeAvailable =
......
......@@ -2167,6 +2167,37 @@ TEST_P(GLSLTest, NestedPowStatements)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// Test that -float calculation is correct.
TEST_P(GLSLTest_ES3, UnaryMinusOperatorFloat)
{
// TODO(oetuaho@nvidia.com): re-enable once http://crbug.com/672380 is fixed.
if ((IsWindows() || IsLinux()) && IsNVIDIA() && IsOpenGL())
{
std::cout << "Test disabled on this OpenGL configuration." << std::endl;
return;
}
const std::string &vert =
"#version 300 es\n"
"in highp vec4 position;\n"
"void main() {\n"
" gl_Position = position;\n"
"}\n";
const std::string &frag =
"#version 300 es\n"
"out highp vec4 o_color;\n"
"void main() {\n"
" highp float f = -1.0;\n"
" // atan(tan(0.5), -f) should be 0.5.\n"
" highp float v = atan(tan(0.5), -f);\n"
" o_color = abs(v - 0.5) < 0.001 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
"}\n";
ANGLE_GL_PROGRAM(prog, vert, frag);
drawQuad(prog.get(), "position", 0.5f);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// Convers a bug with the unary minus operator on signed integer workaround.
TEST_P(GLSLTest_ES3, UnaryMinusOperatorSignedInt)
{
......
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