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 ShaderInterfaceVariableXfbInfo 67 { 68 static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max(); 69 70 // Used by both extension and emulation 71 uint32_t buffer = kInvalid; 72 uint32_t offset = kInvalid; 73 uint32_t stride = kInvalid; 74 75 // Used only by emulation (array index support is missing from VK_EXT_transform_feedback) 76 uint32_t arraySize = kInvalid; 77 uint32_t columnCount = kInvalid; 78 uint32_t rowCount = kInvalid; 79 uint32_t arrayIndex = kInvalid; 80 GLenum componentType = GL_FLOAT; 81 // If empty, the whole array is captured. Otherwise only the specified members are captured. 82 std::vector<ShaderInterfaceVariableXfbInfo> arrayElements; 83 }; 84 85 // Information for each shader interface variable. Not all fields are relevant to each shader 86 // interface variable. For example opaque uniforms require a set and binding index, while vertex 87 // attributes require a location. 88 struct ShaderInterfaceVariableInfo 89 { 90 ShaderInterfaceVariableInfo(); 91 92 static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max(); 93 94 // Used for interface blocks and opaque uniforms. 95 uint32_t descriptorSet = kInvalid; 96 uint32_t binding = kInvalid; 97 // Used for vertex attributes, fragment shader outputs and varyings. There could be different 98 // variables that share the same name, such as a vertex attribute and a fragment output. They 99 // will share this object since they have the same name, but will find possibly different 100 // locations in their respective slots. 101 uint32_t location = kInvalid; 102 uint32_t component = kInvalid; 103 uint32_t index = kInvalid; 104 // The stages this shader interface variable is active. 105 gl::ShaderBitSet activeStages; 106 // Used for transform feedback extension to decorate vertex shader output. 107 ShaderInterfaceVariableXfbInfo xfb; 108 std::vector<ShaderInterfaceVariableXfbInfo> fieldXfb; 109 // Indicates that the precision needs to be modified in the generated SPIR-V 110 // to support only transferring medium precision data when there's a precision 111 // mismatch between the shaders. For example, either the VS casts highp->mediump 112 // or the FS casts mediump->highp. 113 bool useRelaxedPrecision = false; 114 // Indicate if varying is input or output, or both (in case of for example gl_Position in a 115 // geometry shader) 116 bool varyingIsInput = false; 117 bool varyingIsOutput = false; 118 // For vertex attributes, this is the number of components / locations. These are used by the 119 // vertex attribute aliasing transformation only. 120 uint8_t attributeComponentCount = 0; 121 uint8_t attributeLocationCount = 0; 122 }; 123 124 // TODO: http://anglebug.com/4524: Need a different hash key than a string, since that's slow to 125 // calculate. 126 class ShaderInterfaceVariableInfoMap final : angle::NonCopyable 127 { 128 public: 129 ShaderInterfaceVariableInfoMap(); 130 ~ShaderInterfaceVariableInfoMap(); 131 132 void clear(); 133 bool contains(gl::ShaderType shaderType, const std::string &variableName) const; 134 const ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType, 135 const std::string &variableName) const; 136 ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType, const std::string &variableName); 137 ShaderInterfaceVariableInfo &add(gl::ShaderType shaderType, const std::string &variableName); 138 ShaderInterfaceVariableInfo &addOrGet(gl::ShaderType shaderType, 139 const std::string &variableName); variableCount(gl::ShaderType shaderType)140 size_t variableCount(gl::ShaderType shaderType) const { return mData[shaderType].size(); } 141 142 using VariableNameToInfoMap = angle::HashMap<std::string, ShaderInterfaceVariableInfo>; 143 144 class Iterator final 145 { 146 public: Iterator(VariableNameToInfoMap::const_iterator beginIt,VariableNameToInfoMap::const_iterator endIt)147 Iterator(VariableNameToInfoMap::const_iterator beginIt, 148 VariableNameToInfoMap::const_iterator endIt) 149 : mBeginIt(beginIt), mEndIt(endIt) 150 {} begin()151 VariableNameToInfoMap::const_iterator begin() { return mBeginIt; } end()152 VariableNameToInfoMap::const_iterator end() { return mEndIt; } 153 154 private: 155 VariableNameToInfoMap::const_iterator mBeginIt; 156 VariableNameToInfoMap::const_iterator mEndIt; 157 }; 158 159 Iterator getIterator(gl::ShaderType shaderType) const; 160 161 private: 162 gl::ShaderMap<VariableNameToInfoMap> mData; 163 }; 164 165 bool GetImageNameWithoutIndices(std::string *name); 166 167 // Get the mapped sampler name. 168 std::string GlslangGetMappedSamplerName(const std::string &originalName); 169 std::string GetXfbBufferName(const uint32_t bufferIndex); 170 171 void GlslangAssignLocations(const GlslangSourceOptions &options, 172 const gl::ProgramState &programState, 173 const gl::ProgramVaryingPacking &varyingPacking, 174 const gl::ShaderType shaderType, 175 const gl::ShaderType frontShaderType, 176 bool isTransformFeedbackStage, 177 GlslangProgramInterfaceInfo *programInterfaceInfo, 178 ShaderInterfaceVariableInfoMap *variableInfoMapOut); 179 180 void GlslangAssignTransformFeedbackLocations(gl::ShaderType shaderType, 181 const gl::ProgramState &programState, 182 bool isTransformFeedbackStage, 183 GlslangProgramInterfaceInfo *programInterfaceInfo, 184 ShaderInterfaceVariableInfoMap *variableInfoMapOut); 185 186 // Retrieves the compiled SPIR-V code for each shader stage, and calls |GlslangAssignLocations|. 187 void GlslangGetShaderSpirvCode(const GlslangSourceOptions &options, 188 const gl::ProgramState &programState, 189 const gl::ProgramLinkedResources &resources, 190 GlslangProgramInterfaceInfo *programInterfaceInfo, 191 gl::ShaderMap<const angle::spirv::Blob *> *spirvBlobsOut, 192 ShaderInterfaceVariableInfoMap *variableInfoMapOut); 193 194 angle::Result GlslangTransformSpirvCode(const GlslangSpirvOptions &options, 195 const ShaderInterfaceVariableInfoMap &variableInfoMap, 196 const angle::spirv::Blob &initialSpirvBlob, 197 angle::spirv::Blob *spirvBlobOut); 198 199 } // namespace rx 200 201 #endif // LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_ 202