Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:21

0001 //===-- llvm/BinaryFormat/DXContainer.h - The DXBC file format --*- C++/-*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines manifest constants for the DXContainer object file format.
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 // The DXContainer file format is arranged as a header and "parts". Semantically
0026 // parts are similar to sections in other object file formats. The File format
0027 // structure is roughly:
0028 
0029 // ┌────────────────────────────────┐
0030 // │             Header             │
0031 // ├────────────────────────────────┤
0032 // │              Part              │
0033 // ├────────────────────────────────┤
0034 // │              Part              │
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,           // No flags defined.
0053   IncludesSource = 1, // This flag indicates that the shader hash was computed
0054                       // taking into account source information (-Zss)
0055 };
0056 
0057 struct ShaderHash {
0058   uint32_t Flags; // dxbc::HashFlags
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]; // "DXBC"
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   // Structure is followed by part offsets: uint32_t PartOffset[PartCount];
0089   // The offset is to a PartHeader, which is followed by the Part Data.
0090 };
0091 
0092 /// Use this type to describe the size and type of a DXIL container part.
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   // Structure is followed directly by part data: uint8_t PartData[PartSize].
0102 };
0103 
0104 struct BitcodeHeader {
0105   uint8_t Magic[4];     // ACSII "DXIL".
0106   uint8_t MinorVersion; // DXIL version.
0107   uint8_t MajorVersion; // DXIL version.
0108   uint16_t Unused;
0109   uint32_t Offset; // Offset to LLVM bitcode (from start of header).
0110   uint32_t Size;   // Size of LLVM bitcode (in bytes).
0111   // Followed by uint8_t[BitcodeHeader.Size] at &BitcodeHeader + Header.Offset
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; // Size in uint32_t words including this header.
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     // nothing to swap
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     // nothing to swap
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; // minimum lane count required, 0 if unused
0333   uint32_t MaximumWaveLaneCount; // maximum lane count required,
0334                                  // 0xffffffff if unused
0335   void swapBytes() {
0336     // Skip the union because we don't know which field it has
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 } // namespace v0
0387 
0388 namespace v1 {
0389 
0390 struct MeshRuntimeInfo {
0391   uint8_t SigPrimVectors; // Primitive output for MS
0392   uint8_t MeshOutputTopology;
0393 };
0394 
0395 union GeometryExtraInfo {
0396   uint16_t MaxVertexCount;            // MaxVertexCount for GS only (max 1024)
0397   uint8_t SigPatchConstOrPrimVectors; // Output for HS; Input for DS;
0398                                       // Primitive output for MS (overlaps
0399                                       // MeshInfo::SigPrimVectors)
0400   MeshRuntimeInfo MeshInfo;
0401 };
0402 struct RuntimeInfo : public v0::RuntimeInfo {
0403   uint8_t ShaderStage; // PSVShaderKind
0404   uint8_t UsesViewID;
0405   GeometryExtraInfo GeomData;
0406 
0407   // PSVSignatureElement counts
0408   uint8_t SigInputElements;
0409   uint8_t SigOutputElements;
0410   uint8_t SigPatchOrPrimElements;
0411 
0412   // Number of packed vectors per signature
0413   uint8_t SigInputVectors;
0414   uint8_t SigOutputVectors[4];
0415 
0416   void swapBytes() {
0417     // nothing to swap since everything is single-byte or a union field
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 } // namespace v1
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 } // namespace v2
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 } // namespace v3
0474 } // namespace PSV
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;     // Stream index (parameters must appear in non-decreasing
0509                        // stream order)
0510   uint32_t NameOffset; // Offset from the start of the ProgramSignatureHeader to
0511                        // the start of the null terminated string for the name.
0512   uint32_t Index;      // Semantic Index
0513   D3DSystemValue SystemValue; // Semantic type. Similar to PSV::SemanticKind.
0514   SigComponentType CompType;  // Type of bits.
0515   uint32_t Register;          // Register Index (row index)
0516   uint8_t Mask;               // Mask (column allocation)
0517 
0518   // The ExclusiveMask has a different meaning for input and output signatures.
0519   // For an output signature, masked components of the output register are never
0520   // written to.
0521   // For an input signature, masked components of the input register are always
0522   // read.
0523   uint8_t ExclusiveMask;
0524 
0525   uint16_t Unused;
0526   SigMinPrecision MinPrecision; // Minimum precision of input/output data
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 } // namespace dxbc
0545 } // namespace llvm
0546 
0547 #endif // LLVM_BINARYFORMAT_DXCONTAINER_H