1 //
2 // Copyright 2021 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 // ShaderInterfaceVariableInfoMap: Maps shader interface variable SPIR-V ids to their Vulkan
7 // mapping.
8 //
9
10 #include "libANGLE/renderer/vulkan/ShaderInterfaceVariableInfoMap.h"
11
12 namespace rx
13 {
14 namespace
15 {
HashSPIRVId(uint32_t id)16 uint32_t HashSPIRVId(uint32_t id)
17 {
18 ASSERT(id >= sh::vk::spirv::kIdShaderVariablesBegin);
19 return id - sh::vk::spirv::kIdShaderVariablesBegin;
20 }
21 } // anonymous namespace
22
ShaderInterfaceVariableInfo()23 ShaderInterfaceVariableInfo::ShaderInterfaceVariableInfo() {}
24
25 // ShaderInterfaceVariableInfoMap implementation.
26 ShaderInterfaceVariableInfoMap::ShaderInterfaceVariableInfoMap() = default;
27
28 ShaderInterfaceVariableInfoMap::~ShaderInterfaceVariableInfoMap() = default;
29
clear()30 void ShaderInterfaceVariableInfoMap::clear()
31 {
32 mData.clear();
33 for (gl::ShaderType shaderType : gl::AllShaderTypes())
34 {
35 mIdToIndexMap[shaderType].clear();
36 }
37 std::fill(mInputPerVertexActiveMembers.begin(), mInputPerVertexActiveMembers.end(),
38 gl::PerVertexMemberBitSet{});
39 std::fill(mOutputPerVertexActiveMembers.begin(), mOutputPerVertexActiveMembers.end(),
40 gl::PerVertexMemberBitSet{});
41 }
42
load(VariableInfoArray && data,gl::ShaderMap<IdToIndexMap> && idToIndexMap,gl::ShaderMap<gl::PerVertexMemberBitSet> && inputPerVertexActiveMembers,gl::ShaderMap<gl::PerVertexMemberBitSet> && outputPerVertexActiveMembers)43 void ShaderInterfaceVariableInfoMap::load(
44 VariableInfoArray &&data,
45 gl::ShaderMap<IdToIndexMap> &&idToIndexMap,
46 gl::ShaderMap<gl::PerVertexMemberBitSet> &&inputPerVertexActiveMembers,
47 gl::ShaderMap<gl::PerVertexMemberBitSet> &&outputPerVertexActiveMembers)
48 {
49 mData.swap(data);
50 mIdToIndexMap.swap(idToIndexMap);
51 mInputPerVertexActiveMembers.swap(inputPerVertexActiveMembers);
52 mOutputPerVertexActiveMembers.swap(outputPerVertexActiveMembers);
53 }
54
setInputPerVertexActiveMembers(gl::ShaderType shaderType,gl::PerVertexMemberBitSet activeMembers)55 void ShaderInterfaceVariableInfoMap::setInputPerVertexActiveMembers(
56 gl::ShaderType shaderType,
57 gl::PerVertexMemberBitSet activeMembers)
58 {
59 // Input gl_PerVertex is only meaningful for tessellation and geometry stages
60 ASSERT(shaderType == gl::ShaderType::TessControl ||
61 shaderType == gl::ShaderType::TessEvaluation || shaderType == gl::ShaderType::Geometry ||
62 activeMembers.none());
63 mInputPerVertexActiveMembers[shaderType] = activeMembers;
64 }
65
setOutputPerVertexActiveMembers(gl::ShaderType shaderType,gl::PerVertexMemberBitSet activeMembers)66 void ShaderInterfaceVariableInfoMap::setOutputPerVertexActiveMembers(
67 gl::ShaderType shaderType,
68 gl::PerVertexMemberBitSet activeMembers)
69 {
70 // Output gl_PerVertex is only meaningful for vertex, tessellation and geometry stages
71 ASSERT(shaderType == gl::ShaderType::Vertex || shaderType == gl::ShaderType::TessControl ||
72 shaderType == gl::ShaderType::TessEvaluation || shaderType == gl::ShaderType::Geometry ||
73 activeMembers.none());
74 mOutputPerVertexActiveMembers[shaderType] = activeMembers;
75 }
76
setVariableIndex(gl::ShaderType shaderType,uint32_t id,VariableIndex index)77 void ShaderInterfaceVariableInfoMap::setVariableIndex(gl::ShaderType shaderType,
78 uint32_t id,
79 VariableIndex index)
80 {
81 mIdToIndexMap[shaderType][HashSPIRVId(id)] = index;
82 }
83
getVariableIndex(gl::ShaderType shaderType,uint32_t id) const84 const VariableIndex &ShaderInterfaceVariableInfoMap::getVariableIndex(gl::ShaderType shaderType,
85 uint32_t id) const
86 {
87 return mIdToIndexMap[shaderType].at(HashSPIRVId(id));
88 }
89
getMutable(gl::ShaderType shaderType,uint32_t id)90 ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::getMutable(gl::ShaderType shaderType,
91 uint32_t id)
92 {
93 ASSERT(hasVariable(shaderType, id));
94 uint32_t index = getVariableIndex(shaderType, id).index;
95 return mData[index];
96 }
97
add(gl::ShaderType shaderType,uint32_t id)98 ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::add(gl::ShaderType shaderType,
99 uint32_t id)
100 {
101 ASSERT(!hasVariable(shaderType, id));
102 uint32_t index = static_cast<uint32_t>(mData.size());
103 setVariableIndex(shaderType, id, {index});
104 mData.resize(index + 1);
105 return mData[index];
106 }
107
addResource(gl::ShaderBitSet shaderTypes,const gl::ShaderMap<uint32_t> & idInShaderTypes,uint32_t descriptorSet,uint32_t binding)108 void ShaderInterfaceVariableInfoMap::addResource(gl::ShaderBitSet shaderTypes,
109 const gl::ShaderMap<uint32_t> &idInShaderTypes,
110 uint32_t descriptorSet,
111 uint32_t binding)
112 {
113 uint32_t index = static_cast<uint32_t>(mData.size());
114 mData.resize(index + 1);
115 ShaderInterfaceVariableInfo *info = &mData[index];
116
117 info->descriptorSet = descriptorSet;
118 info->binding = binding;
119 info->activeStages = shaderTypes;
120
121 for (const gl::ShaderType shaderType : shaderTypes)
122 {
123 const uint32_t id = idInShaderTypes[shaderType];
124 ASSERT(!hasVariable(shaderType, id));
125 setVariableIndex(shaderType, id, {index});
126 }
127 }
128
addOrGet(gl::ShaderType shaderType,uint32_t id)129 ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::addOrGet(gl::ShaderType shaderType,
130 uint32_t id)
131 {
132 if (!hasVariable(shaderType, id))
133 {
134 return add(shaderType, id);
135 }
136 else
137 {
138 uint32_t index = getVariableIndex(shaderType, id).index;
139 return mData[index];
140 }
141 }
142
hasVariable(gl::ShaderType shaderType,uint32_t id) const143 bool ShaderInterfaceVariableInfoMap::hasVariable(gl::ShaderType shaderType, uint32_t id) const
144 {
145 const uint32_t hashedId = HashSPIRVId(id);
146 return hashedId < mIdToIndexMap[shaderType].size() &&
147 mIdToIndexMap[shaderType].at(hashedId).index != VariableIndex::kInvalid;
148 }
149
hasTransformFeedbackInfo(gl::ShaderType shaderType,uint32_t bufferIndex) const150 bool ShaderInterfaceVariableInfoMap::hasTransformFeedbackInfo(gl::ShaderType shaderType,
151 uint32_t bufferIndex) const
152 {
153 return hasVariable(shaderType, SpvGetXfbBufferBlockId(bufferIndex));
154 }
155 } // namespace rx
156