Add work-around for D3D9 shader compiler bug.
With certain selection statements with a vertex input in the
condition and side-effects in the else-block, we'd run in to
a D3D9 compiler bug which would cause incorrect results.
We can work around this bug in D3D9 by selectively rewriting
these statements to use an 'else if' clause instead of 'else'.
BUG=322794
Change-Id: I93c96fb201ff4959c00d9a36321faac7e0343278
Reviewed-on: https://chromium-review.googlesource.com/184681
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index c25ca86..0a7b930 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -16,6 +16,7 @@
#include "compiler/translator/HLSLLayoutEncoder.h"
#include "compiler/translator/FlagStd140Structs.h"
#include "compiler/translator/NodeSearch.h"
+#include "compiler/translator/RewriteElseBlocks.h"
#include <algorithm>
#include <cfloat>
@@ -23,16 +24,6 @@
namespace sh
{
-// Integer to TString conversion
-template <typename T>
-TString str(T i)
-{
- ASSERT(std::numeric_limits<T>::is_integer);
- char buffer[(CHAR_BIT * sizeof(T) / 3) + 3];
- const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";
- snprintf(buffer, sizeof(buffer), formatStr, i);
- return buffer;
-}
TString OutputHLSL::TextureFunction::name() const
{
@@ -173,6 +164,13 @@
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
makeFlaggedStructMaps(flaggedStructs);
+ // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
+ // use a vertex attribute as a condition, and some related computation in the else block.
+ if (mOutputType == SH_HLSL9_OUTPUT && mContext.shaderType == SH_VERTEX_SHADER)
+ {
+ RewriteElseBlocks(mContext.treeRoot);
+ }
+
mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header
header();
@@ -1674,6 +1672,10 @@
mUsesFragDepth = true;
out << "gl_Depth";
}
+ else if (qualifier == EvqInternal)
+ {
+ out << name;
+ }
else
{
out << decorate(name);