1 //===-- LayoutUtils.h - Vulkan Layout Util functions ------------*- C++ -*-===// 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 14 #ifndef MLIR_DIALECT_SPIRV_UTILS_LAYOUTUTILS_H_ 15 #define MLIR_DIALECT_SPIRV_UTILS_LAYOUTUTILS_H_ 16 17 #include <cstdint> 18 19 namespace mlir { 20 class Type; 21 class VectorType; 22 23 namespace spirv { 24 class ArrayType; 25 class RuntimeArrayType; 26 class StructType; 27 } // namespace spirv 28 29 /// According to the Vulkan spec "15.6.4. Offset and Stride Assignment": 30 /// "There are different alignment requirements depending on the specific 31 /// resources and on the features enabled on the device." 32 /// 33 /// There are 3 types of alignment: scalar, base, extended. 34 /// See the spec for details. 35 /// 36 /// Note: Even if scalar alignment is supported, it is generally more 37 /// performant to use the base alignment. So here the calculation is based on 38 /// base alignment. 39 /// 40 /// The memory layout must obey the following rules: 41 /// 1. The Offset decoration of any member must be a multiple of its alignment. 42 /// 2. Any ArrayStride or MatrixStride decoration must be a multiple of the 43 /// alignment of the array or matrix as defined above. 44 /// 45 /// According to the SPIR-V spec: 46 /// "The ArrayStride, MatrixStride, and Offset decorations must be large 47 /// enough to hold the size of the objects they affect (that is, specifying 48 /// overlap is invalid)." 49 class VulkanLayoutUtils { 50 public: 51 using Size = uint64_t; 52 53 /// Returns a new StructType with layout decoration. 54 static spirv::StructType decorateType(spirv::StructType structType); 55 56 /// Checks whether a type is legal in terms of Vulkan layout info 57 /// decoration. A type is dynamically illegal if it's a composite type in the 58 /// StorageBuffer, PhysicalStorageBuffer, Uniform, and PushConstant Storage 59 /// Classes without layout information. 60 static bool isLegalType(Type type); 61 62 private: 63 /// Returns a new type with layout decoration. Assigns the type size in bytes 64 /// to the `size`. Assigns the type alignment in bytes to the `alignment`. 65 static Type decorateType(Type type, Size &size, Size &alignment); 66 67 static Type decorateType(VectorType vectorType, Size &size, Size &alignment); 68 static Type decorateType(spirv::ArrayType arrayType, Size &size, 69 Size &alignment); 70 static Type decorateType(spirv::RuntimeArrayType arrayType, Size &alignment); 71 static spirv::StructType decorateType(spirv::StructType structType, 72 Size &size, Size &alignment); 73 74 /// Calculates the alignment for the given scalar type. 75 static Size getScalarTypeAlignment(Type scalarType); 76 }; 77 78 } // namespace mlir 79 80 #endif // MLIR_DIALECT_SPIRV_UTILS_LAYOUTUTILS_H_ 81