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.
6
// RemoveInactiveInterfaceVariables.h:
7
// Drop shader interface variable declarations for those that are inactive.
10
#include "compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h"
12
#include "compiler/translator/SymbolTable.h"
13
#include "compiler/translator/tree_util/IntermTraverse.h"
14
#include "compiler/translator/util.h"
22
// Traverser that removes all declarations that correspond to inactive variables.
23
class RemoveInactiveInterfaceVariablesTraverser : public TIntermTraverser
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);
33
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
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;
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),
54
mInterfaceBlocks(interfaceBlocks)
57
template <typename Variable>
58
bool IsVariableActive(const std::vector<Variable> &mVars, const ImmutableString &name)
60
for (const Variable &var : mVars)
71
bool RemoveInactiveInterfaceVariablesTraverser::visitDeclaration(Visit visit,
72
TIntermDeclaration *node)
74
// SeparateDeclarations should have already been run.
75
ASSERT(node->getSequence()->size() == 1u);
77
TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
80
TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
86
const TType &type = declarator->getType();
88
// Remove all shader interface variables except outputs, i.e. uniforms, interface blocks and
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.
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();
100
if (type.isInterfaceBlock())
102
removeDeclaration = !IsVariableActive(mInterfaceBlocks, type.getInterfaceBlock()->name());
104
else if (qualifier == EvqUniform)
106
removeDeclaration = !IsVariableActive(mUniforms, asSymbol->getName());
108
else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
110
removeDeclaration = !IsVariableActive(mAttributes, asSymbol->getName());
112
else if (IsShaderIn(qualifier))
114
removeDeclaration = !IsVariableActive(mInputVaryings, asSymbol->getName());
116
else if (qualifier == EvqFragmentOut)
118
removeDeclaration = !IsVariableActive(mOutputVariables, asSymbol->getName());
121
if (removeDeclaration)
123
TIntermSequence emptySequence;
124
mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node, emptySequence);
132
bool RemoveInactiveInterfaceVariables(TCompiler *compiler,
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)
140
RemoveInactiveInterfaceVariablesTraverser traverser(attributes, inputVaryings, outputVariables,
141
uniforms, interfaceBlocks);
142
root->traverse(&traverser);
143
return traverser.updateTree(compiler, root);