1 // 2 // Copyright 2024 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 7 #ifndef COMPILER_TRANSLATOR_WGSL_OUTPUT_UNIFORM_BLOCKS_H_ 8 #define COMPILER_TRANSLATOR_WGSL_OUTPUT_UNIFORM_BLOCKS_H_ 9 10 #include "compiler/translator/Common.h" 11 #include "compiler/translator/Compiler.h" 12 #include "compiler/translator/IntermNode.h" 13 14 namespace sh 15 { 16 17 const char kDefaultUniformBlockVarType[] = "ANGLE_DefaultUniformBlock"; 18 const char kDefaultUniformBlockVarName[] = "ANGLE_defaultUniformBlock"; 19 const uint32_t kDefaultUniformBlockBindGroup = 0; 20 const uint32_t kDefaultVertexUniformBlockBinding = 0; 21 const uint32_t kDefaultFragmentUniformBlockBinding = 1; 22 23 const uint32_t kTextureAndSamplerBindGroup = 1; 24 // The translator emits this dummy location, which needs to be replaced when linking the two 25 // separate shader stages. 26 const char kTextureSamplerBindingMarker[] = "@group(1) @binding(@@@@@@) var "; 27 // The translator emits split samplers/textures for GLSL's combined textures/samplers (combined 28 // textures/samplers are not supported by WGSL). The new variables are prefixed with these 29 // constants, respectively. 30 const char kAngleSamplerPrefix[] = "ANGLE_sampler_"; 31 const char kAngleTexturePrefix[] = "ANGLE_texture_"; 32 33 const char kWrappedStructFieldName[] = "elem"; 34 35 struct UniformBlockMetadata 36 { 37 // A list of structs used anywhere in the uniform address space. These will require special 38 // handling (@align() attributes, wrapping of basic types, etc.) to ensure they fit WGSL's 39 // uniform layout requirements. 40 // The key is TSymbolUniqueId::get(). 41 TUnorderedSet<int> structsInUniformAddressSpace; 42 }; 43 44 // Given a GLSL AST `root`, fills in `outMetadata`, to be used when outputting WGSL. 45 // If the AST is manipulated after calling this, it may be out of sync with the data recorded in 46 // `outMetadata`. 47 bool RecordUniformBlockMetadata(TIntermBlock *root, UniformBlockMetadata &outMetadata); 48 49 // Based on the GLSL, some extra WGSL will have to be generated so it can be referenced by 50 // the WGSL generated by the traverser, This tracks exactly which WGSL snippets will need to be 51 // generated, 52 struct WGSLGenerationMetadataForUniforms 53 { 54 // Arrays must have a stride of at least 16 if used in the uniform address spaces. If the array 55 // element type doesn't have an aligned size of a multiple of 16 (e.g. f32), the element type 56 // must be wrapped in a struct which is then aligned to 16. Adding to 57 // `arrayElementTypesInUniforms` will cause `OutputUniformWrapperStructsAndConversions` to 58 // generate a WGSL wrapper struct of the form: 59 // 60 // struct ANGLE_wrapper_f32 { 61 // @align(16) elem : f32; 62 // }; 63 TSet<TType> arrayElementTypesInUniforms; 64 65 // If we need to convert arrays with wrapped element types into arrays with unwrapped element 66 // types, the necessary conversions are listed here. 67 TSet<TType> arrayElementTypesThatNeedUnwrappingConversions; 68 69 // MatCx2 in a uniform will be represented as array<ANGLE_wrapped_vec2, C> to match std140 (WGSL 70 // uniforms pack their matrices a bit tighter). These will have to be converted back to matCx2 71 // for all other purposes (e.g. multiplication). 72 // If this set isn't empty, ANGLE_wrapped_vec2 will be generated even if it 73 // hasn't been yet. 74 TSet<TType> outputMatCx2Conversion; 75 }; 76 bool OutputUniformWrapperStructsAndConversions( 77 TInfoSinkBase &output, 78 const WGSLGenerationMetadataForUniforms &wgslGenerationMetadataForUniforms); 79 80 bool IsMatCx2(const TType *type); 81 82 ImmutableString MakeUnwrappingArrayConversionFunctionName(const TType *type); 83 ImmutableString MakeMatCx2ConversionFunctionName(const TType *type); 84 85 // TODO(anglebug.com/42267100): for now does not output all uniform blocks, 86 // just the default block. (fails for matCx2, bool.) 87 bool OutputUniformBlocksAndSamplers(TCompiler *compiler, TIntermBlock *root); 88 89 // GLSL sampler uniforms are extracted from structs. Given a GLSL sampler's associated name string, 90 // this function retrieves its new WGSL name and strips off array indices. 91 std::string WGSLGetMappedSamplerName(const std::string &originalName); 92 93 } // namespace sh 94 95 #endif // COMPILER_TRANSLATOR_WGSL_OUTPUT_UNIFORM_BLOCKS_H_ 96