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; // dxbc::HashFlags 51 uint8_t Digest[16]; 52 53 bool isPopulated(); 54 swapBytesShaderHash55 void swapBytes() { sys::swapByteOrder(Flags); } 56 }; 57 58 struct ContainerVersion { 59 uint16_t Major; 60 uint16_t Minor; 61 swapBytesContainerVersion62 void swapBytes() { 63 sys::swapByteOrder(Major); 64 sys::swapByteOrder(Minor); 65 } 66 }; 67 68 struct Header { 69 uint8_t Magic[4]; // "DXBC" 70 Hash FileHash; 71 ContainerVersion Version; 72 uint32_t FileSize; 73 uint32_t PartCount; 74 swapBytesHeader75 void swapBytes() { 76 Version.swapBytes(); 77 sys::swapByteOrder(FileSize); 78 sys::swapByteOrder(PartCount); 79 } 80 // Structure is followed by part offsets: uint32_t PartOffset[PartCount]; 81 // The offset is to a PartHeader, which is followed by the Part Data. 82 }; 83 84 /// Use this type to describe the size and type of a DXIL container part. 85 struct PartHeader { 86 uint8_t Name[4]; 87 uint32_t Size; 88 swapBytesPartHeader89 void swapBytes() { sys::swapByteOrder(Size); } getNamePartHeader90 StringRef getName() const { 91 return StringRef(reinterpret_cast<const char *>(&Name[0]), 4); 92 } 93 // Structure is followed directly by part data: uint8_t PartData[PartSize]. 94 }; 95 96 struct BitcodeHeader { 97 uint8_t Magic[4]; // ACSII "DXIL". 98 uint8_t MajorVersion; // DXIL version. 99 uint8_t MinorVersion; // DXIL version. 100 uint16_t Unused; 101 uint32_t Offset; // Offset to LLVM bitcode (from start of header). 102 uint32_t Size; // Size of LLVM bitcode (in bytes). 103 // Followed by uint8_t[BitcodeHeader.Size] at &BitcodeHeader + Header.Offset 104 swapBytesBitcodeHeader105 void swapBytes() { 106 sys::swapByteOrder(MinorVersion); 107 sys::swapByteOrder(MajorVersion); 108 sys::swapByteOrder(Offset); 109 sys::swapByteOrder(Size); 110 } 111 }; 112 113 struct ProgramHeader { 114 uint8_t MinorVersion : 4; 115 uint8_t MajorVersion : 4; 116 uint8_t Unused; 117 uint16_t ShaderKind; 118 uint32_t Size; // Size in uint32_t words including this header. 119 BitcodeHeader Bitcode; 120 swapBytesProgramHeader121 void swapBytes() { 122 sys::swapByteOrder(ShaderKind); 123 sys::swapByteOrder(Size); 124 Bitcode.swapBytes(); 125 } 126 }; 127 128 static_assert(sizeof(ProgramHeader) == 24, "ProgramHeader Size incorrect!"); 129 130 #define CONTAINER_PART(Part) Part, 131 enum class PartType { 132 Unknown = 0, 133 #include "DXContainerConstants.def" 134 }; 135 136 #define SHADER_FLAG(Num, Val, Str) Val = 1ull << Num, 137 enum class FeatureFlags : uint64_t { 138 #include "DXContainerConstants.def" 139 }; 140 static_assert((uint64_t)FeatureFlags::NextUnusedBit <= 1ull << 63, 141 "Shader flag bits exceed enum size."); 142 143 PartType parsePartType(StringRef S); 144 145 } // namespace dxbc 146 } // namespace llvm 147 148 #endif // LLVM_BINARYFORMAT_DXCONTAINER_H 149