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