Set proper precision on loop index for variable init
Previously the index variable was missing a precision. This may have
been behind loop-based init failing on some Android platforms.
BUG=chromium:735497
TEST=angle_unittests
Change-Id: I0307891dfb2edf6c52efd5b495f602b380263d65
Reviewed-on: https://chromium-review.googlesource.com/822413
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index abb60cc..e4559aa 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -602,7 +602,10 @@
bool initializeLocalsAndGlobals =
(compileOptions & SH_INITIALIZE_UNINITIALIZED_LOCALS) && !IsOutputHLSL(getOutputType());
bool canUseLoopsToInitialize = !(compileOptions & SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES);
- DeferGlobalInitializers(root, initializeLocalsAndGlobals, canUseLoopsToInitialize, &symbolTable);
+ bool highPrecisionSupported =
+ shaderType != GL_FRAGMENT_SHADER || compileResources.FragmentPrecisionHigh;
+ DeferGlobalInitializers(root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
+ highPrecisionSupported, &symbolTable);
if (initializeLocalsAndGlobals)
{
@@ -623,7 +626,7 @@
}
InitializeUninitializedLocals(root, getShaderVersion(), canUseLoopsToInitialize,
- &getSymbolTable());
+ highPrecisionSupported, &getSymbolTable());
}
if (getShaderType() == GL_VERTEX_SHADER && (compileOptions & SH_CLAMP_POINT_SIZE))
@@ -1067,7 +1070,7 @@
sh::ShaderVariable var(GL_FLOAT_VEC4);
var.name = "gl_Position";
list.push_back(var);
- InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false);
+ InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false, false);
}
void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
@@ -1109,7 +1112,7 @@
list.push_back(var);
}
}
- InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false);
+ InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false, false);
}
const TExtensionBehavior &TCompiler::getExtensionBehavior() const
diff --git a/src/compiler/translator/DeferGlobalInitializers.cpp b/src/compiler/translator/DeferGlobalInitializers.cpp
index 67d51ea..1cef1a5 100644
--- a/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -30,6 +30,7 @@
void GetDeferredInitializers(TIntermDeclaration *declaration,
bool initializeUninitializedGlobals,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TIntermSequence *deferredInitializersOut,
TSymbolTable *symbolTable)
{
@@ -83,8 +84,8 @@
if (symbolNode->getQualifier() == EvqGlobal && symbolNode->getSymbol() != "")
{
- TIntermSequence *initCode =
- CreateInitCode(symbolNode, canUseLoopsToInitialize, symbolTable);
+ TIntermSequence *initCode = CreateInitCode(symbolNode, canUseLoopsToInitialize,
+ highPrecisionSupported, symbolTable);
deferredInitializersOut->insert(deferredInitializersOut->end(), initCode->begin(),
initCode->end());
}
@@ -121,6 +122,7 @@
void DeferGlobalInitializers(TIntermBlock *root,
bool initializeUninitializedGlobals,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TSymbolTable *symbolTable)
{
TIntermSequence *deferredInitializers = new TIntermSequence();
@@ -133,7 +135,8 @@
if (declaration)
{
GetDeferredInitializers(declaration, initializeUninitializedGlobals,
- canUseLoopsToInitialize, deferredInitializers, symbolTable);
+ canUseLoopsToInitialize, highPrecisionSupported,
+ deferredInitializers, symbolTable);
}
}
diff --git a/src/compiler/translator/DeferGlobalInitializers.h b/src/compiler/translator/DeferGlobalInitializers.h
index 86930a5..0ca2c4d 100644
--- a/src/compiler/translator/DeferGlobalInitializers.h
+++ b/src/compiler/translator/DeferGlobalInitializers.h
@@ -25,6 +25,7 @@
void DeferGlobalInitializers(TIntermBlock *root,
bool initializeUninitializedGlobals,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TSymbolTable *symbolTable);
} // namespace sh
diff --git a/src/compiler/translator/InitializeVariables.cpp b/src/compiler/translator/InitializeVariables.cpp
index aa1a042..86c3d23 100644
--- a/src/compiler/translator/InitializeVariables.cpp
+++ b/src/compiler/translator/InitializeVariables.cpp
@@ -22,11 +22,13 @@
void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable);
void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable);
@@ -38,19 +40,20 @@
void AddZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable)
{
if (initializedNode->isArray())
{
- AddArrayZeroInitSequence(initializedNode, canUseLoopsToInitialize, initSequenceOut,
- symbolTable);
+ AddArrayZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
}
else if (initializedNode->getType().isStructureContainingArrays() ||
initializedNode->getType().isNamelessStruct())
{
- AddStructZeroInitSequence(initializedNode, canUseLoopsToInitialize, initSequenceOut,
- symbolTable);
+ AddStructZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
}
else
{
@@ -60,6 +63,7 @@
void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable)
{
@@ -72,12 +76,14 @@
// Structs can't be defined inside structs, so the type of a struct field can't be a
// nameless struct.
ASSERT(!element->getType().isNamelessStruct());
- AddZeroInitSequence(element, canUseLoopsToInitialize, initSequenceOut, symbolTable);
+ AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
}
}
void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable)
{
@@ -85,20 +91,24 @@
{
TIntermBinary *element =
new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i));
- AddZeroInitSequence(element, canUseLoopsToInitialize, initSequenceOut, symbolTable);
+ AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
}
}
void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
+ bool highPrecisionSupported,
TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable)
{
ASSERT(initializedNode->isArray());
TSymbolUniqueId indexSymbol(symbolTable);
- TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexSymbol, TType(EbtInt), EvqTemporary);
+ TType indexType(EbtInt, highPrecisionSupported ? EbpHigh : EbpMedium);
+
+ TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexSymbol, indexType, EvqTemporary);
TIntermDeclaration *indexInit =
- CreateTempInitDeclarationNode(indexSymbol, CreateZeroNode(TType(EbtInt)), EvqTemporary);
+ CreateTempInitDeclarationNode(indexSymbol, CreateZeroNode(indexType), EvqTemporary);
TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize());
TIntermBinary *indexSmallerThanSize =
new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
@@ -109,7 +119,7 @@
TIntermBinary *element = new TIntermBinary(EOpIndexIndirect, initializedNode->deepCopy(),
indexSymbolNode->deepCopy());
- AddZeroInitSequence(element, true, forLoopBodySeq, symbolTable);
+ AddZeroInitSequence(element, true, highPrecisionSupported, forLoopBodySeq, symbolTable);
TIntermLoop *forLoop =
new TIntermLoop(ELoopFor, indexInit, indexSmallerThanSize, indexIncrement, forLoopBody);
@@ -118,6 +128,7 @@
void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable)
{
@@ -135,12 +146,13 @@
{
// Fragment outputs should not be indexed by non-constant indices.
// Also it doesn't make sense to use loops to initialize very small arrays.
- AddArrayZeroInitStatementList(initializedNode, canUseLoopsToInitialize, initSequenceOut,
- symbolTable);
+ AddArrayZeroInitStatementList(initializedNode, canUseLoopsToInitialize,
+ highPrecisionSupported, initSequenceOut, symbolTable);
}
else
{
- AddArrayZeroInitForLoop(initializedNode, initSequenceOut, symbolTable);
+ AddArrayZeroInitForLoop(initializedNode, highPrecisionSupported, initSequenceOut,
+ symbolTable);
}
}
@@ -149,7 +161,8 @@
TSymbolTable *symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior,
- bool canUseLoopsToInitialize)
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
{
for (const auto &var : variables)
{
@@ -183,8 +196,8 @@
}
ASSERT(initializedSymbol != nullptr);
- TIntermSequence *initCode =
- CreateInitCode(initializedSymbol, canUseLoopsToInitialize, symbolTable);
+ TIntermSequence *initCode = CreateInitCode(initializedSymbol, canUseLoopsToInitialize,
+ highPrecisionSupported, symbolTable);
mainBody->insert(mainBody->begin(), initCode->begin(), initCode->end());
}
}
@@ -194,10 +207,12 @@
public:
InitializeLocalsTraverser(int shaderVersion,
TSymbolTable *symbolTable,
- bool canUseLoopsToInitialize)
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
: TIntermTraverser(true, false, false, symbolTable),
mShaderVersion(shaderVersion),
- mCanUseLoopsToInitialize(canUseLoopsToInitialize)
+ mCanUseLoopsToInitialize(canUseLoopsToInitialize),
+ mHighPrecisionSupported(highPrecisionSupported)
{
}
@@ -235,8 +250,8 @@
// this declarator.
ASSERT(node->getSequence()->size() == 1);
insertStatementsInParentBlock(
- TIntermSequence(),
- *CreateInitCode(symbol, mCanUseLoopsToInitialize, mSymbolTable));
+ TIntermSequence(), *CreateInitCode(symbol, mCanUseLoopsToInitialize,
+ mHighPrecisionSupported, mSymbolTable));
}
else
{
@@ -252,25 +267,30 @@
private:
int mShaderVersion;
bool mCanUseLoopsToInitialize;
+ bool mHighPrecisionSupported;
};
} // namespace anonymous
TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TSymbolTable *symbolTable)
{
TIntermSequence *initCode = new TIntermSequence();
- AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, initCode, symbolTable);
+ AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
+ initCode, symbolTable);
return initCode;
}
void InitializeUninitializedLocals(TIntermBlock *root,
int shaderVersion,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TSymbolTable *symbolTable)
{
- InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize);
+ InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize,
+ highPrecisionSupported);
root->traverse(&traverser);
traverser.updateTree();
}
@@ -280,11 +300,12 @@
TSymbolTable *symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior,
- bool canUseLoopsToInitialize)
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
{
TIntermBlock *body = FindMainBody(root);
InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior,
- canUseLoopsToInitialize);
+ canUseLoopsToInitialize, highPrecisionSupported);
}
} // namespace sh
diff --git a/src/compiler/translator/InitializeVariables.h b/src/compiler/translator/InitializeVariables.h
index 1a7b3c0..f9a83f1 100644
--- a/src/compiler/translator/InitializeVariables.h
+++ b/src/compiler/translator/InitializeVariables.h
@@ -25,12 +25,14 @@
// may be an array, struct or any combination of these, as long as it contains only basic types.
TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TSymbolTable *symbolTable);
// Initialize all uninitialized local variables, so that undefined behavior is avoided.
void InitializeUninitializedLocals(TIntermBlock *root,
int shaderVersion,
bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
TSymbolTable *symbolTable);
// This function can initialize all the types that CreateInitCode is able to initialize. All
@@ -46,7 +48,8 @@
TSymbolTable *symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior,
- bool canUseLoopsToInitialize);
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported);
} // namespace sh