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 class ShaderInterfaceVariableInfoMap; 21 constexpr gl::ShaderMap<const char *> kDefaultUniformNames = { 22 {gl::ShaderType::Vertex, sh::vk::kDefaultUniformsNameVS}, 23 {gl::ShaderType::TessControl, sh::vk::kDefaultUniformsNameTCS}, 24 {gl::ShaderType::TessEvaluation, sh::vk::kDefaultUniformsNameTES}, 25 {gl::ShaderType::Geometry, sh::vk::kDefaultUniformsNameGS}, 26 {gl::ShaderType::Fragment, sh::vk::kDefaultUniformsNameFS}, 27 {gl::ShaderType::Compute, sh::vk::kDefaultUniformsNameCS}, 28 }; 29 30 struct GlslangProgramInterfaceInfo 31 { 32 // Uniforms set index: 33 uint32_t uniformsAndXfbDescriptorSetIndex; 34 uint32_t currentUniformBindingIndex; 35 // Textures set index: 36 uint32_t textureDescriptorSetIndex; 37 uint32_t currentTextureBindingIndex; 38 // Other shader resources set index: 39 uint32_t shaderResourceDescriptorSetIndex; 40 uint32_t currentShaderResourceBindingIndex; 41 // ANGLE driver uniforms set index: 42 uint32_t driverUniformsDescriptorSetIndex; 43 44 uint32_t locationsUsedForXfbExtension; 45 }; 46 47 struct GlslangSourceOptions 48 { 49 bool supportsTransformFeedbackExtension = false; 50 bool supportsTransformFeedbackEmulation = false; 51 bool enableTransformFeedbackEmulation = false; 52 bool emulateBresenhamLines = false; 53 }; 54 55 struct GlslangSpirvOptions 56 { 57 gl::ShaderType shaderType = gl::ShaderType::InvalidEnum; 58 SurfaceRotation preRotation = SurfaceRotation::Identity; 59 bool negativeViewportSupported = false; 60 bool transformPositionToVulkanClipSpace = false; 61 bool removeEarlyFragmentTestsOptimization = false; 62 bool removeDebugInfo = false; 63 bool isTransformFeedbackStage = false; 64 bool isTransformFeedbackEmulated = false; 65 }; 66 67 struct UniformBindingInfo final 68 { 69 UniformBindingInfo(); 70 UniformBindingInfo(uint32_t bindingIndex, 71 gl::ShaderBitSet shaderBitSet, 72 gl::ShaderType frontShaderType); 73 uint32_t bindingIndex = 0; 74 gl::ShaderBitSet shaderBitSet = gl::ShaderBitSet(); 75 gl::ShaderType frontShaderType = gl::ShaderType::InvalidEnum; 76 }; 77 78 using UniformBindingIndexMap = angle::HashMap<std::string, UniformBindingInfo>; 79 80 struct ShaderInterfaceVariableXfbInfo 81 { 82 static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max(); 83 84 // Used by both extension and emulation 85 uint32_t buffer = kInvalid; 86 uint32_t offset = kInvalid; 87 uint32_t stride = kInvalid; 88 89 // Used only by emulation (array index support is missing from VK_EXT_transform_feedback) 90 uint32_t arraySize = kInvalid; 91 uint32_t columnCount = kInvalid; 92 uint32_t rowCount = kInvalid; 93 uint32_t arrayIndex = kInvalid; 94 GLenum componentType = GL_FLOAT; 95 // If empty, the whole array is captured. Otherwise only the specified members are captured. 96 std::vector<ShaderInterfaceVariableXfbInfo> arrayElements; 97 }; 98 99 // Information for each shader interface variable. Not all fields are relevant to each shader 100 // interface variable. For example opaque uniforms require a set and binding index, while vertex 101 // attributes require a location. 102 struct ShaderInterfaceVariableInfo 103 { 104 ShaderInterfaceVariableInfo(); 105 106 static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max(); 107 108 // Used for interface blocks and opaque uniforms. 109 uint32_t descriptorSet = kInvalid; 110 uint32_t binding = kInvalid; 111 // Used for vertex attributes, fragment shader outputs and varyings. There could be different 112 // variables that share the same name, such as a vertex attribute and a fragment output. They 113 // will share this object since they have the same name, but will find possibly different 114 // locations in their respective slots. 115 uint32_t location = kInvalid; 116 uint32_t component = kInvalid; 117 uint32_t index = kInvalid; 118 // The stages this shader interface variable is active. 119 gl::ShaderBitSet activeStages; 120 // Used for transform feedback extension to decorate vertex shader output. 121 ShaderInterfaceVariableXfbInfo xfb; 122 std::vector<ShaderInterfaceVariableXfbInfo> fieldXfb; 123 // Indicates that the precision needs to be modified in the generated SPIR-V 124 // to support only transferring medium precision data when there's a precision 125 // mismatch between the shaders. For example, either the VS casts highp->mediump 126 // or the FS casts mediump->highp. 127 bool useRelaxedPrecision = false; 128 // Indicate if varying is input or output, or both (in case of for example gl_Position in a 129 // geometry shader) 130 bool varyingIsInput = false; 131 bool varyingIsOutput = false; 132 // For vertex attributes, this is the number of components / locations. These are used by the 133 // vertex attribute aliasing transformation only. 134 uint8_t attributeComponentCount = 0; 135 uint8_t attributeLocationCount = 0; 136 // Indicate if this variable has been deduplicated. 137 bool isDuplicate = false; 138 }; 139 140 bool GetImageNameWithoutIndices(std::string *name); 141 142 // Get the mapped sampler name. 143 std::string GlslangGetMappedSamplerName(const std::string &originalName); 144 std::string GetXfbBufferName(const uint32_t bufferIndex); 145 146 void GlslangAssignLocations(const GlslangSourceOptions &options, 147 const gl::ProgramExecutable &programExecutable, 148 const gl::ProgramVaryingPacking &varyingPacking, 149 const gl::ShaderType shaderType, 150 const gl::ShaderType frontShaderType, 151 bool isTransformFeedbackStage, 152 GlslangProgramInterfaceInfo *programInterfaceInfo, 153 UniformBindingIndexMap *uniformBindingIndexMapOut, 154 ShaderInterfaceVariableInfoMap *variableInfoMapOut); 155 156 void GlslangAssignTransformFeedbackLocations(gl::ShaderType shaderType, 157 const gl::ProgramExecutable &programExecutable, 158 bool isTransformFeedbackStage, 159 GlslangProgramInterfaceInfo *programInterfaceInfo, 160 ShaderInterfaceVariableInfoMap *variableInfoMapOut); 161 162 // Retrieves the compiled SPIR-V code for each shader stage, and calls |GlslangAssignLocations|. 163 void GlslangGetShaderSpirvCode(const GlslangSourceOptions &options, 164 const gl::ProgramState &programState, 165 const gl::ProgramLinkedResources &resources, 166 GlslangProgramInterfaceInfo *programInterfaceInfo, 167 gl::ShaderMap<const angle::spirv::Blob *> *spirvBlobsOut, 168 ShaderInterfaceVariableInfoMap *variableInfoMapOut); 169 170 angle::Result GlslangTransformSpirvCode(const GlslangSpirvOptions &options, 171 const ShaderInterfaceVariableInfoMap &variableInfoMap, 172 const angle::spirv::Blob &initialSpirvBlob, 173 angle::spirv::Blob *spirvBlobOut); 174 175 } // namespace rx 176 177 #endif // LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_ 178