Commit f3be8481 by Nicolas Capens

Use shader optimization level 3 selectively.

Revert to HLSL compiler optimization level 1 and work around a compiler bug with break in nested loops by using optimization level 3. BUG=angle:603 Change-Id: Ib45815ef5bc3f72a3c51c7041c8a77ec573aa9e7 Reviewed-on: https://chromium-review.googlesource.com/194130Tested-by: 's avatarNicolas Capens <nicolascapens@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org>
parent d1234cd5
......@@ -68,6 +68,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mUsesAtan2_3 = false;
mUsesAtan2_4 = false;
mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
......@@ -78,6 +79,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mContainsLoopDiscontinuity = false;
mOutputLod0Function = false;
mInsideDiscontinuousLoop = false;
mNestedLoopDepth = 0;
mExcessiveLoopIndex = NULL;
......@@ -204,6 +206,11 @@ void OutputHLSL::header()
out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
}
if (mUsesNestedBreak)
{
out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
}
if (shaderType == SH_FRAGMENT_SHADER)
{
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
......@@ -2033,6 +2040,8 @@ void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node)
bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{
mNestedLoopDepth++;
bool wasDiscontinuous = mInsideDiscontinuousLoop;
if (mContainsLoopDiscontinuity && !mInsideDiscontinuousLoop)
......@@ -2044,6 +2053,9 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{
if (handleExcessiveLoop(node))
{
mInsideDiscontinuousLoop = wasDiscontinuous;
mNestedLoopDepth--;
return false;
}
}
......@@ -2107,6 +2119,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
out << "}\n";
mInsideDiscontinuousLoop = wasDiscontinuous;
mNestedLoopDepth--;
return false;
}
......@@ -2123,6 +2136,11 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
case EOpBreak:
if (visit == PreVisit)
{
if (mNestedLoopDepth > 1)
{
mUsesNestedBreak = true;
}
if (mExcessiveLoopIndex)
{
out << "{Break";
......
......@@ -127,6 +127,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesAtan2_3;
bool mUsesAtan2_4;
bool mUsesDiscardRewriting;
bool mUsesNestedBreak;
int mNumRenderTargets;
......@@ -148,6 +149,7 @@ class OutputHLSL : public TIntermTraverser
bool mContainsLoopDiscontinuity;
bool mOutputLod0Function;
bool mInsideDiscontinuousLoop;
int mNestedLoopDepth;
TIntermSymbol *mExcessiveLoopIndex;
......
......@@ -34,12 +34,27 @@ std::string str(int i)
return buffer;
}
static rx::D3DWorkaroundType DiscardWorkaround(bool usesDiscard)
static rx::D3DWorkaroundType DiscardWorkaround(bool usesDiscard, bool nestedBreak)
{
return (usesDiscard ? rx::ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER : rx::ANGLE_D3D_WORKAROUND_NONE);
if (usesDiscard)
{
// ANGLE issue 486:
// Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
}
if (nestedBreak)
{
// ANGLE issue 603:
// Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization
// We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence
return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
}
return rx::ANGLE_D3D_WORKAROUND_NONE;
}
UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index)
UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index)
: name(name), element(element), index(index)
{
}
......@@ -1979,8 +1994,8 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
if (success)
{
mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, DiscardWorkaround(vertexShader->mUsesDiscardRewriting));
mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, DiscardWorkaround(fragmentShader->mUsesDiscardRewriting));
mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, DiscardWorkaround(vertexShader->mUsesDiscardRewriting, vertexShader->mUsesNestedBreak));
mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, DiscardWorkaround(fragmentShader->mUsesDiscardRewriting, fragmentShader->mUsesNestedBreak));
if (usesGeometryShader())
{
......
......@@ -308,6 +308,7 @@ void Shader::parseVaryings()
mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL;
mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
mUsesDiscardRewriting = strstr(mHlsl, "ANGLE_USES_DISCARD_REWRITING") != NULL;
mUsesNestedBreak = strstr(mHlsl, "ANGLE_USES_NESTED_BREAK") != NULL;
}
}
......@@ -342,6 +343,7 @@ void Shader::uncompile()
mUsesDepthRange = false;
mUsesFragDepth = false;
mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
mActiveUniforms.clear();
}
......
......@@ -108,6 +108,7 @@ class Shader
bool mUsesDepthRange;
bool mUsesFragDepth;
bool mUsesDiscardRewriting;
bool mUsesNestedBreak;
static void *mFragmentCompiler;
static void *mVertexCompiler;
......
......@@ -14,7 +14,9 @@
#include "libGLESv2/angletypes.h"
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
// It should only be used selectively to work around specific bugs.
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
#endif
const int versionWindowsVista = MAKEWORD(0x00, 0x06);
......@@ -96,7 +98,8 @@ enum ShaderType
enum D3DWorkaroundType
{
ANGLE_D3D_WORKAROUND_NONE,
ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER
ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION,
ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION
};
class Renderer
......
......@@ -3169,9 +3169,17 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
return NULL;
}
// ANGLE issue 486:
// Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
UINT optimizationFlags = (workaround == ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER ? D3DCOMPILE_SKIP_OPTIMIZATION : ANGLE_COMPILE_OPTIMIZATION_LEVEL);
UINT optimizationFlags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
if (workaround == ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION)
{
optimizationFlags = D3DCOMPILE_SKIP_OPTIMIZATION;
}
else if (workaround == ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION)
{
optimizationFlags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
}
else ASSERT(workaround == ANGLE_D3D_WORKAROUND_NONE);
ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true);
if (!binary)
......
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