Commit 96a387f8 by Geoff Lang Committed by Commit Bot

Disable loop unrolling when encounting errors about invalid array indices.

Zero-sized loops or loops that might never be executed may be unrolled into constant array accesses that are invalid, generating HLSL compiler errors. This issue showed up with the passthrough command decoder because it only does a single compilation step of WebGL shader -> HLSL instead of the validating decoder which does WebGL shader -> ESSL -> HLSL and eliminates these zero- sized loops in the process. BUG=angleproject:3269 Change-Id: Iaa14149c542f23a6da58c90cf6de51f4df7e27d6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1524696Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent e41882aa
...@@ -258,22 +258,43 @@ angle::Result HLSLCompiler::compileToBinary(d3d::Context *context, ...@@ -258,22 +258,43 @@ angle::Result HLSLCompiler::compileToBinary(d3d::Context *context,
WARN() << std::endl << message; WARN() << std::endl << message;
if ((message.find("error X3531:") != if (macros != nullptr)
std::string::npos || // "can't unroll loops marked with loop attribute"
message.find("error X4014:") !=
std::string::npos) && // "cannot have gradient operations inside loops with
// divergent flow control", even though it is
// counter-intuitive to disable unrolling for this
// error, some very long shaders have trouble deciding
// which loops to unroll and turning off forced unrolls
// allows them to compile properly.
macros != nullptr)
{ {
macros = nullptr; // Disable [loop] and [flatten] constexpr const char *kLoopRelatedErrors[] = {
// "can't unroll loops marked with loop attribute"
"error X3531:",
// "cannot have gradient operations inside loops with divergent flow control",
// even though it is counter-intuitive to disable unrolling for this error, some
// very long shaders have trouble deciding which loops to unroll and turning off
// forced unrolls allows them to compile properly.
"error X4014:",
// "array index out of bounds", loop unrolling can result in invalid array
// access if the indices become constant, causing loops that may never be
// executed to generate compilation errors
"error X3504:",
};
bool hasLoopRelatedError = false;
for (const char *errorType : kLoopRelatedErrors)
{
if (message.find(errorType) != std::string::npos)
{
hasLoopRelatedError = true;
break;
}
}
// Retry without changing compiler flags if (hasLoopRelatedError)
i--; {
continue; // Disable [loop] and [flatten]
macros = nullptr;
// Retry without changing compiler flags
i--;
continue;
}
} }
} }
......
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