1 //
2 // Copyright 2020 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 // FlagSamplersForTexelFetch.cpp: finds all instances of texelFetch used with a static reference to
7 // a sampler uniform, and flag that uniform as having been used with texelFetch
8 //
9 
10 #include "compiler/translator/tree_ops/vulkan/FlagSamplersWithTexelFetch.h"
11 
12 #include "angle_gl.h"
13 #include "common/utilities.h"
14 
15 #include "compiler/translator/SymbolTable.h"
16 #include "compiler/translator/tree_util/IntermNode_util.h"
17 #include "compiler/translator/tree_util/IntermTraverse.h"
18 #include "compiler/translator/tree_util/ReplaceVariable.h"
19 
20 namespace sh
21 {
22 namespace
23 {
24 
25 class FlagSamplersWithTexelFetchTraverser : public TIntermTraverser
26 {
27   public:
FlagSamplersWithTexelFetchTraverser(TSymbolTable * symbolTable,std::vector<ShaderVariable> * uniforms)28     FlagSamplersWithTexelFetchTraverser(TSymbolTable *symbolTable,
29                                         std::vector<ShaderVariable> *uniforms)
30         : TIntermTraverser(true, true, true, symbolTable), mUniforms(uniforms)
31     {}
32 
visitAggregate(Visit visit,TIntermAggregate * node)33     bool visitAggregate(Visit visit, TIntermAggregate *node) override
34     {
35         // Decide if the node is a call to texelFetch[Offset]
36         if (!BuiltInGroup::IsBuiltIn(node->getOp()))
37         {
38             return true;
39         }
40 
41         ASSERT(node->getFunction()->symbolType() == SymbolType::BuiltIn);
42         if (node->getFunction()->name() != "texelFetch" &&
43             node->getFunction()->name() != "texelFetchOffset")
44         {
45             return true;
46         }
47 
48         const TIntermSequence *sequence = node->getSequence();
49 
50         ASSERT(sequence->size() > 0);
51 
52         TIntermSymbol *samplerSymbol = sequence->at(0)->getAsSymbolNode();
53         ASSERT(samplerSymbol != nullptr);
54 
55         const TVariable &samplerVariable = samplerSymbol->variable();
56 
57         for (ShaderVariable &uniform : *mUniforms)
58         {
59             if (samplerVariable.name() == uniform.name)
60             {
61                 ASSERT(gl::IsSamplerType(uniform.type));
62                 uniform.texelFetchStaticUse = true;
63                 break;
64             }
65         }
66 
67         return true;
68     }
69 
70   private:
71     std::vector<ShaderVariable> *mUniforms;
72 };
73 
74 }  // anonymous namespace
75 
FlagSamplersForTexelFetch(TCompiler * compiler,TIntermBlock * root,TSymbolTable * symbolTable,std::vector<ShaderVariable> * uniforms)76 bool FlagSamplersForTexelFetch(TCompiler *compiler,
77                                TIntermBlock *root,
78                                TSymbolTable *symbolTable,
79                                std::vector<ShaderVariable> *uniforms)
80 {
81     ASSERT(uniforms != nullptr);
82     if (uniforms->size() > 0)
83     {
84         FlagSamplersWithTexelFetchTraverser traverser(symbolTable, uniforms);
85         root->traverse(&traverser);
86     }
87 
88     return true;
89 }
90 
91 }  // namespace sh
92