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