File indexing completed on 2026-05-10 08:43:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_BINARYFORMAT_DXCONTAINER_H
0014 #define LLVM_BINARYFORMAT_DXCONTAINER_H
0015
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/Support/SwapByteOrder.h"
0018 #include "llvm/TargetParser/Triple.h"
0019
0020 #include <stdint.h>
0021
0022 namespace llvm {
0023 template <typename T> struct EnumEntry;
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 namespace dxbc {
0040
0041 inline Triple::EnvironmentType getShaderStage(uint32_t Kind) {
0042 assert(Kind <= Triple::Amplification - Triple::Pixel &&
0043 "Shader kind out of expected range.");
0044 return static_cast<Triple::EnvironmentType>(Triple::Pixel + Kind);
0045 }
0046
0047 struct Hash {
0048 uint8_t Digest[16];
0049 };
0050
0051 enum class HashFlags : uint32_t {
0052 None = 0,
0053 IncludesSource = 1,
0054
0055 };
0056
0057 struct ShaderHash {
0058 uint32_t Flags;
0059 uint8_t Digest[16];
0060
0061 bool isPopulated();
0062
0063 void swapBytes() { sys::swapByteOrder(Flags); }
0064 };
0065
0066 struct ContainerVersion {
0067 uint16_t Major;
0068 uint16_t Minor;
0069
0070 void swapBytes() {
0071 sys::swapByteOrder(Major);
0072 sys::swapByteOrder(Minor);
0073 }
0074 };
0075
0076 struct Header {
0077 uint8_t Magic[4];
0078 Hash FileHash;
0079 ContainerVersion Version;
0080 uint32_t FileSize;
0081 uint32_t PartCount;
0082
0083 void swapBytes() {
0084 Version.swapBytes();
0085 sys::swapByteOrder(FileSize);
0086 sys::swapByteOrder(PartCount);
0087 }
0088
0089
0090 };
0091
0092
0093 struct PartHeader {
0094 uint8_t Name[4];
0095 uint32_t Size;
0096
0097 void swapBytes() { sys::swapByteOrder(Size); }
0098 StringRef getName() const {
0099 return StringRef(reinterpret_cast<const char *>(&Name[0]), 4);
0100 }
0101
0102 };
0103
0104 struct BitcodeHeader {
0105 uint8_t Magic[4];
0106 uint8_t MinorVersion;
0107 uint8_t MajorVersion;
0108 uint16_t Unused;
0109 uint32_t Offset;
0110 uint32_t Size;
0111
0112
0113 void swapBytes() {
0114 sys::swapByteOrder(MinorVersion);
0115 sys::swapByteOrder(MajorVersion);
0116 sys::swapByteOrder(Offset);
0117 sys::swapByteOrder(Size);
0118 }
0119 };
0120
0121 struct ProgramHeader {
0122 uint8_t Version;
0123 uint8_t Unused;
0124 uint16_t ShaderKind;
0125 uint32_t Size;
0126 BitcodeHeader Bitcode;
0127
0128 void swapBytes() {
0129 sys::swapByteOrder(ShaderKind);
0130 sys::swapByteOrder(Size);
0131 Bitcode.swapBytes();
0132 }
0133 uint8_t getMajorVersion() { return Version >> 4; }
0134 uint8_t getMinorVersion() { return Version & 0xF; }
0135 static uint8_t getVersion(uint8_t Major, uint8_t Minor) {
0136 return (Major << 4) | Minor;
0137 }
0138 };
0139
0140 static_assert(sizeof(ProgramHeader) == 24, "ProgramHeader Size incorrect!");
0141
0142 #define CONTAINER_PART(Part) Part,
0143 enum class PartType {
0144 Unknown = 0,
0145 #include "DXContainerConstants.def"
0146 };
0147
0148 #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) Val = 1ull << Num,
0149 enum class FeatureFlags : uint64_t {
0150 #include "DXContainerConstants.def"
0151 };
0152 static_assert((uint64_t)FeatureFlags::NextUnusedBit <= 1ull << 63,
0153 "Shader flag bits exceed enum size.");
0154
0155 PartType parsePartType(StringRef S);
0156
0157 struct VertexPSVInfo {
0158 uint8_t OutputPositionPresent;
0159 uint8_t Unused[3];
0160
0161 void swapBytes() {
0162
0163 }
0164 };
0165
0166 struct HullPSVInfo {
0167 uint32_t InputControlPointCount;
0168 uint32_t OutputControlPointCount;
0169 uint32_t TessellatorDomain;
0170 uint32_t TessellatorOutputPrimitive;
0171
0172 void swapBytes() {
0173 sys::swapByteOrder(InputControlPointCount);
0174 sys::swapByteOrder(OutputControlPointCount);
0175 sys::swapByteOrder(TessellatorDomain);
0176 sys::swapByteOrder(TessellatorOutputPrimitive);
0177 }
0178 };
0179
0180 struct DomainPSVInfo {
0181 uint32_t InputControlPointCount;
0182 uint8_t OutputPositionPresent;
0183 uint8_t Unused[3];
0184 uint32_t TessellatorDomain;
0185
0186 void swapBytes() {
0187 sys::swapByteOrder(InputControlPointCount);
0188 sys::swapByteOrder(TessellatorDomain);
0189 }
0190 };
0191
0192 struct GeometryPSVInfo {
0193 uint32_t InputPrimitive;
0194 uint32_t OutputTopology;
0195 uint32_t OutputStreamMask;
0196 uint8_t OutputPositionPresent;
0197 uint8_t Unused[3];
0198
0199 void swapBytes() {
0200 sys::swapByteOrder(InputPrimitive);
0201 sys::swapByteOrder(OutputTopology);
0202 sys::swapByteOrder(OutputStreamMask);
0203 }
0204 };
0205
0206 struct PixelPSVInfo {
0207 uint8_t DepthOutput;
0208 uint8_t SampleFrequency;
0209 uint8_t Unused[2];
0210
0211 void swapBytes() {
0212
0213 }
0214 };
0215
0216 struct MeshPSVInfo {
0217 uint32_t GroupSharedBytesUsed;
0218 uint32_t GroupSharedBytesDependentOnViewID;
0219 uint32_t PayloadSizeInBytes;
0220 uint16_t MaxOutputVertices;
0221 uint16_t MaxOutputPrimitives;
0222
0223 void swapBytes() {
0224 sys::swapByteOrder(GroupSharedBytesUsed);
0225 sys::swapByteOrder(GroupSharedBytesDependentOnViewID);
0226 sys::swapByteOrder(PayloadSizeInBytes);
0227 sys::swapByteOrder(MaxOutputVertices);
0228 sys::swapByteOrder(MaxOutputPrimitives);
0229 }
0230 };
0231
0232 struct AmplificationPSVInfo {
0233 uint32_t PayloadSizeInBytes;
0234
0235 void swapBytes() { sys::swapByteOrder(PayloadSizeInBytes); }
0236 };
0237
0238 union PipelinePSVInfo {
0239 VertexPSVInfo VS;
0240 HullPSVInfo HS;
0241 DomainPSVInfo DS;
0242 GeometryPSVInfo GS;
0243 PixelPSVInfo PS;
0244 MeshPSVInfo MS;
0245 AmplificationPSVInfo AS;
0246
0247 void swapBytes(Triple::EnvironmentType Stage) {
0248 switch (Stage) {
0249 case Triple::EnvironmentType::Pixel:
0250 PS.swapBytes();
0251 break;
0252 case Triple::EnvironmentType::Vertex:
0253 VS.swapBytes();
0254 break;
0255 case Triple::EnvironmentType::Geometry:
0256 GS.swapBytes();
0257 break;
0258 case Triple::EnvironmentType::Hull:
0259 HS.swapBytes();
0260 break;
0261 case Triple::EnvironmentType::Domain:
0262 DS.swapBytes();
0263 break;
0264 case Triple::EnvironmentType::Mesh:
0265 MS.swapBytes();
0266 break;
0267 case Triple::EnvironmentType::Amplification:
0268 AS.swapBytes();
0269 break;
0270 default:
0271 break;
0272 }
0273 }
0274 };
0275
0276 static_assert(sizeof(PipelinePSVInfo) == 4 * sizeof(uint32_t),
0277 "Pipeline-specific PSV info must fit in 16 bytes.");
0278
0279 namespace PSV {
0280
0281 #define SEMANTIC_KIND(Val, Enum) Enum = Val,
0282 enum class SemanticKind : uint8_t {
0283 #include "DXContainerConstants.def"
0284 };
0285
0286 ArrayRef<EnumEntry<SemanticKind>> getSemanticKinds();
0287
0288 #define COMPONENT_TYPE(Val, Enum) Enum = Val,
0289 enum class ComponentType : uint8_t {
0290 #include "DXContainerConstants.def"
0291 };
0292
0293 ArrayRef<EnumEntry<ComponentType>> getComponentTypes();
0294
0295 #define INTERPOLATION_MODE(Val, Enum) Enum = Val,
0296 enum class InterpolationMode : uint8_t {
0297 #include "DXContainerConstants.def"
0298 };
0299
0300 ArrayRef<EnumEntry<InterpolationMode>> getInterpolationModes();
0301
0302 #define RESOURCE_TYPE(Val, Enum) Enum = Val,
0303 enum class ResourceType : uint32_t {
0304 #include "DXContainerConstants.def"
0305 };
0306
0307 ArrayRef<EnumEntry<ResourceType>> getResourceTypes();
0308
0309 #define RESOURCE_KIND(Val, Enum) Enum = Val,
0310 enum class ResourceKind : uint32_t {
0311 #include "DXContainerConstants.def"
0312 };
0313
0314 ArrayRef<EnumEntry<ResourceKind>> getResourceKinds();
0315
0316 #define RESOURCE_FLAG(Index, Enum) bool Enum = false;
0317 struct ResourceFlags {
0318 ResourceFlags() {};
0319 struct FlagsBits {
0320 #include "llvm/BinaryFormat/DXContainerConstants.def"
0321 };
0322 union {
0323 uint32_t Flags;
0324 FlagsBits Bits;
0325 };
0326 bool operator==(const uint32_t RFlags) const { return Flags == RFlags; }
0327 };
0328
0329 namespace v0 {
0330 struct RuntimeInfo {
0331 PipelinePSVInfo StageInfo;
0332 uint32_t MinimumWaveLaneCount;
0333 uint32_t MaximumWaveLaneCount;
0334
0335 void swapBytes() {
0336
0337 sys::swapByteOrder(MinimumWaveLaneCount);
0338 sys::swapByteOrder(MaximumWaveLaneCount);
0339 }
0340
0341 void swapBytes(Triple::EnvironmentType Stage) { StageInfo.swapBytes(Stage); }
0342 };
0343
0344 struct ResourceBindInfo {
0345 ResourceType Type;
0346 uint32_t Space;
0347 uint32_t LowerBound;
0348 uint32_t UpperBound;
0349
0350 void swapBytes() {
0351 sys::swapByteOrder(Type);
0352 sys::swapByteOrder(Space);
0353 sys::swapByteOrder(LowerBound);
0354 sys::swapByteOrder(UpperBound);
0355 }
0356 };
0357
0358 struct SignatureElement {
0359 uint32_t NameOffset;
0360 uint32_t IndicesOffset;
0361
0362 uint8_t Rows;
0363 uint8_t StartRow;
0364 uint8_t Cols : 4;
0365 uint8_t StartCol : 2;
0366 uint8_t Allocated : 1;
0367 uint8_t Unused : 1;
0368 SemanticKind Kind;
0369
0370 ComponentType Type;
0371 InterpolationMode Mode;
0372 uint8_t DynamicMask : 4;
0373 uint8_t Stream : 2;
0374 uint8_t Unused2 : 2;
0375 uint8_t Reserved;
0376
0377 void swapBytes() {
0378 sys::swapByteOrder(NameOffset);
0379 sys::swapByteOrder(IndicesOffset);
0380 }
0381 };
0382
0383 static_assert(sizeof(SignatureElement) == 4 * sizeof(uint32_t),
0384 "PSV Signature elements must fit in 16 bytes.");
0385
0386 }
0387
0388 namespace v1 {
0389
0390 struct MeshRuntimeInfo {
0391 uint8_t SigPrimVectors;
0392 uint8_t MeshOutputTopology;
0393 };
0394
0395 union GeometryExtraInfo {
0396 uint16_t MaxVertexCount;
0397 uint8_t SigPatchConstOrPrimVectors;
0398
0399
0400 MeshRuntimeInfo MeshInfo;
0401 };
0402 struct RuntimeInfo : public v0::RuntimeInfo {
0403 uint8_t ShaderStage;
0404 uint8_t UsesViewID;
0405 GeometryExtraInfo GeomData;
0406
0407
0408 uint8_t SigInputElements;
0409 uint8_t SigOutputElements;
0410 uint8_t SigPatchOrPrimElements;
0411
0412
0413 uint8_t SigInputVectors;
0414 uint8_t SigOutputVectors[4];
0415
0416 void swapBytes() {
0417
0418 }
0419
0420 void swapBytes(Triple::EnvironmentType Stage) {
0421 v0::RuntimeInfo::swapBytes(Stage);
0422 if (Stage == Triple::EnvironmentType::Geometry)
0423 sys::swapByteOrder(GeomData.MaxVertexCount);
0424 }
0425 };
0426
0427 }
0428
0429 namespace v2 {
0430 struct RuntimeInfo : public v1::RuntimeInfo {
0431 uint32_t NumThreadsX;
0432 uint32_t NumThreadsY;
0433 uint32_t NumThreadsZ;
0434
0435 void swapBytes() {
0436 sys::swapByteOrder(NumThreadsX);
0437 sys::swapByteOrder(NumThreadsY);
0438 sys::swapByteOrder(NumThreadsZ);
0439 }
0440
0441 void swapBytes(Triple::EnvironmentType Stage) {
0442 v1::RuntimeInfo::swapBytes(Stage);
0443 }
0444 };
0445
0446 struct ResourceBindInfo : public v0::ResourceBindInfo {
0447 ResourceKind Kind;
0448 ResourceFlags Flags;
0449
0450 void swapBytes() {
0451 v0::ResourceBindInfo::swapBytes();
0452 sys::swapByteOrder(Kind);
0453 sys::swapByteOrder(Flags.Flags);
0454 }
0455 };
0456
0457 }
0458
0459 namespace v3 {
0460 struct RuntimeInfo : public v2::RuntimeInfo {
0461 uint32_t EntryNameOffset;
0462
0463 void swapBytes() {
0464 v2::RuntimeInfo::swapBytes();
0465 sys::swapByteOrder(EntryNameOffset);
0466 }
0467
0468 void swapBytes(Triple::EnvironmentType Stage) {
0469 v2::RuntimeInfo::swapBytes(Stage);
0470 }
0471 };
0472
0473 }
0474 }
0475
0476 #define COMPONENT_PRECISION(Val, Enum) Enum = Val,
0477 enum class SigMinPrecision : uint32_t {
0478 #include "DXContainerConstants.def"
0479 };
0480
0481 ArrayRef<EnumEntry<SigMinPrecision>> getSigMinPrecisions();
0482
0483 #define D3D_SYSTEM_VALUE(Val, Enum) Enum = Val,
0484 enum class D3DSystemValue : uint32_t {
0485 #include "DXContainerConstants.def"
0486 };
0487
0488 ArrayRef<EnumEntry<D3DSystemValue>> getD3DSystemValues();
0489
0490 #define COMPONENT_TYPE(Val, Enum) Enum = Val,
0491 enum class SigComponentType : uint32_t {
0492 #include "DXContainerConstants.def"
0493 };
0494
0495 ArrayRef<EnumEntry<SigComponentType>> getSigComponentTypes();
0496
0497 struct ProgramSignatureHeader {
0498 uint32_t ParamCount;
0499 uint32_t FirstParamOffset;
0500
0501 void swapBytes() {
0502 sys::swapByteOrder(ParamCount);
0503 sys::swapByteOrder(FirstParamOffset);
0504 }
0505 };
0506
0507 struct ProgramSignatureElement {
0508 uint32_t Stream;
0509
0510 uint32_t NameOffset;
0511
0512 uint32_t Index;
0513 D3DSystemValue SystemValue;
0514 SigComponentType CompType;
0515 uint32_t Register;
0516 uint8_t Mask;
0517
0518
0519
0520
0521
0522
0523 uint8_t ExclusiveMask;
0524
0525 uint16_t Unused;
0526 SigMinPrecision MinPrecision;
0527
0528 void swapBytes() {
0529 sys::swapByteOrder(Stream);
0530 sys::swapByteOrder(NameOffset);
0531 sys::swapByteOrder(Index);
0532 sys::swapByteOrder(SystemValue);
0533 sys::swapByteOrder(CompType);
0534 sys::swapByteOrder(Register);
0535 sys::swapByteOrder(Mask);
0536 sys::swapByteOrder(ExclusiveMask);
0537 sys::swapByteOrder(MinPrecision);
0538 }
0539 };
0540
0541 static_assert(sizeof(ProgramSignatureElement) == 32,
0542 "ProgramSignatureElement is misaligned");
0543
0544 }
0545 }
0546
0547 #endif