Hash :
53ec86ab
Author :
Date :
2024-12-17T14:40:31
WGSL: support small stride arrays in uniforms WGSL requires arrays in the uniform address space to have a stride a multiple of 16. This CL makes WGSL translator emit wrapper structs for array element types used in the uniform address space, when the array stride is not a multiple of 16. The exception is for structs that aren't an aligned size of 16n, and for any types matCx2, since they are (or will be) handled in different ways that ensure alignment to 16. This should leave only f32, i32, u32, and vec2. See https://www.w3.org/TR/WGSL/#example-67da5de6 for an example of using a wrapper struct. This requires converting arrays with a wrapper struct element type to arrays with an unwrapped element type when they are first used; this can be "optimized" later for the common case of accessing a single array element, which can then be unwrapped immediately. This CL generates WGSL conversion functions when necessary. After this, the only types that can't yet be used in a uniform are matCx2 and bools. This is #2 in https://docs.google.com/document/d/17Qku1QEbLDhvJS-JJ9lPQAbnuZtLxWhG-ha5eCUhtEY/edit?tab=t.0#bookmark=id.rt3slgehd4te Bug: angleproject:376553328 Change-Id: I1edfa7f481a6cbf5b595643aae8728e67bc4b770 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6092038 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Liza Burakova <liza@chromium.org> Reviewed-by: Matt Denton <mpdenton@google.com> Commit-Queue: Matt Denton <mpdenton@google.com>
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
//
// 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";
const uint32_t kDefaultUniformBlockBindGroup = 0;
const uint32_t kDefaultVertexUniformBlockBinding = 0;
const uint32_t kDefaultFragmentUniformBlockBinding = 1;
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;
};
bool OutputUniformWrapperStructsAndConversions(
TInfoSinkBase &output,
const WGSLGenerationMetadataForUniforms &arrayElementTypesInUniforms);
ImmutableString MakeUnwrappingArrayConversionFunctionName(const TType *type);
// TODO(anglebug.com/42267100): for now does not output all uniform blocks,
// just the default block. (fails for matCx2, bool.)
bool OutputUniformBlocks(TCompiler *compiler, TIntermBlock *root);
} // namespace sh
#endif // COMPILER_TRANSLATOR_WGSL_OUTPUT_UNIFORM_BLOCKS_H_