Commit 5e0c80ad by Nicolas Capens

Use attributes to avoid unrolling and flatten conditionals.

[loop] and [flatten] help avoid unrolling make more shaders compile successfully. When unrolling has to happen, an error X3531 is generated so we have to try compiling again without these attributes. BUG=395048,395286 Change-Id: I91ea8ac3a822ab1f1ac24907d42326e3c6c9d9af Reviewed-on: https://chromium-review.googlesource.com/222810Tested-by: 's avatarNicolas Capens <capn@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 24d4a3c1
...@@ -320,14 +320,22 @@ void OutputHLSL::header() ...@@ -320,14 +320,22 @@ void OutputHLSL::header()
if (mUsesDiscardRewriting) if (mUsesDiscardRewriting)
{ {
out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n"; out << "#define ANGLE_USES_DISCARD_REWRITING\n";
} }
if (mUsesNestedBreak) if (mUsesNestedBreak)
{ {
out << "#define ANGLE_USES_NESTED_BREAK" << "\n"; out << "#define ANGLE_USES_NESTED_BREAK\n";
} }
out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
"#define LOOP [loop]\n"
"#define FLATTEN [flatten]\n"
"#else\n"
"#define LOOP\n"
"#define FLATTEN\n"
"#endif\n";
if (mContext.shaderType == GL_FRAGMENT_SHADER) if (mContext.shaderType == GL_FRAGMENT_SHADER)
{ {
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers"); TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
...@@ -2293,7 +2301,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) ...@@ -2293,7 +2301,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
{ {
mUnfoldShortCircuit->traverse(node->getCondition()); mUnfoldShortCircuit->traverse(node->getCondition());
out << "if ("; out << "FLATTEN if (";
node->getCondition()->traverse(this); node->getCondition()->traverse(this);
...@@ -2373,14 +2381,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -2373,14 +2381,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
if (node->getType() == ELoopDoWhile) if (node->getType() == ELoopDoWhile)
{ {
out << "{do\n"; out << "{LOOP do\n";
outputLineDirective(node->getLine().first_line); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
} }
else else
{ {
out << "{for("; out << "{LOOP for(";
if (node->getInit()) if (node->getInit())
{ {
...@@ -2687,7 +2695,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2687,7 +2695,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
// for(int index = initial; index < clampedLimit; index += increment) // for(int index = initial; index < clampedLimit; index += increment)
out << "for("; out << "LOOP for(";
index->traverse(this); index->traverse(this);
out << " = "; out << " = ";
out << initial; out << initial;
......
...@@ -83,7 +83,8 @@ void HLSLCompiler::release() ...@@ -83,7 +83,8 @@ void HLSLCompiler::release()
} }
gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile, gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs, ID3DBlob **outCompiledBlob) const const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
ID3DBlob **outCompiledBlob) const
{ {
ASSERT(mD3DCompilerModule && mD3DCompileFunc); ASSERT(mD3DCompilerModule && mD3DCompileFunc);
...@@ -94,23 +95,33 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string ...@@ -94,23 +95,33 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
} }
const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : NULL;
for (size_t i = 0; i < configs.size(); ++i) for (size_t i = 0; i < configs.size(); ++i)
{ {
ID3DBlob *errorMessage = NULL; ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL; ID3DBlob *binary = NULL;
HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, NULL, NULL, "main", profile.c_str(), HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, NULL, "main", profile.c_str(),
configs[i].flags, 0, &binary, &errorMessage); configs[i].flags, 0, &binary, &errorMessage);
if (errorMessage) if (errorMessage)
{ {
const char *message = (const char*)errorMessage->GetBufferPointer(); std::string message = (const char*)errorMessage->GetBufferPointer();
SafeRelease(errorMessage);
infoLog.appendSanitized(message); infoLog.appendSanitized(message.c_str());
TRACE("\n%s", hlsl); TRACE("\n%s", hlsl);
TRACE("\n%s", message); TRACE("\n%s", message);
SafeRelease(errorMessage); if (message.find("error X3531:") != std::string::npos) // "can't unroll loops marked with loop attribute"
{
macros = NULL; // Disable [loop] and [flatten]
// Retry without changing compiler flags
i--;
continue;
}
} }
if (SUCCEEDED(result)) if (SUCCEEDED(result))
......
...@@ -38,7 +38,8 @@ class HLSLCompiler ...@@ -38,7 +38,8 @@ class HLSLCompiler
// Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob // Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob
// even if no GL errors are returned. // even if no GL errors are returned.
gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile, gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs, ID3DBlob **outCompiledBlob) const; const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
ID3DBlob **outCompiledBlob) const;
private: private:
DISALLOW_COPY_AND_ASSIGN(HLSLCompiler); DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);
......
...@@ -2404,7 +2404,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin ...@@ -2404,7 +2404,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0; UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
if (gl::perfActive()) if (gl::perfActive())
{ {
...@@ -2422,8 +2422,10 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin ...@@ -2422,8 +2422,10 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" )); configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" ));
configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization")); configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization"));
D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} };
ID3DBlob *binary = NULL; ID3DBlob *binary = NULL;
gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, &binary); gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -2927,7 +2927,7 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string ...@@ -2927,7 +2927,7 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string
configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control")); configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control"));
ID3DBlob *binary = NULL; ID3DBlob *binary = NULL;
gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, &binary); gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
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