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