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