Commit 87cc90df by Olli Etuaho Committed by Commit Bot

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/822413Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 495162b9
...@@ -602,7 +602,10 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root, ...@@ -602,7 +602,10 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
bool initializeLocalsAndGlobals = bool initializeLocalsAndGlobals =
(compileOptions & SH_INITIALIZE_UNINITIALIZED_LOCALS) && !IsOutputHLSL(getOutputType()); (compileOptions & SH_INITIALIZE_UNINITIALIZED_LOCALS) && !IsOutputHLSL(getOutputType());
bool canUseLoopsToInitialize = !(compileOptions & SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES); 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) if (initializeLocalsAndGlobals)
{ {
...@@ -623,7 +626,7 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root, ...@@ -623,7 +626,7 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
} }
InitializeUninitializedLocals(root, getShaderVersion(), canUseLoopsToInitialize, InitializeUninitializedLocals(root, getShaderVersion(), canUseLoopsToInitialize,
&getSymbolTable()); highPrecisionSupported, &getSymbolTable());
} }
if (getShaderType() == GL_VERTEX_SHADER && (compileOptions & SH_CLAMP_POINT_SIZE)) if (getShaderType() == GL_VERTEX_SHADER && (compileOptions & SH_CLAMP_POINT_SIZE))
...@@ -1067,7 +1070,7 @@ void TCompiler::initializeGLPosition(TIntermBlock *root) ...@@ -1067,7 +1070,7 @@ void TCompiler::initializeGLPosition(TIntermBlock *root)
sh::ShaderVariable var(GL_FLOAT_VEC4); sh::ShaderVariable var(GL_FLOAT_VEC4);
var.name = "gl_Position"; var.name = "gl_Position";
list.push_back(var); list.push_back(var);
InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false); InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false, false);
} }
void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root) void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
...@@ -1109,7 +1112,7 @@ void TCompiler::initializeOutputVariables(TIntermBlock *root) ...@@ -1109,7 +1112,7 @@ void TCompiler::initializeOutputVariables(TIntermBlock *root)
list.push_back(var); list.push_back(var);
} }
} }
InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false); InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false, false);
} }
const TExtensionBehavior &TCompiler::getExtensionBehavior() const const TExtensionBehavior &TCompiler::getExtensionBehavior() const
......
...@@ -30,6 +30,7 @@ namespace ...@@ -30,6 +30,7 @@ namespace
void GetDeferredInitializers(TIntermDeclaration *declaration, void GetDeferredInitializers(TIntermDeclaration *declaration,
bool initializeUninitializedGlobals, bool initializeUninitializedGlobals,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TIntermSequence *deferredInitializersOut, TIntermSequence *deferredInitializersOut,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
...@@ -83,8 +84,8 @@ void GetDeferredInitializers(TIntermDeclaration *declaration, ...@@ -83,8 +84,8 @@ void GetDeferredInitializers(TIntermDeclaration *declaration,
if (symbolNode->getQualifier() == EvqGlobal && symbolNode->getSymbol() != "") if (symbolNode->getQualifier() == EvqGlobal && symbolNode->getSymbol() != "")
{ {
TIntermSequence *initCode = TIntermSequence *initCode = CreateInitCode(symbolNode, canUseLoopsToInitialize,
CreateInitCode(symbolNode, canUseLoopsToInitialize, symbolTable); highPrecisionSupported, symbolTable);
deferredInitializersOut->insert(deferredInitializersOut->end(), initCode->begin(), deferredInitializersOut->insert(deferredInitializersOut->end(), initCode->begin(),
initCode->end()); initCode->end());
} }
...@@ -121,6 +122,7 @@ void InsertInitCallToMain(TIntermBlock *root, ...@@ -121,6 +122,7 @@ void InsertInitCallToMain(TIntermBlock *root,
void DeferGlobalInitializers(TIntermBlock *root, void DeferGlobalInitializers(TIntermBlock *root,
bool initializeUninitializedGlobals, bool initializeUninitializedGlobals,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
TIntermSequence *deferredInitializers = new TIntermSequence(); TIntermSequence *deferredInitializers = new TIntermSequence();
...@@ -133,7 +135,8 @@ void DeferGlobalInitializers(TIntermBlock *root, ...@@ -133,7 +135,8 @@ void DeferGlobalInitializers(TIntermBlock *root,
if (declaration) if (declaration)
{ {
GetDeferredInitializers(declaration, initializeUninitializedGlobals, GetDeferredInitializers(declaration, initializeUninitializedGlobals,
canUseLoopsToInitialize, deferredInitializers, symbolTable); canUseLoopsToInitialize, highPrecisionSupported,
deferredInitializers, symbolTable);
} }
} }
......
...@@ -25,6 +25,7 @@ class TSymbolTable; ...@@ -25,6 +25,7 @@ class TSymbolTable;
void DeferGlobalInitializers(TIntermBlock *root, void DeferGlobalInitializers(TIntermBlock *root,
bool initializeUninitializedGlobals, bool initializeUninitializedGlobals,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TSymbolTable *symbolTable); TSymbolTable *symbolTable);
} // namespace sh } // namespace sh
......
...@@ -22,11 +22,13 @@ namespace ...@@ -22,11 +22,13 @@ namespace
void AddArrayZeroInitSequence(const TIntermTyped *initializedNode, void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TIntermSequence *initSequenceOut, TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable); TSymbolTable *symbolTable);
void AddStructZeroInitSequence(const TIntermTyped *initializedNode, void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TIntermSequence *initSequenceOut, TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable); TSymbolTable *symbolTable);
...@@ -38,19 +40,20 @@ TIntermBinary *CreateZeroInitAssignment(const TIntermTyped *initializedNode) ...@@ -38,19 +40,20 @@ TIntermBinary *CreateZeroInitAssignment(const TIntermTyped *initializedNode)
void AddZeroInitSequence(const TIntermTyped *initializedNode, void AddZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TIntermSequence *initSequenceOut, TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
if (initializedNode->isArray()) if (initializedNode->isArray())
{ {
AddArrayZeroInitSequence(initializedNode, canUseLoopsToInitialize, initSequenceOut, AddArrayZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
symbolTable); initSequenceOut, symbolTable);
} }
else if (initializedNode->getType().isStructureContainingArrays() || else if (initializedNode->getType().isStructureContainingArrays() ||
initializedNode->getType().isNamelessStruct()) initializedNode->getType().isNamelessStruct())
{ {
AddStructZeroInitSequence(initializedNode, canUseLoopsToInitialize, initSequenceOut, AddStructZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
symbolTable); initSequenceOut, symbolTable);
} }
else else
{ {
...@@ -60,6 +63,7 @@ void AddZeroInitSequence(const TIntermTyped *initializedNode, ...@@ -60,6 +63,7 @@ void AddZeroInitSequence(const TIntermTyped *initializedNode,
void AddStructZeroInitSequence(const TIntermTyped *initializedNode, void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TIntermSequence *initSequenceOut, TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
...@@ -72,12 +76,14 @@ void AddStructZeroInitSequence(const TIntermTyped *initializedNode, ...@@ -72,12 +76,14 @@ void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
// Structs can't be defined inside structs, so the type of a struct field can't be a // Structs can't be defined inside structs, so the type of a struct field can't be a
// nameless struct. // nameless struct.
ASSERT(!element->getType().isNamelessStruct()); ASSERT(!element->getType().isNamelessStruct());
AddZeroInitSequence(element, canUseLoopsToInitialize, initSequenceOut, symbolTable); AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
initSequenceOut, symbolTable);
} }
} }
void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode, void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TIntermSequence *initSequenceOut, TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
...@@ -85,20 +91,24 @@ void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode, ...@@ -85,20 +91,24 @@ void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode,
{ {
TIntermBinary *element = TIntermBinary *element =
new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i)); new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i));
AddZeroInitSequence(element, canUseLoopsToInitialize, initSequenceOut, symbolTable); AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
initSequenceOut, symbolTable);
} }
} }
void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode, void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
bool highPrecisionSupported,
TIntermSequence *initSequenceOut, TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
ASSERT(initializedNode->isArray()); ASSERT(initializedNode->isArray());
TSymbolUniqueId indexSymbol(symbolTable); TSymbolUniqueId indexSymbol(symbolTable);
TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexSymbol, TType(EbtInt), EvqTemporary); TType indexType(EbtInt, highPrecisionSupported ? EbpHigh : EbpMedium);
TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexSymbol, indexType, EvqTemporary);
TIntermDeclaration *indexInit = TIntermDeclaration *indexInit =
CreateTempInitDeclarationNode(indexSymbol, CreateZeroNode(TType(EbtInt)), EvqTemporary); CreateTempInitDeclarationNode(indexSymbol, CreateZeroNode(indexType), EvqTemporary);
TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize()); TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize());
TIntermBinary *indexSmallerThanSize = TIntermBinary *indexSmallerThanSize =
new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode); new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
...@@ -109,7 +119,7 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode, ...@@ -109,7 +119,7 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
TIntermBinary *element = new TIntermBinary(EOpIndexIndirect, initializedNode->deepCopy(), TIntermBinary *element = new TIntermBinary(EOpIndexIndirect, initializedNode->deepCopy(),
indexSymbolNode->deepCopy()); indexSymbolNode->deepCopy());
AddZeroInitSequence(element, true, forLoopBodySeq, symbolTable); AddZeroInitSequence(element, true, highPrecisionSupported, forLoopBodySeq, symbolTable);
TIntermLoop *forLoop = TIntermLoop *forLoop =
new TIntermLoop(ELoopFor, indexInit, indexSmallerThanSize, indexIncrement, forLoopBody); new TIntermLoop(ELoopFor, indexInit, indexSmallerThanSize, indexIncrement, forLoopBody);
...@@ -118,6 +128,7 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode, ...@@ -118,6 +128,7 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
void AddArrayZeroInitSequence(const TIntermTyped *initializedNode, void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TIntermSequence *initSequenceOut, TIntermSequence *initSequenceOut,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
...@@ -135,12 +146,13 @@ void AddArrayZeroInitSequence(const TIntermTyped *initializedNode, ...@@ -135,12 +146,13 @@ void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
{ {
// Fragment outputs should not be indexed by non-constant indices. // Fragment outputs should not be indexed by non-constant indices.
// Also it doesn't make sense to use loops to initialize very small arrays. // Also it doesn't make sense to use loops to initialize very small arrays.
AddArrayZeroInitStatementList(initializedNode, canUseLoopsToInitialize, initSequenceOut, AddArrayZeroInitStatementList(initializedNode, canUseLoopsToInitialize,
symbolTable); highPrecisionSupported, initSequenceOut, symbolTable);
} }
else else
{ {
AddArrayZeroInitForLoop(initializedNode, initSequenceOut, symbolTable); AddArrayZeroInitForLoop(initializedNode, highPrecisionSupported, initSequenceOut,
symbolTable);
} }
} }
...@@ -149,7 +161,8 @@ void InsertInitCode(TIntermSequence *mainBody, ...@@ -149,7 +161,8 @@ void InsertInitCode(TIntermSequence *mainBody,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
int shaderVersion, int shaderVersion,
const TExtensionBehavior &extensionBehavior, const TExtensionBehavior &extensionBehavior,
bool canUseLoopsToInitialize) bool canUseLoopsToInitialize,
bool highPrecisionSupported)
{ {
for (const auto &var : variables) for (const auto &var : variables)
{ {
...@@ -183,8 +196,8 @@ void InsertInitCode(TIntermSequence *mainBody, ...@@ -183,8 +196,8 @@ void InsertInitCode(TIntermSequence *mainBody,
} }
ASSERT(initializedSymbol != nullptr); ASSERT(initializedSymbol != nullptr);
TIntermSequence *initCode = TIntermSequence *initCode = CreateInitCode(initializedSymbol, canUseLoopsToInitialize,
CreateInitCode(initializedSymbol, canUseLoopsToInitialize, symbolTable); highPrecisionSupported, symbolTable);
mainBody->insert(mainBody->begin(), initCode->begin(), initCode->end()); mainBody->insert(mainBody->begin(), initCode->begin(), initCode->end());
} }
} }
...@@ -194,10 +207,12 @@ class InitializeLocalsTraverser : public TIntermTraverser ...@@ -194,10 +207,12 @@ class InitializeLocalsTraverser : public TIntermTraverser
public: public:
InitializeLocalsTraverser(int shaderVersion, InitializeLocalsTraverser(int shaderVersion,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
bool canUseLoopsToInitialize) bool canUseLoopsToInitialize,
bool highPrecisionSupported)
: TIntermTraverser(true, false, false, symbolTable), : TIntermTraverser(true, false, false, symbolTable),
mShaderVersion(shaderVersion), mShaderVersion(shaderVersion),
mCanUseLoopsToInitialize(canUseLoopsToInitialize) mCanUseLoopsToInitialize(canUseLoopsToInitialize),
mHighPrecisionSupported(highPrecisionSupported)
{ {
} }
...@@ -235,8 +250,8 @@ class InitializeLocalsTraverser : public TIntermTraverser ...@@ -235,8 +250,8 @@ class InitializeLocalsTraverser : public TIntermTraverser
// this declarator. // this declarator.
ASSERT(node->getSequence()->size() == 1); ASSERT(node->getSequence()->size() == 1);
insertStatementsInParentBlock( insertStatementsInParentBlock(
TIntermSequence(), TIntermSequence(), *CreateInitCode(symbol, mCanUseLoopsToInitialize,
*CreateInitCode(symbol, mCanUseLoopsToInitialize, mSymbolTable)); mHighPrecisionSupported, mSymbolTable));
} }
else else
{ {
...@@ -252,25 +267,30 @@ class InitializeLocalsTraverser : public TIntermTraverser ...@@ -252,25 +267,30 @@ class InitializeLocalsTraverser : public TIntermTraverser
private: private:
int mShaderVersion; int mShaderVersion;
bool mCanUseLoopsToInitialize; bool mCanUseLoopsToInitialize;
bool mHighPrecisionSupported;
}; };
} // namespace anonymous } // namespace anonymous
TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol, TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
TIntermSequence *initCode = new TIntermSequence(); TIntermSequence *initCode = new TIntermSequence();
AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, initCode, symbolTable); AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
initCode, symbolTable);
return initCode; return initCode;
} }
void InitializeUninitializedLocals(TIntermBlock *root, void InitializeUninitializedLocals(TIntermBlock *root,
int shaderVersion, int shaderVersion,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize); InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize,
highPrecisionSupported);
root->traverse(&traverser); root->traverse(&traverser);
traverser.updateTree(); traverser.updateTree();
} }
...@@ -280,11 +300,12 @@ void InitializeVariables(TIntermBlock *root, ...@@ -280,11 +300,12 @@ void InitializeVariables(TIntermBlock *root,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
int shaderVersion, int shaderVersion,
const TExtensionBehavior &extensionBehavior, const TExtensionBehavior &extensionBehavior,
bool canUseLoopsToInitialize) bool canUseLoopsToInitialize,
bool highPrecisionSupported)
{ {
TIntermBlock *body = FindMainBody(root); TIntermBlock *body = FindMainBody(root);
InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior, InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior,
canUseLoopsToInitialize); canUseLoopsToInitialize, highPrecisionSupported);
} }
} // namespace sh } // namespace sh
...@@ -25,12 +25,14 @@ typedef std::vector<sh::ShaderVariable> InitVariableList; ...@@ -25,12 +25,14 @@ typedef std::vector<sh::ShaderVariable> InitVariableList;
// may be an array, struct or any combination of these, as long as it contains only basic types. // may be an array, struct or any combination of these, as long as it contains only basic types.
TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol, TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TSymbolTable *symbolTable); TSymbolTable *symbolTable);
// Initialize all uninitialized local variables, so that undefined behavior is avoided. // Initialize all uninitialized local variables, so that undefined behavior is avoided.
void InitializeUninitializedLocals(TIntermBlock *root, void InitializeUninitializedLocals(TIntermBlock *root,
int shaderVersion, int shaderVersion,
bool canUseLoopsToInitialize, bool canUseLoopsToInitialize,
bool highPrecisionSupported,
TSymbolTable *symbolTable); TSymbolTable *symbolTable);
// This function can initialize all the types that CreateInitCode is able to initialize. All // This function can initialize all the types that CreateInitCode is able to initialize. All
...@@ -46,7 +48,8 @@ void InitializeVariables(TIntermBlock *root, ...@@ -46,7 +48,8 @@ void InitializeVariables(TIntermBlock *root,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
int shaderVersion, int shaderVersion,
const TExtensionBehavior &extensionBehavior, const TExtensionBehavior &extensionBehavior,
bool canUseLoopsToInitialize); bool canUseLoopsToInitialize,
bool highPrecisionSupported);
} // namespace sh } // namespace sh
......
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