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 // Header for the shared ShaderInterfaceVariableInfoMap class, used by both the
7 // Direct-to-Metal and Metal-SPIRV backends
8
9 #ifndef LIBANGLE_RENDERER_SHADERINTERFACEVARIABLEINFOMAP_H_
10 #define LIBANGLE_RENDERER_SHADERINTERFACEVARIABLEINFOMAP_H_
11
12 #include "common/FastVector.h"
13 #include "libANGLE/renderer/ProgramImpl.h"
14 #include "libANGLE/renderer/glslang_wrapper_utils.h"
15 #include "libANGLE/renderer/renderer_utils.h"
16
17 #include <functional>
18
19 #include <stdio.h>
20
21 namespace rx
22 {
23
24 enum class ShaderVariableType
25 {
26 AtomicCounter,
27 Attribute,
28 DefaultUniform,
29 DriverUniform,
30 FramebufferFetch,
31 Image,
32 Output,
33 SecondaryOutput,
34 ShaderStorageBuffer,
35 Texture,
36 TransformFeedback,
37 UniformBuffer,
38 Varying,
39 EnumCount,
40 };
41
42 struct TypeAndIndex
43 {
44 ShaderVariableType variableType;
45 uint32_t index;
46 };
47
48 class ShaderInterfaceVariableInfoMap final : angle::NonCopyable
49 {
50 public:
51 using VariableInfoArray = std::vector<ShaderInterfaceVariableInfo>;
52 using VariableTypeToInfoMap = angle::PackedEnumMap<ShaderVariableType, VariableInfoArray>;
53 using NameToTypeAndIndexMap = angle::HashMap<std::string, TypeAndIndex>;
54
55 static constexpr size_t kResourceFastMapMax = 32;
56 using ResourceIndexMap = angle::FastMap<uint32_t, kResourceFastMapMax>;
57 using VariableTypeToIndexMap = angle::PackedEnumMap<ShaderVariableType, ResourceIndexMap>;
58
59 ShaderInterfaceVariableInfoMap();
60 ~ShaderInterfaceVariableInfoMap();
61
62 void clear();
63 void load(const gl::ShaderMap<VariableTypeToInfoMap> &data,
64 const gl::ShaderMap<NameToTypeAndIndexMap> &nameToTypeAndIndexMap,
65 const gl::ShaderMap<VariableTypeToIndexMap> &indexedResourceIndexMap);
66
67 ShaderInterfaceVariableInfo &add(gl::ShaderType shaderType,
68 ShaderVariableType variableType,
69 const std::string &variableName);
70 void markAsDuplicate(gl::ShaderType shaderType,
71 ShaderVariableType variableType,
72 const std::string &variableName);
73 ShaderInterfaceVariableInfo &addOrGet(gl::ShaderType shaderType,
74 ShaderVariableType variableType,
75 const std::string &variableName);
76
77 void setActiveStages(gl::ShaderType shaderType,
78 ShaderVariableType variableType,
79 const std::string &variableName,
80 gl::ShaderBitSet activeStages);
81 ShaderInterfaceVariableInfo &getMutable(gl::ShaderType shaderType,
82 ShaderVariableType variableType,
83 const std::string &variableName);
84
85 const ShaderInterfaceVariableInfo &getDefaultUniformInfo(gl::ShaderType shaderType) const;
86 const ShaderInterfaceVariableInfo &getIndexedVariableInfo(gl::ShaderType shaderType,
87 ShaderVariableType variableType,
88 uint32_t variableIndex) const;
89 bool hasAtomicCounterInfo(gl::ShaderType shaderType) const;
90 const ShaderInterfaceVariableInfo &getAtomicCounterInfo(gl::ShaderType shaderType) const;
91 const ShaderInterfaceVariableInfo &getFramebufferFetchInfo(gl::ShaderType shaderType) const;
92 bool hasTransformFeedbackInfo(gl::ShaderType shaderType, uint32_t bufferIndex) const;
93 const ShaderInterfaceVariableInfo &getTransformFeedbackInfo(gl::ShaderType shaderType,
94 uint32_t bufferIndex) const;
95
96 bool hasVariable(gl::ShaderType shaderType, const std::string &variableName) const;
97 const ShaderInterfaceVariableInfo &getVariableByName(gl::ShaderType shaderType,
98 const std::string &variableName) const;
99 void mapIndexedResourceByName(gl::ShaderType shaderType,
100 ShaderVariableType variableType,
101 uint32_t resourceIndex,
102 const std::string &variableName);
103 void mapIndexedResource(gl::ShaderType shaderType,
104 ShaderVariableType variableType,
105 uint32_t resourceIndex,
106 uint32_t variableIndex);
107
108 const VariableInfoArray &getAttributes() const;
109 const gl::ShaderMap<VariableTypeToInfoMap> &getData() const;
110 const gl::ShaderMap<NameToTypeAndIndexMap> &getNameToTypeAndIndexMap() const;
111 const gl::ShaderMap<VariableTypeToIndexMap> &getIndexedResourceMap() const;
112
113 private:
114 gl::ShaderMap<VariableTypeToInfoMap> mData;
115 gl::ShaderMap<NameToTypeAndIndexMap> mNameToTypeAndIndexMap;
116 gl::ShaderMap<VariableTypeToIndexMap> mIndexedResourceIndexMap;
117 };
118
119 ANGLE_INLINE const ShaderInterfaceVariableInfo &
getDefaultUniformInfo(gl::ShaderType shaderType)120 ShaderInterfaceVariableInfoMap::getDefaultUniformInfo(gl::ShaderType shaderType) const
121 {
122 ASSERT(mData[shaderType][ShaderVariableType::DefaultUniform].size() == 1);
123 return mData[shaderType][ShaderVariableType::DefaultUniform][0];
124 }
125
126 ANGLE_INLINE const ShaderInterfaceVariableInfo &
getIndexedVariableInfo(gl::ShaderType shaderType,ShaderVariableType variableType,uint32_t resourceIndex)127 ShaderInterfaceVariableInfoMap::getIndexedVariableInfo(gl::ShaderType shaderType,
128 ShaderVariableType variableType,
129 uint32_t resourceIndex) const
130 {
131 ASSERT(resourceIndex < mIndexedResourceIndexMap[shaderType][variableType].size());
132 uint32_t variableIndex = mIndexedResourceIndexMap[shaderType][variableType][resourceIndex];
133 ASSERT(variableIndex < mData[shaderType][variableType].size());
134 return mData[shaderType][variableType][variableIndex];
135 }
136
hasAtomicCounterInfo(gl::ShaderType shaderType)137 ANGLE_INLINE bool ShaderInterfaceVariableInfoMap::hasAtomicCounterInfo(
138 gl::ShaderType shaderType) const
139 {
140 return !mData[shaderType][ShaderVariableType::AtomicCounter].empty();
141 }
142
143 ANGLE_INLINE const ShaderInterfaceVariableInfo &
getAtomicCounterInfo(gl::ShaderType shaderType)144 ShaderInterfaceVariableInfoMap::getAtomicCounterInfo(gl::ShaderType shaderType) const
145 {
146 ASSERT(mData[shaderType][ShaderVariableType::AtomicCounter].size() == 1);
147 return mData[shaderType][ShaderVariableType::AtomicCounter][0];
148 }
149
150 ANGLE_INLINE const ShaderInterfaceVariableInfo &
getFramebufferFetchInfo(gl::ShaderType shaderType)151 ShaderInterfaceVariableInfoMap::getFramebufferFetchInfo(gl::ShaderType shaderType) const
152 {
153 ASSERT(!mData[shaderType][ShaderVariableType::FramebufferFetch].empty());
154 return mData[shaderType][ShaderVariableType::FramebufferFetch][0];
155 }
156
157 ANGLE_INLINE const ShaderInterfaceVariableInfo &
getTransformFeedbackInfo(gl::ShaderType shaderType,uint32_t bufferIndex)158 ShaderInterfaceVariableInfoMap::getTransformFeedbackInfo(gl::ShaderType shaderType,
159 uint32_t bufferIndex) const
160 {
161 ASSERT(bufferIndex < mData[shaderType][ShaderVariableType::TransformFeedback].size());
162 return mData[shaderType][ShaderVariableType::TransformFeedback][bufferIndex];
163 }
164 } // namespace rx
165 #endif // LIBANGLE_RENDERER_SHADERINTERFACEVARIABLEINFOMAP_H_
166