Incorporated patch from haixia@ changing the default implementation of
array index clamping to use the clamp intrinsic. This works more
reliably on pure OpenGL ES devices and on Windows.
Added a mechanism in ShBuiltInResources to choose the strategy for
array index clamping.
BUG=none
TEST=various out-of-bounds array indexing tests and various WebGL content
Review URL: https://codereview.appspot.com/7194051
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1798 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 1e2c945..f555537 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -102,6 +102,7 @@
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type),
shaderSpec(spec),
+ clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
builtInFunctionEmulator(type)
{
longNameMap = LongNameMap::GetInstance();
@@ -125,6 +126,9 @@
return false;
InitExtensionBehavior(resources, extensionBehavior);
+ arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
+ clampingStrategy = resources.ArrayIndexClampingStrategy;
+
hashFunction = resources.HashFunction;
return true;
@@ -355,13 +359,17 @@
return extensionBehavior;
}
-const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
-{
- return builtInFunctionEmulator;
-}
-
const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
{
return arrayBoundsClamper;
}
+ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
+{
+ return clampingStrategy;
+}
+
+const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
+{
+ return builtInFunctionEmulator;
+}
diff --git a/src/compiler/OutputESSL.cpp b/src/compiler/OutputESSL.cpp
index 0331752..c2048f1 100644
--- a/src/compiler/OutputESSL.cpp
+++ b/src/compiler/OutputESSL.cpp
@@ -7,10 +7,11 @@
#include "compiler/OutputESSL.h"
TOutputESSL::TOutputESSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable)
- : TOutputGLSLBase(objSink, hashFunction, nameMap, symbolTable)
+ : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable)
{
}
diff --git a/src/compiler/OutputESSL.h b/src/compiler/OutputESSL.h
index dd8c5ab..05db96e 100644
--- a/src/compiler/OutputESSL.h
+++ b/src/compiler/OutputESSL.h
@@ -13,6 +13,7 @@
{
public:
TOutputESSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable);
diff --git a/src/compiler/OutputGLSL.cpp b/src/compiler/OutputGLSL.cpp
index 5873042..206f403 100644
--- a/src/compiler/OutputGLSL.cpp
+++ b/src/compiler/OutputGLSL.cpp
@@ -7,10 +7,11 @@
#include "compiler/OutputGLSL.h"
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable)
- : TOutputGLSLBase(objSink, hashFunction, nameMap, symbolTable)
+ : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable)
{
}
diff --git a/src/compiler/OutputGLSL.h b/src/compiler/OutputGLSL.h
index 9030212..199b6f3 100644
--- a/src/compiler/OutputGLSL.h
+++ b/src/compiler/OutputGLSL.h
@@ -13,6 +13,7 @@
{
public:
TOutputGLSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable);
diff --git a/src/compiler/OutputGLSLBase.cpp b/src/compiler/OutputGLSLBase.cpp
index 06eae13..45fabed 100644
--- a/src/compiler/OutputGLSLBase.cpp
+++ b/src/compiler/OutputGLSLBase.cpp
@@ -40,12 +40,14 @@
} // namespace
TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
mDeclaringVariables(false),
+ mClampingStrategy(clampingStrategy),
mHashFunction(hashFunction),
mNameMap(nameMap),
mSymbolTable(symbolTable)
@@ -221,7 +223,11 @@
{
if (visit == InVisit)
{
- out << "[webgl_int_clamp(";
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
+ out << "[int(clamp(float(";
+ } else {
+ out << "[webgl_int_clamp(";
+ }
}
else if (visit == PostVisit)
{
@@ -238,7 +244,12 @@
{
maxSize = leftType.getNominalSize() - 1;
}
- out << ", 0, " << maxSize << ")]";
+
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
+ out << "), 0.0, float(" << maxSize << ")))]";
+ } else {
+ out << ", 0, " << maxSize << ")]";
+ }
}
}
else
diff --git a/src/compiler/OutputGLSLBase.h b/src/compiler/OutputGLSLBase.h
index 01e9d4a..c9f72d5 100644
--- a/src/compiler/OutputGLSLBase.h
+++ b/src/compiler/OutputGLSLBase.h
@@ -17,6 +17,7 @@
{
public:
TOutputGLSLBase(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable);
@@ -62,8 +63,11 @@
ForLoopUnroll mLoopUnroll;
+ ShArrayIndexClampingStrategy mClampingStrategy;
+
// name hashing.
ShHashFunction64 mHashFunction;
+
NameMap& mNameMap;
TSymbolTable& mSymbolTable;
diff --git a/src/compiler/ShHandle.h b/src/compiler/ShHandle.h
index a50be62..274f792 100644
--- a/src/compiler/ShHandle.h
+++ b/src/compiler/ShHandle.h
@@ -110,6 +110,7 @@
const TExtensionBehavior& getExtensionBehavior() const;
const ArrayBoundsClamper& getArrayBoundsClamper() const;
+ ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
private:
@@ -125,6 +126,7 @@
TExtensionBehavior extensionBehavior;
ArrayBoundsClamper arrayBoundsClamper;
+ ShArrayIndexClampingStrategy clampingStrategy;
BuiltInFunctionEmulator builtInFunctionEmulator;
// Results of compilation.
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index a4a8f6c..8aed31b 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -129,6 +129,8 @@
// Disable name hashing by default.
resources->HashFunction = NULL;
+
+ resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
}
//
@@ -363,4 +365,4 @@
break;
default: UNREACHABLE();
}
-}
\ No newline at end of file
+}
diff --git a/src/compiler/TranslatorESSL.cpp b/src/compiler/TranslatorESSL.cpp
index a4f047a..2900f8a 100644
--- a/src/compiler/TranslatorESSL.cpp
+++ b/src/compiler/TranslatorESSL.cpp
@@ -26,7 +26,7 @@
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
// Write translated shader.
- TOutputESSL outputESSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
+ TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputESSL);
}
diff --git a/src/compiler/TranslatorGLSL.cpp b/src/compiler/TranslatorGLSL.cpp
index 5f3dbcc..7ca4341 100644
--- a/src/compiler/TranslatorGLSL.cpp
+++ b/src/compiler/TranslatorGLSL.cpp
@@ -39,6 +39,6 @@
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
// Write translated shader.
- TOutputGLSL outputGLSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
+ TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputGLSL);
}