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