| // |
| // Copyright 2019 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // Wrapper for Khronos glslang compiler. This file is used by Vulkan and Metal backends. |
| // |
| |
| #ifndef LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_ |
| #define LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_ |
| |
| #include <functional> |
| |
| #include "common/spirv/spirv_types.h" |
| #include "libANGLE/renderer/ProgramImpl.h" |
| #include "libANGLE/renderer/renderer_utils.h" |
| |
| namespace rx |
| { |
| class ShaderInterfaceVariableInfoMap; |
| constexpr gl::ShaderMap<const char *> kDefaultUniformNames = { |
| {gl::ShaderType::Vertex, sh::vk::kDefaultUniformsNameVS}, |
| {gl::ShaderType::TessControl, sh::vk::kDefaultUniformsNameTCS}, |
| {gl::ShaderType::TessEvaluation, sh::vk::kDefaultUniformsNameTES}, |
| {gl::ShaderType::Geometry, sh::vk::kDefaultUniformsNameGS}, |
| {gl::ShaderType::Fragment, sh::vk::kDefaultUniformsNameFS}, |
| {gl::ShaderType::Compute, sh::vk::kDefaultUniformsNameCS}, |
| }; |
| |
| struct GlslangProgramInterfaceInfo |
| { |
| // Uniforms set index: |
| uint32_t uniformsAndXfbDescriptorSetIndex; |
| uint32_t currentUniformBindingIndex; |
| // Textures set index: |
| uint32_t textureDescriptorSetIndex; |
| uint32_t currentTextureBindingIndex; |
| // Other shader resources set index: |
| uint32_t shaderResourceDescriptorSetIndex; |
| uint32_t currentShaderResourceBindingIndex; |
| // ANGLE driver uniforms set index: |
| uint32_t driverUniformsDescriptorSetIndex; |
| |
| uint32_t locationsUsedForXfbExtension; |
| }; |
| |
| struct GlslangSourceOptions |
| { |
| bool supportsTransformFeedbackExtension = false; |
| bool supportsTransformFeedbackEmulation = false; |
| bool enableTransformFeedbackEmulation = false; |
| bool emulateBresenhamLines = false; |
| }; |
| |
| struct GlslangSpirvOptions |
| { |
| gl::ShaderType shaderType = gl::ShaderType::InvalidEnum; |
| bool negativeViewportSupported = false; |
| bool transformPositionToVulkanClipSpace = false; |
| bool removeDebugInfo = false; |
| bool isLastPreFragmentStage = false; |
| bool isTransformFeedbackStage = false; |
| bool isTransformFeedbackEmulated = false; |
| }; |
| |
| struct UniformBindingInfo final |
| { |
| UniformBindingInfo(); |
| UniformBindingInfo(uint32_t bindingIndex, |
| gl::ShaderBitSet shaderBitSet, |
| gl::ShaderType frontShaderType); |
| uint32_t bindingIndex = 0; |
| gl::ShaderBitSet shaderBitSet = gl::ShaderBitSet(); |
| gl::ShaderType frontShaderType = gl::ShaderType::InvalidEnum; |
| }; |
| |
| using UniformBindingIndexMap = angle::HashMap<std::string, UniformBindingInfo>; |
| |
| struct ShaderInterfaceVariableXfbInfo |
| { |
| static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max(); |
| |
| // Used by both extension and emulation |
| uint32_t buffer = kInvalid; |
| uint32_t offset = kInvalid; |
| uint32_t stride = kInvalid; |
| |
| // Used only by emulation (array index support is missing from VK_EXT_transform_feedback) |
| uint32_t arraySize = kInvalid; |
| uint32_t columnCount = kInvalid; |
| uint32_t rowCount = kInvalid; |
| uint32_t arrayIndex = kInvalid; |
| GLenum componentType = GL_FLOAT; |
| // If empty, the whole array is captured. Otherwise only the specified members are captured. |
| std::vector<ShaderInterfaceVariableXfbInfo> arrayElements; |
| }; |
| |
| // Information for each shader interface variable. Not all fields are relevant to each shader |
| // interface variable. For example opaque uniforms require a set and binding index, while vertex |
| // attributes require a location. |
| struct ShaderInterfaceVariableInfo |
| { |
| ShaderInterfaceVariableInfo(); |
| |
| static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max(); |
| |
| // Used for interface blocks and opaque uniforms. |
| uint32_t descriptorSet = kInvalid; |
| uint32_t binding = kInvalid; |
| // Used for vertex attributes, fragment shader outputs and varyings. There could be different |
| // variables that share the same name, such as a vertex attribute and a fragment output. They |
| // will share this object since they have the same name, but will find possibly different |
| // locations in their respective slots. |
| uint32_t location = kInvalid; |
| uint32_t component = kInvalid; |
| uint32_t index = kInvalid; |
| // The stages this shader interface variable is active. |
| gl::ShaderBitSet activeStages; |
| // Used for transform feedback extension to decorate vertex shader output. |
| ShaderInterfaceVariableXfbInfo xfb; |
| std::vector<ShaderInterfaceVariableXfbInfo> fieldXfb; |
| // Indicates that the precision needs to be modified in the generated SPIR-V |
| // to support only transferring medium precision data when there's a precision |
| // mismatch between the shaders. For example, either the VS casts highp->mediump |
| // or the FS casts mediump->highp. |
| bool useRelaxedPrecision = false; |
| // Indicate if varying is input or output, or both (in case of for example gl_Position in a |
| // geometry shader) |
| bool varyingIsInput = false; |
| bool varyingIsOutput = false; |
| // For vertex attributes, this is the number of components / locations. These are used by the |
| // vertex attribute aliasing transformation only. |
| uint8_t attributeComponentCount = 0; |
| uint8_t attributeLocationCount = 0; |
| // Indicate if this variable has been deduplicated. |
| bool isDuplicate = false; |
| }; |
| |
| bool GetImageNameWithoutIndices(std::string *name); |
| |
| // Get the mapped sampler name. |
| std::string GlslangGetMappedSamplerName(const std::string &originalName); |
| std::string GetXfbBufferName(const uint32_t bufferIndex); |
| |
| void GlslangAssignLocations(const GlslangSourceOptions &options, |
| const gl::ProgramExecutable &programExecutable, |
| const gl::ProgramVaryingPacking &varyingPacking, |
| const gl::ShaderType shaderType, |
| const gl::ShaderType frontShaderType, |
| bool isTransformFeedbackStage, |
| GlslangProgramInterfaceInfo *programInterfaceInfo, |
| UniformBindingIndexMap *uniformBindingIndexMapOut, |
| ShaderInterfaceVariableInfoMap *variableInfoMapOut); |
| |
| void GlslangAssignTransformFeedbackLocations(gl::ShaderType shaderType, |
| const gl::ProgramExecutable &programExecutable, |
| bool isTransformFeedbackStage, |
| GlslangProgramInterfaceInfo *programInterfaceInfo, |
| ShaderInterfaceVariableInfoMap *variableInfoMapOut); |
| #if ANGLE_ENABLE_METAL_SPIRV |
| // Retrieves the compiled SPIR-V code for each shader stage, and calls |GlslangAssignLocations|. |
| void GlslangGetShaderSpirvCode(const GlslangSourceOptions &options, |
| const gl::ProgramState &programState, |
| const gl::ProgramLinkedResources &resources, |
| GlslangProgramInterfaceInfo *programInterfaceInfo, |
| gl::ShaderMap<const angle::spirv::Blob *> *spirvBlobsOut, |
| ShaderInterfaceVariableInfoMap *variableInfoMapOut); |
| |
| angle::Result GlslangTransformSpirvCode(const GlslangSpirvOptions &options, |
| const ShaderInterfaceVariableInfoMap &variableInfoMap, |
| const angle::spirv::Blob &initialSpirvBlob, |
| angle::spirv::Blob *spirvBlobOut); |
| #endif |
| |
| } // namespace rx |
| |
| #endif // LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_ |