• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // ShaderCompileTreeTest.cpp:
7 //   Test that shader validation results in the correct compile status.
8 //
9 
10 #include "tests/test_utils/ShaderCompileTreeTest.h"
11 
12 #include "compiler/translator/glsl/TranslatorESSL.h"
13 #include "compiler/translator/tree_util/IntermTraverse.h"
14 
15 namespace sh
16 {
17 
18 namespace
19 {
20 
21 // Checks that the node traversed is a zero node. It can be made out of multiple constructors and
22 // constant union nodes as long as there's no arithmetic involved and all constants are zero.
23 class OnlyContainsZeroConstantsTraverser final : public TIntermTraverser
24 {
25   public:
OnlyContainsZeroConstantsTraverser()26     OnlyContainsZeroConstantsTraverser()
27         : TIntermTraverser(true, false, false), mOnlyContainsConstantZeros(true)
28     {}
29 
visitUnary(Visit,TIntermUnary * node)30     bool visitUnary(Visit, TIntermUnary *node) override
31     {
32         mOnlyContainsConstantZeros = false;
33         return false;
34     }
35 
visitBinary(Visit,TIntermBinary * node)36     bool visitBinary(Visit, TIntermBinary *node) override
37     {
38         mOnlyContainsConstantZeros = false;
39         return false;
40     }
41 
visitTernary(Visit,TIntermTernary * node)42     bool visitTernary(Visit, TIntermTernary *node) override
43     {
44         mOnlyContainsConstantZeros = false;
45         return false;
46     }
47 
visitSwizzle(Visit,TIntermSwizzle * node)48     bool visitSwizzle(Visit, TIntermSwizzle *node) override
49     {
50         mOnlyContainsConstantZeros = false;
51         return false;
52     }
53 
visitAggregate(Visit,TIntermAggregate * node)54     bool visitAggregate(Visit, TIntermAggregate *node) override
55     {
56         if (node->getOp() != EOpConstruct)
57         {
58             mOnlyContainsConstantZeros = false;
59             return false;
60         }
61         return true;
62     }
63 
visitSymbol(TIntermSymbol * node)64     void visitSymbol(TIntermSymbol *node) override { mOnlyContainsConstantZeros = false; }
65 
visitConstantUnion(TIntermConstantUnion * node)66     void visitConstantUnion(TIntermConstantUnion *node) override
67     {
68         if (!mOnlyContainsConstantZeros)
69         {
70             return;
71         }
72 
73         const TType &type = node->getType();
74         size_t objectSize = type.getObjectSize();
75         for (size_t i = 0u; i < objectSize && mOnlyContainsConstantZeros; ++i)
76         {
77             bool isZero = false;
78             switch (type.getBasicType())
79             {
80                 case EbtFloat:
81                     isZero = (node->getFConst(i) == 0.0f);
82                     break;
83                 case EbtInt:
84                     isZero = (node->getIConst(i) == 0);
85                     break;
86                 case EbtUInt:
87                     isZero = (node->getUConst(i) == 0u);
88                     break;
89                 case EbtBool:
90                     isZero = (node->getBConst(i) == false);
91                     break;
92                 default:
93                     // Cannot handle.
94                     break;
95             }
96             if (!isZero)
97             {
98                 mOnlyContainsConstantZeros = false;
99                 return;
100             }
101         }
102     }
103 
onlyContainsConstantZeros() const104     bool onlyContainsConstantZeros() const { return mOnlyContainsConstantZeros; }
105 
106   private:
107     bool mOnlyContainsConstantZeros;
108 };
109 
110 }  // anonymous namespace
111 
SetUp()112 void ShaderCompileTreeTest::SetUp()
113 {
114     mAllocator.push();
115     SetGlobalPoolAllocator(&mAllocator);
116 
117     ShBuiltInResources resources;
118     sh::InitBuiltInResources(&resources);
119 
120     initResources(&resources);
121 
122     mTranslator = new TranslatorESSL(getShaderType(), getShaderSpec());
123     ASSERT_TRUE(mTranslator->Init(resources));
124 }
125 
TearDown()126 void ShaderCompileTreeTest::TearDown()
127 {
128     delete mTranslator;
129 
130     SetGlobalPoolAllocator(nullptr);
131     mAllocator.pop();
132 }
133 
compile(const std::string & shaderString)134 bool ShaderCompileTreeTest::compile(const std::string &shaderString)
135 {
136     const char *shaderStrings[] = {shaderString.c_str()};
137     mASTRoot            = mTranslator->compileTreeForTesting(shaderStrings, 1, mCompileOptions);
138     TInfoSink &infoSink = mTranslator->getInfoSink();
139     mInfoLog            = infoSink.info.c_str();
140     return mASTRoot != nullptr;
141 }
142 
compileAssumeSuccess(const std::string & shaderString)143 void ShaderCompileTreeTest::compileAssumeSuccess(const std::string &shaderString)
144 {
145     if (!compile(shaderString))
146     {
147         FAIL() << "Shader compilation into ESSL failed, log:\n" << mInfoLog;
148     }
149 }
150 
hasWarning() const151 bool ShaderCompileTreeTest::hasWarning() const
152 {
153     return mInfoLog.find("WARNING: ") != std::string::npos;
154 }
155 
getUniforms() const156 const std::vector<sh::ShaderVariable> &ShaderCompileTreeTest::getUniforms() const
157 {
158     return mTranslator->getUniforms();
159 }
160 
getAttributes() const161 const std::vector<sh::ShaderVariable> &ShaderCompileTreeTest::getAttributes() const
162 {
163     return mTranslator->getAttributes();
164 }
165 
IsZero(TIntermNode * node)166 bool IsZero(TIntermNode *node)
167 {
168     if (!node->getAsTyped())
169     {
170         return false;
171     }
172     OnlyContainsZeroConstantsTraverser traverser;
173     node->traverse(&traverser);
174     return traverser.onlyContainsConstantZeros();
175 }
176 
177 }  // namespace sh
178