Hash :
b23bf47c
Author :
Date :
2023-01-25T18:50:40
Reland "Metal: rewrite default uniforms and uniform blocks" Instead of rewriting uniforms in shaders to match std140 layout, re-pack incoming uniform blocks' std140 packed variables to match Metal's layout. This change intorduces a new BlockLayoutEncoder for Metal types The block encoder handles packing typically larger GL types (bools) into smaller types, and adding support for more compressed matrix types. Since we no longer need to do shader-time packing and unpacking of data from std140 padded structs, complicated shader transformations have been removed. This patch greatly reduces register pressure, especially when working with shaders with arrays of previously expanded types. (Vec3's) Reland: Fix an issue where the default uniform block's final size was not aligned to the default uniform block's alignment requirements, causing crashes with the debug layer enabled. Bug: angleproject:7137 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3733524 Commit-Queue: Kyle Piddington <kpiddington@apple.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Kenneth Russell <kbr@chromium.org> Change-Id: I89d3b817675486fde73b91b0be0f4c25986d4ba5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4209867
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
//
// Copyright 2023 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.
//
// blocklayoutmetal.h:
// Methods and classes related to uniform layout and packing in Metal
//
#ifndef COMMON_BLOCKLAYOUT_METAL__H_
#define COMMON_BLOCKLAYOUT_METAL__H_
#include <cstddef>
#include <map>
#include <vector>
#include <GLSLANG/ShaderLang.h>
#include "angle_gl.h"
#include "compiler/translator/blocklayout.h"
namespace rx
{
namespace mtl
{
size_t GetMetalSizeForGLType(GLenum type);
size_t GetMetalAlignmentForGLType(GLenum type);
size_t GetMTLBaseAlignment(GLenum variableType, bool isRowMajor);
class MetalAlignmentVisitor : public sh::ShaderVariableVisitor
{
public:
MetalAlignmentVisitor() = default;
void visitVariable(const sh::ShaderVariable &variable, bool isRowMajor) override;
// This is in bytes rather than components.
size_t getBaseAlignment() const { return mCurrentAlignment; }
private:
size_t mCurrentAlignment = 0;
};
class BlockLayoutEncoderMTL : public sh::BlockLayoutEncoder
{
public:
BlockLayoutEncoderMTL();
~BlockLayoutEncoderMTL() override {}
sh::BlockMemberInfo encodeType(GLenum type,
const std::vector<unsigned int> &arraySizes,
bool isRowMajorMatrix) override;
// Advance the offset based on struct size and array dimensions. Size can be calculated with
// getShaderVariableSize() or equivalent. |enterAggregateType|/|exitAggregateType| is necessary
// around this call.
sh::BlockMemberInfo encodeArrayOfPreEncodedStructs(
size_t size,
const std::vector<unsigned int> &arraySizes) override;
size_t getCurrentOffset() const override;
size_t getShaderVariableSize(const sh::ShaderVariable &structVar, bool isRowMajor) override;
// Called when entering/exiting a structure variable.
void enterAggregateType(const sh::ShaderVariable &structVar) override;
void exitAggregateType(const sh::ShaderVariable &structVar) override;
private:
void getBlockLayoutInfo(GLenum type,
const std::vector<unsigned int> &arraySizes,
bool isRowMajorMatrix,
int *arrayStrideOut,
int *matrixStrideOut) override;
void advanceOffset(GLenum type,
const std::vector<unsigned int> &arraySizes,
bool isRowMajorMatrix,
int arrayStride,
int matrixStride) override;
size_t getBaseAlignment(const sh::ShaderVariable &variable) const;
size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const;
};
} // namespace mtl
} // namespace rx
#endif // COMMON_BLOCKLAYOUT_METAL_H_