• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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