xref: /aosp_15_r20/external/angle/src/tests/test_utils/ShaderCompileTreeTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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