~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// Copyright 2019 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
// RemoveInactiveInterfaceVariables.h:
 
7
//  Drop shader interface variable declarations for those that are inactive.
 
8
//
 
9
 
 
10
#include "compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h"
 
11
 
 
12
#include "compiler/translator/SymbolTable.h"
 
13
#include "compiler/translator/tree_util/IntermTraverse.h"
 
14
#include "compiler/translator/util.h"
 
15
 
 
16
namespace sh
 
17
{
 
18
 
 
19
namespace
 
20
{
 
21
 
 
22
// Traverser that removes all declarations that correspond to inactive variables.
 
23
class RemoveInactiveInterfaceVariablesTraverser : public TIntermTraverser
 
24
{
 
25
  public:
 
26
    RemoveInactiveInterfaceVariablesTraverser(
 
27
        const std::vector<sh::ShaderVariable> &attributes,
 
28
        const std::vector<sh::ShaderVariable> &inputVaryings,
 
29
        const std::vector<sh::ShaderVariable> &outputVariables,
 
30
        const std::vector<sh::ShaderVariable> &uniforms,
 
31
        const std::vector<sh::InterfaceBlock> &interfaceBlocks);
 
32
 
 
33
    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
 
34
 
 
35
  private:
 
36
    const std::vector<sh::ShaderVariable> &mAttributes;
 
37
    const std::vector<sh::ShaderVariable> &mInputVaryings;
 
38
    const std::vector<sh::ShaderVariable> &mOutputVariables;
 
39
    const std::vector<sh::ShaderVariable> &mUniforms;
 
40
    const std::vector<sh::InterfaceBlock> &mInterfaceBlocks;
 
41
};
 
42
 
 
43
RemoveInactiveInterfaceVariablesTraverser::RemoveInactiveInterfaceVariablesTraverser(
 
44
    const std::vector<sh::ShaderVariable> &attributes,
 
45
    const std::vector<sh::ShaderVariable> &inputVaryings,
 
46
    const std::vector<sh::ShaderVariable> &outputVariables,
 
47
    const std::vector<sh::ShaderVariable> &uniforms,
 
48
    const std::vector<sh::InterfaceBlock> &interfaceBlocks)
 
49
    : TIntermTraverser(true, false, false),
 
50
      mAttributes(attributes),
 
51
      mInputVaryings(inputVaryings),
 
52
      mOutputVariables(outputVariables),
 
53
      mUniforms(uniforms),
 
54
      mInterfaceBlocks(interfaceBlocks)
 
55
{}
 
56
 
 
57
template <typename Variable>
 
58
bool IsVariableActive(const std::vector<Variable> &mVars, const ImmutableString &name)
 
59
{
 
60
    for (const Variable &var : mVars)
 
61
    {
 
62
        if (name == var.name)
 
63
        {
 
64
            return var.active;
 
65
        }
 
66
    }
 
67
    UNREACHABLE();
 
68
    return true;
 
69
}
 
70
 
 
71
bool RemoveInactiveInterfaceVariablesTraverser::visitDeclaration(Visit visit,
 
72
                                                                 TIntermDeclaration *node)
 
73
{
 
74
    // SeparateDeclarations should have already been run.
 
75
    ASSERT(node->getSequence()->size() == 1u);
 
76
 
 
77
    TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
 
78
    ASSERT(declarator);
 
79
 
 
80
    TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
 
81
    if (!asSymbol)
 
82
    {
 
83
        return false;
 
84
    }
 
85
 
 
86
    const TType &type = declarator->getType();
 
87
 
 
88
    // Remove all shader interface variables except outputs, i.e. uniforms, interface blocks and
 
89
    // inputs.
 
90
    //
 
91
    // Imagine a situation where the VS doesn't write to a varying but the FS reads from it.  This
 
92
    // is allowed, though the value of the varying is undefined.  If the varying is removed here,
 
93
    // the situation is changed to VS not declaring the varying, but the FS reading from it, which
 
94
    // is not allowed.  That's why inactive shader outputs are not removed.
 
95
    //
 
96
    // Inactive fragment shader outputs can be removed though, as there is no next stage.
 
97
    bool removeDeclaration     = false;
 
98
    const TQualifier qualifier = type.getQualifier();
 
99
 
 
100
    if (type.isInterfaceBlock())
 
101
    {
 
102
        removeDeclaration = !IsVariableActive(mInterfaceBlocks, type.getInterfaceBlock()->name());
 
103
    }
 
104
    else if (qualifier == EvqUniform)
 
105
    {
 
106
        removeDeclaration = !IsVariableActive(mUniforms, asSymbol->getName());
 
107
    }
 
108
    else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
 
109
    {
 
110
        removeDeclaration = !IsVariableActive(mAttributes, asSymbol->getName());
 
111
    }
 
112
    else if (IsShaderIn(qualifier))
 
113
    {
 
114
        removeDeclaration = !IsVariableActive(mInputVaryings, asSymbol->getName());
 
115
    }
 
116
    else if (qualifier == EvqFragmentOut)
 
117
    {
 
118
        removeDeclaration = !IsVariableActive(mOutputVariables, asSymbol->getName());
 
119
    }
 
120
 
 
121
    if (removeDeclaration)
 
122
    {
 
123
        TIntermSequence emptySequence;
 
124
        mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node, emptySequence);
 
125
    }
 
126
 
 
127
    return false;
 
128
}
 
129
 
 
130
}  // namespace
 
131
 
 
132
bool RemoveInactiveInterfaceVariables(TCompiler *compiler,
 
133
                                      TIntermBlock *root,
 
134
                                      const std::vector<sh::ShaderVariable> &attributes,
 
135
                                      const std::vector<sh::ShaderVariable> &inputVaryings,
 
136
                                      const std::vector<sh::ShaderVariable> &outputVariables,
 
137
                                      const std::vector<sh::ShaderVariable> &uniforms,
 
138
                                      const std::vector<sh::InterfaceBlock> &interfaceBlocks)
 
139
{
 
140
    RemoveInactiveInterfaceVariablesTraverser traverser(attributes, inputVaryings, outputVariables,
 
141
                                                        uniforms, interfaceBlocks);
 
142
    root->traverse(&traverser);
 
143
    return traverser.updateTree(compiler, root);
 
144
}
 
145
 
 
146
}  // namespace sh