Hash :
bb5a7e29
Author :
Date :
2017-08-30T13:03:12
Allow length() on arbitrary array expressions This is required to pass some dEQP GLES 3.1 tests for arrays of arrays, and WebGL conformance tests were also recently fixed to require this behavior. The intent of the GLSL ES spec was not to restrict usage of length(). In practice GL drivers don't implement array length() on expressions with side effects correctly in all cases. HLSL doesn't have an array length operator either. Because of this we always remove array length ops from the AST before output. BUG=angleproject:2142 TEST=angle_unittests, angle_end2end_tests, WebGL conformance tests Change-Id: I863a92e83ac5315b013af9a5626348482bad72b3 Reviewed-on: https://chromium-review.googlesource.com/643190 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
//
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IntermNodePatternMatcher is a helper class for matching node trees to given patterns.
// It can be used whenever the same checks for certain node structures are common to multiple AST
// traversers.
//
#ifndef COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_
#define COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_
namespace sh
{
class TIntermAggregate;
class TIntermBinary;
class TIntermDeclaration;
class TIntermNode;
class TIntermTernary;
class TIntermUnary;
class IntermNodePatternMatcher
{
public:
static bool IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node);
enum PatternType
{
// Matches expressions that are unfolded to if statements by UnfoldShortCircuitToIf
kUnfoldedShortCircuitExpression = 0x0001,
// Matches expressions that return arrays with the exception of simple statements where a
// constructor or function call result is assigned.
kExpressionReturningArray = 0x0001 << 1,
// Matches dynamic indexing of vectors or matrices in l-values.
kDynamicIndexingOfVectorOrMatrixInLValue = 0x0001 << 2,
// Matches declarations with more than one declared variables.
kMultiDeclaration = 0x0001 << 3,
// Matches declarations of arrays.
kArrayDeclaration = 0x0001 << 4,
// Matches declarations of structs where the struct type does not have a name.
kNamelessStructDeclaration = 0x0001 << 5,
// Matches array length() method.
kArrayLengthMethod = 0x0001 << 6
};
IntermNodePatternMatcher(const unsigned int mask);
bool match(TIntermUnary *node);
bool match(TIntermBinary *node, TIntermNode *parentNode);
// Use this version for checking binary node matches in case you're using flag
// kDynamicIndexingOfVectorOrMatrixInLValue.
bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere);
bool match(TIntermAggregate *node, TIntermNode *parentNode);
bool match(TIntermTernary *node);
bool match(TIntermDeclaration *node);
private:
const unsigned int mMask;
bool matchInternal(TIntermBinary *node, TIntermNode *parentNode);
};
} // namespace sh
#endif