xref: /openbsd-src/gnu/llvm/llvm/include/llvm/BinaryFormat/DXContainer.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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