• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Wrapper for Khronos glslang compiler. This file is used by Vulkan and Metal backends.
7 //
8 
9 #ifndef LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_
10 #define LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_
11 
12 #include <functional>
13 
14 #include "common/spirv/spirv_types.h"
15 #include "libANGLE/renderer/ProgramImpl.h"
16 #include "libANGLE/renderer/renderer_utils.h"
17 
18 namespace rx
19 {
20 constexpr gl::ShaderMap<const char *> kDefaultUniformNames = {
21     {gl::ShaderType::Vertex, sh::vk::kDefaultUniformsNameVS},
22     {gl::ShaderType::TessControl, sh::vk::kDefaultUniformsNameTCS},
23     {gl::ShaderType::TessEvaluation, sh::vk::kDefaultUniformsNameTES},
24     {gl::ShaderType::Geometry, sh::vk::kDefaultUniformsNameGS},
25     {gl::ShaderType::Fragment, sh::vk::kDefaultUniformsNameFS},
26     {gl::ShaderType::Compute, sh::vk::kDefaultUniformsNameCS},
27 };
28 
29 struct GlslangProgramInterfaceInfo
30 {
31     // Uniforms set index:
32     uint32_t uniformsAndXfbDescriptorSetIndex;
33     uint32_t currentUniformBindingIndex;
34     // Textures set index:
35     uint32_t textureDescriptorSetIndex;
36     uint32_t currentTextureBindingIndex;
37     // Other shader resources set index:
38     uint32_t shaderResourceDescriptorSetIndex;
39     uint32_t currentShaderResourceBindingIndex;
40     // ANGLE driver uniforms set index:
41     uint32_t driverUniformsDescriptorSetIndex;
42 
43     uint32_t locationsUsedForXfbExtension;
44 };
45 
46 struct GlslangSourceOptions
47 {
48     bool supportsTransformFeedbackExtension = false;
49     bool supportsTransformFeedbackEmulation = false;
50     bool enableTransformFeedbackEmulation   = false;
51     bool emulateBresenhamLines              = false;
52 };
53 
54 struct GlslangSpirvOptions
55 {
56     gl::ShaderType shaderType                 = gl::ShaderType::InvalidEnum;
57     SurfaceRotation preRotation               = SurfaceRotation::Identity;
58     bool negativeViewportSupported            = false;
59     bool transformPositionToVulkanClipSpace   = false;
60     bool removeEarlyFragmentTestsOptimization = false;
61     bool removeDebugInfo                      = false;
62     bool isTransformFeedbackStage             = false;
63     bool isTransformFeedbackEmulated          = false;
64 };
65 
66 struct UniformBindingInfo final
67 {
68     UniformBindingInfo();
69     UniformBindingInfo(uint32_t bindingIndex,
70                        gl::ShaderBitSet shaderBitSet,
71                        gl::ShaderType frontShaderType);
72     uint32_t bindingIndex          = 0;
73     gl::ShaderBitSet shaderBitSet  = gl::ShaderBitSet();
74     gl::ShaderType frontShaderType = gl::ShaderType::InvalidEnum;
75 };
76 
77 using UniformBindingIndexMap = angle::HashMap<std::string, UniformBindingInfo>;
78 
79 struct ShaderInterfaceVariableXfbInfo
80 {
81     static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max();
82 
83     // Used by both extension and emulation
84     uint32_t buffer = kInvalid;
85     uint32_t offset = kInvalid;
86     uint32_t stride = kInvalid;
87 
88     // Used only by emulation (array index support is missing from VK_EXT_transform_feedback)
89     uint32_t arraySize   = kInvalid;
90     uint32_t columnCount = kInvalid;
91     uint32_t rowCount    = kInvalid;
92     uint32_t arrayIndex  = kInvalid;
93     GLenum componentType = GL_FLOAT;
94     // If empty, the whole array is captured.  Otherwise only the specified members are captured.
95     std::vector<ShaderInterfaceVariableXfbInfo> arrayElements;
96 };
97 
98 // Information for each shader interface variable.  Not all fields are relevant to each shader
99 // interface variable.  For example opaque uniforms require a set and binding index, while vertex
100 // attributes require a location.
101 struct ShaderInterfaceVariableInfo
102 {
103     ShaderInterfaceVariableInfo();
104 
105     static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max();
106 
107     // Used for interface blocks and opaque uniforms.
108     uint32_t descriptorSet = kInvalid;
109     uint32_t binding       = kInvalid;
110     // Used for vertex attributes, fragment shader outputs and varyings.  There could be different
111     // variables that share the same name, such as a vertex attribute and a fragment output.  They
112     // will share this object since they have the same name, but will find possibly different
113     // locations in their respective slots.
114     uint32_t location  = kInvalid;
115     uint32_t component = kInvalid;
116     uint32_t index     = kInvalid;
117     // The stages this shader interface variable is active.
118     gl::ShaderBitSet activeStages;
119     // Used for transform feedback extension to decorate vertex shader output.
120     ShaderInterfaceVariableXfbInfo xfb;
121     std::vector<ShaderInterfaceVariableXfbInfo> fieldXfb;
122     // Indicates that the precision needs to be modified in the generated SPIR-V
123     // to support only transferring medium precision data when there's a precision
124     // mismatch between the shaders. For example, either the VS casts highp->mediump
125     // or the FS casts mediump->highp.
126     bool useRelaxedPrecision = false;
127     // Indicate if varying is input or output, or both (in case of for example gl_Position in a
128     // geometry shader)
129     bool varyingIsInput  = false;
130     bool varyingIsOutput = false;
131     // For vertex attributes, this is the number of components / locations.  These are used by the
132     // vertex attribute aliasing transformation only.
133     uint8_t attributeComponentCount = 0;
134     uint8_t attributeLocationCount  = 0;
135     // Indicate if this variable has been deduplicated.
136     bool isDuplicate = false;
137 };
138 
139 // TODO: http://anglebug.com/4524: Need a different hash key than a string, since that's slow to
140 // calculate.
141 class ShaderInterfaceVariableInfoMap final : angle::NonCopyable
142 {
143   public:
144     ShaderInterfaceVariableInfoMap();
145     ~ShaderInterfaceVariableInfoMap();
146 
147     void clear();
148     bool contains(gl::ShaderType shaderType, const std::string &variableName) const;
149     const ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType,
150                                            const std::string &variableName) const;
151     ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType, const std::string &variableName);
152     ShaderInterfaceVariableInfo &add(gl::ShaderType shaderType, const std::string &variableName);
153     void markAsDuplicate(gl::ShaderType shaderType, const std::string &variableName);
154     ShaderInterfaceVariableInfo &addOrGet(gl::ShaderType shaderType,
155                                           const std::string &variableName);
variableCount(gl::ShaderType shaderType)156     size_t variableCount(gl::ShaderType shaderType) const { return mData[shaderType].size(); }
157 
158     using VariableNameToInfoMap = angle::HashMap<std::string, ShaderInterfaceVariableInfo>;
159 
160     class Iterator final
161     {
162       public:
Iterator(VariableNameToInfoMap::const_iterator beginIt,VariableNameToInfoMap::const_iterator endIt)163         Iterator(VariableNameToInfoMap::const_iterator beginIt,
164                  VariableNameToInfoMap::const_iterator endIt)
165             : mBeginIt(beginIt), mEndIt(endIt)
166         {}
begin()167         VariableNameToInfoMap::const_iterator begin() { return mBeginIt; }
end()168         VariableNameToInfoMap::const_iterator end() { return mEndIt; }
169 
170       private:
171         VariableNameToInfoMap::const_iterator mBeginIt;
172         VariableNameToInfoMap::const_iterator mEndIt;
173     };
174 
175     Iterator getIterator(gl::ShaderType shaderType) const;
176 
177   private:
178     gl::ShaderMap<VariableNameToInfoMap> mData;
179 };
180 
181 bool GetImageNameWithoutIndices(std::string *name);
182 
183 // Get the mapped sampler name.
184 std::string GlslangGetMappedSamplerName(const std::string &originalName);
185 std::string GetXfbBufferName(const uint32_t bufferIndex);
186 
187 void GlslangAssignLocations(const GlslangSourceOptions &options,
188                             const gl::ProgramState &programState,
189                             const gl::ProgramVaryingPacking &varyingPacking,
190                             const gl::ShaderType shaderType,
191                             const gl::ShaderType frontShaderType,
192                             bool isTransformFeedbackStage,
193                             GlslangProgramInterfaceInfo *programInterfaceInfo,
194                             UniformBindingIndexMap *uniformBindingIndexMapOut,
195                             ShaderInterfaceVariableInfoMap *variableInfoMapOut);
196 
197 void GlslangAssignTransformFeedbackLocations(gl::ShaderType shaderType,
198                                              const gl::ProgramState &programState,
199                                              bool isTransformFeedbackStage,
200                                              GlslangProgramInterfaceInfo *programInterfaceInfo,
201                                              ShaderInterfaceVariableInfoMap *variableInfoMapOut);
202 
203 // Retrieves the compiled SPIR-V code for each shader stage, and calls |GlslangAssignLocations|.
204 void GlslangGetShaderSpirvCode(const GlslangSourceOptions &options,
205                                const gl::ProgramState &programState,
206                                const gl::ProgramLinkedResources &resources,
207                                GlslangProgramInterfaceInfo *programInterfaceInfo,
208                                gl::ShaderMap<const angle::spirv::Blob *> *spirvBlobsOut,
209                                ShaderInterfaceVariableInfoMap *variableInfoMapOut);
210 
211 angle::Result GlslangTransformSpirvCode(const GlslangSpirvOptions &options,
212                                         const ShaderInterfaceVariableInfoMap &variableInfoMap,
213                                         const angle::spirv::Blob &initialSpirvBlob,
214                                         angle::spirv::Blob *spirvBlobOut);
215 
216 }  // namespace rx
217 
218 #endif  // LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_
219