1 //===-- llvm/BinaryFormat/DXContainer.h - The DXBC file format --*- 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 manifest constants for the DXContainer object file format. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_BINARYFORMAT_DXCONTAINER_H 14 #define LLVM_BINARYFORMAT_DXCONTAINER_H 15 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/Support/SwapByteOrder.h" 18 19 #include <stdint.h> 20 21 namespace llvm { 22 23 // The DXContainer file format is arranged as a header and "parts". Semantically 24 // parts are similar to sections in other object file formats. The File format 25 // structure is roughly: 26 27 // ┌────────────────────────────────┐ 28 // │ Header │ 29 // ├────────────────────────────────┤ 30 // │ Part │ 31 // ├────────────────────────────────┤ 32 // │ Part │ 33 // ├────────────────────────────────┤ 34 // │ ... │ 35 // └────────────────────────────────┘ 36 37 namespace dxbc { 38 39 struct Hash { 40 uint8_t Digest[16]; 41 }; 42 43 enum class HashFlags : uint32_t { 44 None = 0, // No flags defined. 45 IncludesSource = 1, // This flag indicates that the shader hash was computed 46 // taking into account source information (-Zss) 47 }; 48 49 struct ShaderHash { 50 uint32_t Flags; // DxilShaderHashFlags 51 uint8_t Digest[16]; 52 53 void swapBytes() { sys::swapByteOrder(Flags); } 54 }; 55 56 struct ContainerVersion { 57 uint16_t Major; 58 uint16_t Minor; 59 60 void swapBytes() { 61 sys::swapByteOrder(Major); 62 sys::swapByteOrder(Minor); 63 } 64 }; 65 66 struct Header { 67 uint8_t Magic[4]; // "DXBC" 68 Hash FileHash; 69 ContainerVersion Version; 70 uint32_t FileSize; 71 uint32_t PartCount; 72 73 void swapBytes() { 74 Version.swapBytes(); 75 sys::swapByteOrder(FileSize); 76 sys::swapByteOrder(PartCount); 77 } 78 // Structure is followed by part offsets: uint32_t PartOffset[PartCount]; 79 // The offset is to a PartHeader, which is followed by the Part Data. 80 }; 81 82 /// Use this type to describe the size and type of a DXIL container part. 83 struct PartHeader { 84 uint8_t Name[4]; 85 uint32_t Size; 86 87 void swapBytes() { sys::swapByteOrder(Size); } 88 StringRef getName() const { 89 return StringRef(reinterpret_cast<const char *>(&Name[0]), 4); 90 } 91 // Structure is followed directly by part data: uint8_t PartData[PartSize]. 92 }; 93 94 struct BitcodeHeader { 95 uint8_t Magic[4]; // ACSII "DXIL". 96 uint8_t MajorVersion; // DXIL version. 97 uint8_t MinorVersion; // DXIL version. 98 uint16_t Unused; 99 uint32_t Offset; // Offset to LLVM bitcode (from start of header). 100 uint32_t Size; // Size of LLVM bitcode (in bytes). 101 // Followed by uint8_t[BitcodeHeader.Size] at &BitcodeHeader + Header.Offset 102 103 void swapBytes() { 104 sys::swapByteOrder(MinorVersion); 105 sys::swapByteOrder(MajorVersion); 106 sys::swapByteOrder(Offset); 107 sys::swapByteOrder(Size); 108 } 109 }; 110 111 struct ProgramHeader { 112 uint8_t MinorVersion : 4; 113 uint8_t MajorVersion : 4; 114 uint8_t Unused; 115 uint16_t ShaderKind; 116 uint32_t Size; // Size in uint32_t words including this header. 117 BitcodeHeader Bitcode; 118 119 void swapBytes() { 120 sys::swapByteOrder(ShaderKind); 121 sys::swapByteOrder(Size); 122 Bitcode.swapBytes(); 123 } 124 }; 125 126 static_assert(sizeof(ProgramHeader) == 24, "ProgramHeader Size incorrect!"); 127 128 } // namespace dxbc 129 } // namespace llvm 130 131 #endif // LLVM_BINARYFORMAT_DXCONTAINER_H 132