• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- LayoutUtils.h - Decorate composite type with layout information ---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines utilities used to get alignment and layout information for
10 // types in SPIR-V dialect.
11 //
12 //===----------------------------------------------------------------------===//
13 #ifndef MLIR_DIALECT_SPIRV_LAYOUTUTILS_H_
14 #define MLIR_DIALECT_SPIRV_LAYOUTUTILS_H_
15 
16 #include <cstdint>
17 
18 namespace mlir {
19 class Type;
20 class VectorType;
21 
22 namespace spirv {
23 class ArrayType;
24 class RuntimeArrayType;
25 class StructType;
26 } // namespace spirv
27 
28 /// According to the Vulkan spec "14.5.4. Offset and Stride Assignment":
29 /// "There are different alignment requirements depending on the specific
30 /// resources and on the features enabled on the device."
31 ///
32 /// There are 3 types of alignment: scalar, base, extended.
33 /// See the spec for details.
34 ///
35 /// Note: Even if scalar alignment is supported, it is generally more
36 /// performant to use the base alignment. So here the calculation is based on
37 /// base alignment.
38 ///
39 /// The memory layout must obey the following rules:
40 /// 1. The Offset decoration of any member must be a multiple of its alignment.
41 /// 2. Any ArrayStride or MatrixStride decoration must be a multiple of the
42 /// alignment of the array or matrix as defined above.
43 ///
44 /// According to the SPIR-V spec:
45 /// "The ArrayStride, MatrixStride, and Offset decorations must be large
46 /// enough to hold the size of the objects they affect (that is, specifying
47 /// overlap is invalid)."
48 class VulkanLayoutUtils {
49 public:
50   using Size = uint64_t;
51 
52   /// Returns a new StructType with layout decoration.
53   static spirv::StructType decorateType(spirv::StructType structType);
54 
55   /// Checks whether a type is legal in terms of Vulkan layout info
56   /// decoration. A type is dynamically illegal if it's a composite type in the
57   /// StorageBuffer, PhysicalStorageBuffer, Uniform, and PushConstant Storage
58   /// Classes without layout information.
59   static bool isLegalType(Type type);
60 
61 private:
62   /// Returns a new type with layout decoration. Assigns the type size in bytes
63   /// to the `size`. Assigns the type alignment in bytes to the `alignment`.
64   static Type decorateType(Type type, Size &size, Size &alignment);
65 
66   static Type decorateType(VectorType vectorType, Size &size, Size &alignment);
67   static Type decorateType(spirv::ArrayType arrayType, Size &size,
68                            Size &alignment);
69   static Type decorateType(spirv::RuntimeArrayType arrayType, Size &alignment);
70   static spirv::StructType decorateType(spirv::StructType structType,
71                                         Size &size, Size &alignment);
72 
73   /// Calculates the alignment for the given scalar type.
74   static Size getScalarTypeAlignment(Type scalarType);
75 };
76 
77 } // namespace mlir
78 
79 #endif // MLIR_DIALECT_SPIRV_LAYOUTUTILS_H_
80