• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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