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 "libANGLE/renderer/ProgramImpl.h" 15 16 namespace rx 17 { 18 enum class GlslangError 19 { 20 InvalidShader, 21 InvalidSpirv, 22 }; 23 24 constexpr gl::ShaderMap<const char *> kDefaultUniformNames = { 25 {gl::ShaderType::Vertex, sh::vk::kDefaultUniformsNameVS}, 26 {gl::ShaderType::Geometry, sh::vk::kDefaultUniformsNameGS}, 27 {gl::ShaderType::Fragment, sh::vk::kDefaultUniformsNameFS}, 28 {gl::ShaderType::Compute, sh::vk::kDefaultUniformsNameCS}, 29 }; 30 31 struct GlslangProgramInterfaceInfo 32 { 33 // Uniforms set index: 34 uint32_t uniformsAndXfbDescriptorSetIndex; 35 uint32_t currentUniformBindingIndex; 36 // Textures set index: 37 uint32_t textureDescriptorSetIndex; 38 uint32_t currentTextureBindingIndex; 39 // Other shader resources set index: 40 uint32_t shaderResourceDescriptorSetIndex; 41 uint32_t currentShaderResourceBindingIndex; 42 // ANGLE driver uniforms set index: 43 uint32_t driverUniformsDescriptorSetIndex; 44 45 uint32_t locationsUsedForXfbExtension; 46 }; 47 48 struct GlslangSourceOptions 49 { 50 bool useOldRewriteStructSamplers = false; 51 bool supportsTransformFeedbackExtension = false; 52 bool emulateTransformFeedback = false; 53 bool emulateBresenhamLines = false; 54 }; 55 56 using SpirvBlob = std::vector<uint32_t>; 57 58 using GlslangErrorCallback = std::function<angle::Result(GlslangError)>; 59 60 // Information for each shader interface variable. Not all fields are relevant to each shader 61 // interface variable. For example opaque uniforms require a set and binding index, while vertex 62 // attributes require a location. 63 struct ShaderInterfaceVariableInfo 64 { 65 ShaderInterfaceVariableInfo(); 66 67 static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max(); 68 69 // Used for interface blocks and opaque uniforms. 70 uint32_t descriptorSet = kInvalid; 71 uint32_t binding = kInvalid; 72 // Used for vertex attributes, fragment shader outputs and varyings. There could be different 73 // variables that share the same name, such as a vertex attribute and a fragment output. They 74 // will share this object since they have the same name, but will find possibly different 75 // locations in their respective slots. 76 uint32_t location = kInvalid; 77 uint32_t component = kInvalid; 78 // The stages this shader interface variable is active. 79 gl::ShaderBitSet activeStages; 80 // Used for transform feedback extension to decorate vertex shader output. 81 uint32_t xfbBuffer = kInvalid; 82 uint32_t xfbOffset = kInvalid; 83 uint32_t xfbStride = kInvalid; 84 }; 85 86 // TODO: http://anglebug.com/4524: Need a different hash key than a string, since 87 // that's slow to calculate. 88 using ShaderInterfaceVariableInfoMap = std::unordered_map<std::string, ShaderInterfaceVariableInfo>; 89 using ShaderMapInterfaceVariableInfoMap = gl::ShaderMap<ShaderInterfaceVariableInfoMap>; 90 91 void GlslangInitialize(); 92 void GlslangRelease(); 93 94 bool GetImageNameWithoutIndices(std::string *name); 95 96 // Get the mapped sampler name after the soure is transformed by GlslangGetShaderSource() 97 std::string GetMappedSamplerNameOld(const std::string &originalName); 98 std::string GlslangGetMappedSamplerName(const std::string &originalName); 99 std::string GetXfbBufferName(const uint32_t bufferIndex); 100 101 void GlslangAssignLocations(GlslangSourceOptions &options, 102 const gl::ProgramState &programState, 103 const gl::ProgramLinkedResources &resources, 104 const gl::ShaderType shaderType, 105 GlslangProgramInterfaceInfo *programInterfaceInfo, 106 gl::ShaderMap<ShaderInterfaceVariableInfoMap> *variableInfoMapOut); 107 108 // Transform the source to include actual binding points for various shader resources (textures, 109 // buffers, xfb, etc). For some variables, these values are instead output to the variableInfoMap 110 // to be set during a SPIR-V transformation. This is a transitory step towards moving all variables 111 // to this map, at which point GlslangGetShaderSpirvCode will also be called by this function. 112 void GlslangGetShaderSource(GlslangSourceOptions &options, 113 const gl::ProgramState &programState, 114 const gl::ProgramLinkedResources &resources, 115 GlslangProgramInterfaceInfo *programInterfaceInfo, 116 gl::ShaderMap<std::string> *shaderSourcesOut, 117 ShaderMapInterfaceVariableInfoMap *variableInfoMapOut); 118 119 angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback, 120 const gl::ShaderType shaderType, 121 bool removeEarlyFragmentTestsOptimization, 122 const ShaderInterfaceVariableInfoMap &variableInfoMap, 123 const SpirvBlob &initialSpirvBlob, 124 SpirvBlob *spirvBlobOut); 125 126 angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback, 127 const gl::Caps &glCaps, 128 const gl::ShaderMap<std::string> &shaderSources, 129 const ShaderMapInterfaceVariableInfoMap &variableInfoMap, 130 gl::ShaderMap<SpirvBlob> *spirvBlobsOut); 131 132 } // namespace rx 133 134 #endif // LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_ 135