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 ...@@ -68,6 +68,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mUsesAtan2_3 = false; mUsesAtan2_3 = false;
mUsesAtan2_4 = false; mUsesAtan2_4 = false;
mUsesDiscardRewriting = false; mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
...@@ -78,6 +79,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc ...@@ -78,6 +79,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mContainsLoopDiscontinuity = false; mContainsLoopDiscontinuity = false;
mOutputLod0Function = false; mOutputLod0Function = false;
mInsideDiscontinuousLoop = false; mInsideDiscontinuousLoop = false;
mNestedLoopDepth = 0;
mExcessiveLoopIndex = NULL; mExcessiveLoopIndex = NULL;
...@@ -204,6 +206,11 @@ void OutputHLSL::header() ...@@ -204,6 +206,11 @@ void OutputHLSL::header()
out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n"; out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
} }
if (mUsesNestedBreak)
{
out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
}
if (shaderType == SH_FRAGMENT_SHADER) if (shaderType == SH_FRAGMENT_SHADER)
{ {
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers"); TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
...@@ -2033,6 +2040,8 @@ void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node) ...@@ -2033,6 +2040,8 @@ void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node)
bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{ {
mNestedLoopDepth++;
bool wasDiscontinuous = mInsideDiscontinuousLoop; bool wasDiscontinuous = mInsideDiscontinuousLoop;
if (mContainsLoopDiscontinuity && !mInsideDiscontinuousLoop) if (mContainsLoopDiscontinuity && !mInsideDiscontinuousLoop)
...@@ -2044,6 +2053,9 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -2044,6 +2053,9 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{ {
if (handleExcessiveLoop(node)) if (handleExcessiveLoop(node))
{ {
mInsideDiscontinuousLoop = wasDiscontinuous;
mNestedLoopDepth--;
return false; return false;
} }
} }
...@@ -2107,6 +2119,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -2107,6 +2119,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
out << "}\n"; out << "}\n";
mInsideDiscontinuousLoop = wasDiscontinuous; mInsideDiscontinuousLoop = wasDiscontinuous;
mNestedLoopDepth--;
return false; return false;
} }
...@@ -2123,6 +2136,11 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) ...@@ -2123,6 +2136,11 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
case EOpBreak: case EOpBreak:
if (visit == PreVisit) if (visit == PreVisit)
{ {
if (mNestedLoopDepth > 1)
{
mUsesNestedBreak = true;
}
if (mExcessiveLoopIndex) if (mExcessiveLoopIndex)
{ {
out << "{Break"; out << "{Break";
......
...@@ -127,6 +127,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -127,6 +127,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesAtan2_3; bool mUsesAtan2_3;
bool mUsesAtan2_4; bool mUsesAtan2_4;
bool mUsesDiscardRewriting; bool mUsesDiscardRewriting;
bool mUsesNestedBreak;
int mNumRenderTargets; int mNumRenderTargets;
...@@ -148,6 +149,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -148,6 +149,7 @@ class OutputHLSL : public TIntermTraverser
bool mContainsLoopDiscontinuity; bool mContainsLoopDiscontinuity;
bool mOutputLod0Function; bool mOutputLod0Function;
bool mInsideDiscontinuousLoop; bool mInsideDiscontinuousLoop;
int mNestedLoopDepth;
TIntermSymbol *mExcessiveLoopIndex; TIntermSymbol *mExcessiveLoopIndex;
......
...@@ -34,12 +34,27 @@ std::string str(int i) ...@@ -34,12 +34,27 @@ std::string str(int i)
return buffer; 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) : name(name), element(element), index(index)
{ {
} }
...@@ -1979,8 +1994,8 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin ...@@ -1979,8 +1994,8 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
if (success) if (success)
{ {
mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, DiscardWorkaround(vertexShader->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)); mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, DiscardWorkaround(fragmentShader->mUsesDiscardRewriting, fragmentShader->mUsesNestedBreak));
if (usesGeometryShader()) if (usesGeometryShader())
{ {
......
...@@ -308,6 +308,7 @@ void Shader::parseVaryings() ...@@ -308,6 +308,7 @@ void Shader::parseVaryings()
mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL; mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL;
mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL; mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
mUsesDiscardRewriting = strstr(mHlsl, "ANGLE_USES_DISCARD_REWRITING") != NULL; mUsesDiscardRewriting = strstr(mHlsl, "ANGLE_USES_DISCARD_REWRITING") != NULL;
mUsesNestedBreak = strstr(mHlsl, "ANGLE_USES_NESTED_BREAK") != NULL;
} }
} }
...@@ -342,6 +343,7 @@ void Shader::uncompile() ...@@ -342,6 +343,7 @@ void Shader::uncompile()
mUsesDepthRange = false; mUsesDepthRange = false;
mUsesFragDepth = false; mUsesFragDepth = false;
mUsesDiscardRewriting = false; mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
mActiveUniforms.clear(); mActiveUniforms.clear();
} }
......
...@@ -108,6 +108,7 @@ class Shader ...@@ -108,6 +108,7 @@ class Shader
bool mUsesDepthRange; bool mUsesDepthRange;
bool mUsesFragDepth; bool mUsesFragDepth;
bool mUsesDiscardRewriting; bool mUsesDiscardRewriting;
bool mUsesNestedBreak;
static void *mFragmentCompiler; static void *mFragmentCompiler;
static void *mVertexCompiler; static void *mVertexCompiler;
......
...@@ -14,7 +14,9 @@ ...@@ -14,7 +14,9 @@
#include "libGLESv2/angletypes.h" #include "libGLESv2/angletypes.h"
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #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 #endif
const int versionWindowsVista = MAKEWORD(0x00, 0x06); const int versionWindowsVista = MAKEWORD(0x00, 0x06);
...@@ -96,7 +98,8 @@ enum ShaderType ...@@ -96,7 +98,8 @@ enum ShaderType
enum D3DWorkaroundType enum D3DWorkaroundType
{ {
ANGLE_D3D_WORKAROUND_NONE, ANGLE_D3D_WORKAROUND_NONE,
ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION,
ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION
}; };
class Renderer class Renderer
......
...@@ -3169,9 +3169,17 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha ...@@ -3169,9 +3169,17 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
return NULL; return NULL;
} }
// ANGLE issue 486: UINT optimizationFlags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
// 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); 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); ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true);
if (!binary) 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