Files
gps/tools/local/circt/include/llvm/BinaryFormat/DXContainer.h
T
2026-07-12 11:01:51 +03:00

1045 lines
28 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//===-- llvm/BinaryFormat/DXContainer.h - The DXBC file format --*- C++/-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines manifest constants for the DXContainer object file format.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_BINARYFORMAT_DXCONTAINER_H
#define LLVM_BINARYFORMAT_DXCONTAINER_H
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DXILABI.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/TargetParser/Triple.h"
#include <stdint.h>
namespace llvm {
template <typename T> struct EnumEntry;
// The DXContainer file format is arranged as a header and "parts". Semantically
// parts are similar to sections in other object file formats. The File format
// structure is roughly:
// ┌────────────────────────────────┐
// │ Header │
// ├────────────────────────────────┤
// │ Part │
// ├────────────────────────────────┤
// │ Part │
// ├────────────────────────────────┤
// │ ... │
// └────────────────────────────────┘
namespace dxbc {
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
constexpr static uint64_t DXCONTAINER_STRUCT_ALIGNMENT = 4;
inline Triple::EnvironmentType getShaderStage(uint32_t Kind) {
assert(Kind <= Triple::RootSignature - Triple::Pixel &&
"Shader kind out of expected range.");
return static_cast<Triple::EnvironmentType>(Triple::Pixel + Kind);
}
struct Hash {
uint8_t Digest[16];
};
enum class HashFlags : uint32_t {
None = 0, // No flags defined.
IncludesSource = 1, // This flag indicates that the shader hash was computed
// taking into account source information (-Zss)
};
struct ShaderHash {
uint32_t Flags; // dxbc::HashFlags
uint8_t Digest[16];
LLVM_ABI bool isPopulated();
void swapBytes() { sys::swapByteOrder(Flags); }
};
struct ContainerVersion {
uint16_t Major;
uint16_t Minor;
void swapBytes() {
sys::swapByteOrder(Major);
sys::swapByteOrder(Minor);
}
};
struct Header {
uint8_t Magic[4]; // "DXBC"
Hash FileHash;
ContainerVersion Version;
uint32_t FileSize;
uint32_t PartCount;
void swapBytes() {
Version.swapBytes();
sys::swapByteOrder(FileSize);
sys::swapByteOrder(PartCount);
}
// Structure is followed by part offsets: uint32_t PartOffset[PartCount];
// The offset is to a PartHeader, which is followed by the Part Data.
};
/// Use this type to describe the size and type of a DXIL container part.
struct PartHeader {
uint8_t Name[4];
uint32_t Size;
void swapBytes() { sys::swapByteOrder(Size); }
StringRef getName() const {
return StringRef(reinterpret_cast<const char *>(&Name[0]), 4);
}
// Structure is followed directly by part data: uint8_t PartData[PartSize].
};
struct BitcodeHeader {
uint8_t Magic[4]; // ACSII "DXIL".
uint8_t MinorVersion; // DXIL version.
uint8_t MajorVersion; // DXIL version.
uint16_t Unused;
uint32_t Offset; // Offset to LLVM bitcode (from start of header).
uint32_t Size; // Size of LLVM bitcode (in bytes).
// Followed by uint8_t[BitcodeHeader.Size] at &BitcodeHeader + Header.Offset
void swapBytes() {
sys::swapByteOrder(MinorVersion);
sys::swapByteOrder(MajorVersion);
sys::swapByteOrder(Offset);
sys::swapByteOrder(Size);
}
};
struct ProgramHeader {
uint8_t Version;
uint8_t Unused;
uint16_t ShaderKind;
uint32_t Size; // Size in uint32_t words including this header.
BitcodeHeader Bitcode;
void swapBytes() {
sys::swapByteOrder(ShaderKind);
sys::swapByteOrder(Size);
Bitcode.swapBytes();
}
uint8_t getMajorVersion() { return Version >> 4; }
uint8_t getMinorVersion() { return Version & 0xF; }
static uint8_t getVersion(uint8_t Major, uint8_t Minor) {
return (Major << 4) | Minor;
}
};
static_assert(sizeof(ProgramHeader) == 24, "ProgramHeader Size incorrect!");
#define CONTAINER_PART(Part) Part,
enum class PartType {
Unknown = 0,
#include "DXContainerConstants.def"
};
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) Val = 1ull << Num,
enum class FeatureFlags : uint64_t {
#include "DXContainerConstants.def"
};
static_assert((uint64_t)FeatureFlags::NextUnusedBit <= 1ull << 63,
"Shader flag bits exceed enum size.");
#define ROOT_SIGNATURE_FLAG(Num, Val) Val = Num,
enum class RootFlags : uint32_t {
#include "DXContainerConstants.def"
LLVM_MARK_AS_BITMASK_ENUM(SamplerHeapDirectlyIndexed)
};
LLVM_ABI ArrayRef<EnumEntry<RootFlags>> getRootFlags();
#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag) Enum = Num,
enum class RootDescriptorFlags : uint32_t {
#include "DXContainerConstants.def"
LLVM_MARK_AS_BITMASK_ENUM(DataStatic)
};
LLVM_ABI ArrayRef<EnumEntry<RootDescriptorFlags>> getRootDescriptorFlags();
#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag) Enum = Num,
enum class DescriptorRangeFlags : uint32_t {
#include "DXContainerConstants.def"
LLVM_MARK_AS_BITMASK_ENUM(DescriptorsStaticKeepingBufferBoundsChecks)
};
LLVM_ABI ArrayRef<EnumEntry<DescriptorRangeFlags>> getDescriptorRangeFlags();
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) Enum = Num,
enum class StaticSamplerFlags : uint32_t {
#include "DXContainerConstants.def"
LLVM_MARK_AS_BITMASK_ENUM(NonNormalizedCoordinates)
};
LLVM_ABI ArrayRef<EnumEntry<StaticSamplerFlags>> getStaticSamplerFlags();
#define ROOT_PARAMETER(Val, Enum) Enum = Val,
enum class RootParameterType : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<RootParameterType>> getRootParameterTypes();
LLVM_ABI_FOR_TEST bool isValidParameterType(uint32_t V);
LLVM_ABI bool isValidRangeType(uint32_t V);
#define SHADER_VISIBILITY(Val, Enum) Enum = Val,
enum class ShaderVisibility : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<ShaderVisibility>> getShaderVisibility();
LLVM_ABI bool isValidShaderVisibility(uint32_t V);
#define FILTER(Val, Enum) Enum = Val,
enum class SamplerFilter : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI bool isValidSamplerFilter(uint32_t V);
LLVM_ABI ArrayRef<EnumEntry<SamplerFilter>> getSamplerFilters();
#define TEXTURE_ADDRESS_MODE(Val, Enum) Enum = Val,
enum class TextureAddressMode : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<TextureAddressMode>> getTextureAddressModes();
LLVM_ABI bool isValidAddress(uint32_t V);
#define COMPARISON_FUNC(Val, Enum) Enum = Val,
enum class ComparisonFunc : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<ComparisonFunc>> getComparisonFuncs();
LLVM_ABI bool isValidComparisonFunc(uint32_t V);
#define STATIC_BORDER_COLOR(Val, Enum) Enum = Val,
enum class StaticBorderColor : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI bool isValidBorderColor(uint32_t V);
LLVM_ABI bool isValidRootDesciptorFlags(uint32_t V);
LLVM_ABI bool isValidDescriptorRangeFlags(uint32_t V);
LLVM_ABI bool isValidStaticSamplerFlags(uint32_t V);
LLVM_ABI ArrayRef<EnumEntry<StaticBorderColor>> getStaticBorderColors();
LLVM_ABI PartType parsePartType(StringRef S);
LLVM_ABI bool isDebugProgramPart(PartType PT);
LLVM_ABI const char *getProgramPartName(bool IsDebug);
LLVM_ABI bool isProgramPart(StringRef PartName);
struct VertexPSVInfo {
uint8_t OutputPositionPresent;
uint8_t Unused[3];
void swapBytes() {
// nothing to swap
}
};
struct HullPSVInfo {
uint32_t InputControlPointCount;
uint32_t OutputControlPointCount;
uint32_t TessellatorDomain;
uint32_t TessellatorOutputPrimitive;
void swapBytes() {
sys::swapByteOrder(InputControlPointCount);
sys::swapByteOrder(OutputControlPointCount);
sys::swapByteOrder(TessellatorDomain);
sys::swapByteOrder(TessellatorOutputPrimitive);
}
};
struct DomainPSVInfo {
uint32_t InputControlPointCount;
uint8_t OutputPositionPresent;
uint8_t Unused[3];
uint32_t TessellatorDomain;
void swapBytes() {
sys::swapByteOrder(InputControlPointCount);
sys::swapByteOrder(TessellatorDomain);
}
};
struct GeometryPSVInfo {
uint32_t InputPrimitive;
uint32_t OutputTopology;
uint32_t OutputStreamMask;
uint8_t OutputPositionPresent;
uint8_t Unused[3];
void swapBytes() {
sys::swapByteOrder(InputPrimitive);
sys::swapByteOrder(OutputTopology);
sys::swapByteOrder(OutputStreamMask);
}
};
struct PixelPSVInfo {
uint8_t DepthOutput;
uint8_t SampleFrequency;
uint8_t Unused[2];
void swapBytes() {
// nothing to swap
}
};
struct MeshPSVInfo {
uint32_t GroupSharedBytesUsed;
uint32_t GroupSharedBytesDependentOnViewID;
uint32_t PayloadSizeInBytes;
uint16_t MaxOutputVertices;
uint16_t MaxOutputPrimitives;
void swapBytes() {
sys::swapByteOrder(GroupSharedBytesUsed);
sys::swapByteOrder(GroupSharedBytesDependentOnViewID);
sys::swapByteOrder(PayloadSizeInBytes);
sys::swapByteOrder(MaxOutputVertices);
sys::swapByteOrder(MaxOutputPrimitives);
}
};
struct AmplificationPSVInfo {
uint32_t PayloadSizeInBytes;
void swapBytes() { sys::swapByteOrder(PayloadSizeInBytes); }
};
union PipelinePSVInfo {
VertexPSVInfo VS;
HullPSVInfo HS;
DomainPSVInfo DS;
GeometryPSVInfo GS;
PixelPSVInfo PS;
MeshPSVInfo MS;
AmplificationPSVInfo AS;
void swapBytes(Triple::EnvironmentType Stage) {
switch (Stage) {
case Triple::EnvironmentType::Pixel:
PS.swapBytes();
break;
case Triple::EnvironmentType::Vertex:
VS.swapBytes();
break;
case Triple::EnvironmentType::Geometry:
GS.swapBytes();
break;
case Triple::EnvironmentType::Hull:
HS.swapBytes();
break;
case Triple::EnvironmentType::Domain:
DS.swapBytes();
break;
case Triple::EnvironmentType::Mesh:
MS.swapBytes();
break;
case Triple::EnvironmentType::Amplification:
AS.swapBytes();
break;
default:
break;
}
}
};
static_assert(sizeof(PipelinePSVInfo) == 4 * sizeof(uint32_t),
"Pipeline-specific PSV info must fit in 16 bytes.");
namespace PSV {
#define SEMANTIC_KIND(Val, Enum) Enum = Val,
enum class SemanticKind : uint8_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<SemanticKind>> getSemanticKinds();
#define COMPONENT_TYPE(Val, Enum) Enum = Val,
enum class ComponentType : uint8_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<ComponentType>> getComponentTypes();
#define INTERPOLATION_MODE(Val, Enum) Enum = Val,
enum class InterpolationMode : uint8_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<InterpolationMode>> getInterpolationModes();
#define RESOURCE_TYPE(Val, Enum) Enum = Val,
enum class ResourceType : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<ResourceType>> getResourceTypes();
#define RESOURCE_KIND(Val, Enum) Enum = Val,
enum class ResourceKind : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<ResourceKind>> getResourceKinds();
#define RESOURCE_FLAG(Index, Enum) bool Enum = false;
struct ResourceFlags {
ResourceFlags() : Flags(0U) {};
struct FlagsBits {
#include "llvm/BinaryFormat/DXContainerConstants.def"
};
union {
uint32_t Flags;
FlagsBits Bits;
};
bool operator==(const uint32_t RFlags) const { return Flags == RFlags; }
};
namespace v0 {
struct RuntimeInfo {
PipelinePSVInfo StageInfo;
uint32_t MinimumWaveLaneCount; // minimum lane count required, 0 if unused
uint32_t MaximumWaveLaneCount; // maximum lane count required,
// 0xffffffff if unused
void swapBytes() {
// Skip the union because we don't know which field it has
sys::swapByteOrder(MinimumWaveLaneCount);
sys::swapByteOrder(MaximumWaveLaneCount);
}
void swapBytes(Triple::EnvironmentType Stage) { StageInfo.swapBytes(Stage); }
};
struct ResourceBindInfo {
ResourceType Type;
uint32_t Space;
uint32_t LowerBound;
uint32_t UpperBound;
void swapBytes() {
sys::swapByteOrder(Type);
sys::swapByteOrder(Space);
sys::swapByteOrder(LowerBound);
sys::swapByteOrder(UpperBound);
}
};
struct SignatureElement {
uint32_t NameOffset;
uint32_t IndicesOffset;
uint8_t Rows;
uint8_t StartRow;
uint8_t Cols : 4;
uint8_t StartCol : 2;
uint8_t Allocated : 1;
uint8_t Unused : 1;
SemanticKind Kind;
ComponentType Type;
InterpolationMode Mode;
uint8_t DynamicMask : 4;
uint8_t Stream : 2;
uint8_t Unused2 : 2;
uint8_t Reserved;
void swapBytes() {
sys::swapByteOrder(NameOffset);
sys::swapByteOrder(IndicesOffset);
}
};
static_assert(sizeof(SignatureElement) == 4 * sizeof(uint32_t),
"PSV Signature elements must fit in 16 bytes.");
} // namespace v0
namespace v1 {
struct MeshRuntimeInfo {
uint8_t SigPrimVectors; // Primitive output for MS
uint8_t MeshOutputTopology;
};
union GeometryExtraInfo {
uint16_t MaxVertexCount; // MaxVertexCount for GS only (max 1024)
uint8_t SigPatchConstOrPrimVectors; // Output for HS; Input for DS;
// Primitive output for MS (overlaps
// MeshInfo::SigPrimVectors)
MeshRuntimeInfo MeshInfo;
};
struct RuntimeInfo : public v0::RuntimeInfo {
uint8_t ShaderStage; // PSVShaderKind
uint8_t UsesViewID;
GeometryExtraInfo GeomData;
// PSVSignatureElement counts
uint8_t SigInputElements;
uint8_t SigOutputElements;
uint8_t SigPatchOrPrimElements;
// Number of packed vectors per signature
uint8_t SigInputVectors;
uint8_t SigOutputVectors[4];
void swapBytes() {
// nothing to swap since everything is single-byte or a union field
}
void swapBytes(Triple::EnvironmentType Stage) {
v0::RuntimeInfo::swapBytes(Stage);
if (Stage == Triple::EnvironmentType::Geometry)
sys::swapByteOrder(GeomData.MaxVertexCount);
}
};
} // namespace v1
namespace v2 {
struct RuntimeInfo : public v1::RuntimeInfo {
uint32_t NumThreadsX;
uint32_t NumThreadsY;
uint32_t NumThreadsZ;
void swapBytes() {
sys::swapByteOrder(NumThreadsX);
sys::swapByteOrder(NumThreadsY);
sys::swapByteOrder(NumThreadsZ);
}
void swapBytes(Triple::EnvironmentType Stage) {
v1::RuntimeInfo::swapBytes(Stage);
}
};
struct ResourceBindInfo : public v0::ResourceBindInfo {
ResourceKind Kind;
ResourceFlags Flags;
void swapBytes() {
v0::ResourceBindInfo::swapBytes();
sys::swapByteOrder(Kind);
sys::swapByteOrder(Flags.Flags);
}
};
} // namespace v2
namespace v3 {
struct RuntimeInfo : public v2::RuntimeInfo {
// Offset into the string table, which is stored separately in the PSV0 part.
// The entry name string itself is not stored in the RuntimeInfo record.
uint32_t EntryNameOffset;
void swapBytes() {
v2::RuntimeInfo::swapBytes();
sys::swapByteOrder(EntryNameOffset);
}
void swapBytes(Triple::EnvironmentType Stage) {
v2::RuntimeInfo::swapBytes(Stage);
}
};
} // namespace v3
} // namespace PSV
#define COMPONENT_PRECISION(Val, Enum) Enum = Val,
enum class SigMinPrecision : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<SigMinPrecision>> getSigMinPrecisions();
#define D3D_SYSTEM_VALUE(Val, Enum) Enum = Val,
enum class D3DSystemValue : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<D3DSystemValue>> getD3DSystemValues();
#define COMPONENT_TYPE(Val, Enum) Enum = Val,
enum class SigComponentType : uint32_t {
#include "DXContainerConstants.def"
};
LLVM_ABI ArrayRef<EnumEntry<SigComponentType>> getSigComponentTypes();
struct ProgramSignatureHeader {
uint32_t ParamCount;
uint32_t FirstParamOffset;
void swapBytes() {
sys::swapByteOrder(ParamCount);
sys::swapByteOrder(FirstParamOffset);
}
};
struct ProgramSignatureElement {
uint32_t Stream; // Stream index (parameters must appear in non-decreasing
// stream order)
uint32_t NameOffset; // Offset from the start of the ProgramSignatureHeader to
// the start of the null terminated string for the name.
uint32_t Index; // Semantic Index
D3DSystemValue SystemValue; // Semantic type. Similar to PSV::SemanticKind.
SigComponentType CompType; // Type of bits.
uint32_t Register; // Register Index (row index)
uint8_t Mask; // Mask (column allocation)
// The ExclusiveMask has a different meaning for input and output signatures.
// For an output signature, masked components of the output register are never
// written to.
// For an input signature, masked components of the input register are always
// read.
uint8_t ExclusiveMask;
uint16_t Unused;
SigMinPrecision MinPrecision; // Minimum precision of input/output data
void swapBytes() {
sys::swapByteOrder(Stream);
sys::swapByteOrder(NameOffset);
sys::swapByteOrder(Index);
sys::swapByteOrder(SystemValue);
sys::swapByteOrder(CompType);
sys::swapByteOrder(Register);
sys::swapByteOrder(Mask);
sys::swapByteOrder(ExclusiveMask);
sys::swapByteOrder(MinPrecision);
}
};
static_assert(sizeof(ProgramSignatureElement) == 32,
"ProgramSignatureElement is misaligned");
namespace RTS0 {
namespace v1 {
struct StaticSampler {
uint32_t Filter;
uint32_t AddressU;
uint32_t AddressV;
uint32_t AddressW;
float MipLODBias;
uint32_t MaxAnisotropy;
uint32_t ComparisonFunc;
uint32_t BorderColor;
float MinLOD;
float MaxLOD;
uint32_t ShaderRegister;
uint32_t RegisterSpace;
uint32_t ShaderVisibility;
void swapBytes() {
sys::swapByteOrder(Filter);
sys::swapByteOrder(AddressU);
sys::swapByteOrder(AddressV);
sys::swapByteOrder(AddressW);
sys::swapByteOrder(MipLODBias);
sys::swapByteOrder(MaxAnisotropy);
sys::swapByteOrder(ComparisonFunc);
sys::swapByteOrder(BorderColor);
sys::swapByteOrder(MinLOD);
sys::swapByteOrder(MaxLOD);
sys::swapByteOrder(ShaderRegister);
sys::swapByteOrder(RegisterSpace);
sys::swapByteOrder(ShaderVisibility);
};
};
struct DescriptorRange {
uint32_t RangeType;
uint32_t NumDescriptors;
uint32_t BaseShaderRegister;
uint32_t RegisterSpace;
uint32_t OffsetInDescriptorsFromTableStart;
void swapBytes() {
sys::swapByteOrder(RangeType);
sys::swapByteOrder(NumDescriptors);
sys::swapByteOrder(BaseShaderRegister);
sys::swapByteOrder(RegisterSpace);
sys::swapByteOrder(OffsetInDescriptorsFromTableStart);
}
};
struct RootDescriptor {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
void swapBytes() {
sys::swapByteOrder(ShaderRegister);
sys::swapByteOrder(RegisterSpace);
}
};
// following dx12 naming
// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_root_constants
struct RootConstants {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
uint32_t Num32BitValues;
void swapBytes() {
sys::swapByteOrder(ShaderRegister);
sys::swapByteOrder(RegisterSpace);
sys::swapByteOrder(Num32BitValues);
}
};
struct RootParameterHeader {
uint32_t ParameterType;
uint32_t ShaderVisibility;
uint32_t ParameterOffset;
void swapBytes() {
sys::swapByteOrder(ParameterType);
sys::swapByteOrder(ShaderVisibility);
sys::swapByteOrder(ParameterOffset);
}
};
struct RootSignatureHeader {
uint32_t Version;
uint32_t NumParameters;
uint32_t ParametersOffset;
uint32_t NumStaticSamplers;
uint32_t StaticSamplerOffset;
uint32_t Flags;
void swapBytes() {
sys::swapByteOrder(Version);
sys::swapByteOrder(NumParameters);
sys::swapByteOrder(ParametersOffset);
sys::swapByteOrder(NumStaticSamplers);
sys::swapByteOrder(StaticSamplerOffset);
sys::swapByteOrder(Flags);
}
};
} // namespace v1
namespace v2 {
struct RootDescriptor : public v1::RootDescriptor {
uint32_t Flags;
RootDescriptor() = default;
explicit RootDescriptor(v1::RootDescriptor &Base)
: v1::RootDescriptor(Base), Flags(0u) {}
void swapBytes() {
v1::RootDescriptor::swapBytes();
sys::swapByteOrder(Flags);
}
};
struct DescriptorRange {
uint32_t RangeType;
uint32_t NumDescriptors;
uint32_t BaseShaderRegister;
uint32_t RegisterSpace;
uint32_t Flags;
uint32_t OffsetInDescriptorsFromTableStart;
void swapBytes() {
sys::swapByteOrder(RangeType);
sys::swapByteOrder(NumDescriptors);
sys::swapByteOrder(BaseShaderRegister);
sys::swapByteOrder(RegisterSpace);
sys::swapByteOrder(OffsetInDescriptorsFromTableStart);
sys::swapByteOrder(Flags);
}
};
} // namespace v2
namespace v3 {
struct StaticSampler : public v1::StaticSampler {
uint32_t Flags;
StaticSampler() = default;
explicit StaticSampler(v1::StaticSampler &Base)
: v1::StaticSampler(Base), Flags(0U) {}
void swapBytes() {
v1::StaticSampler::swapBytes();
sys::swapByteOrder(Flags);
}
};
} // namespace v3
} // namespace RTS0
// D3D_ROOT_SIGNATURE_VERSION
enum class RootSignatureVersion {
V1_0 = 0x1,
V1_1 = 0x2,
V1_2 = 0x3,
};
struct DebugNameHeader {
uint16_t Flags;
/// Debug file name length, without null terminator.
uint16_t NameLength;
void swapBytes() {
sys::swapByteOrder(Flags);
sys::swapByteOrder(NameLength);
}
};
static_assert(sizeof(DebugNameHeader) == 4, "DebugNameHeader size incorrect.");
#define VERSION_INFO_FLAG(Num, Val, Str) Val = Num,
enum class CompilerVersionFlags : uint32_t {
#include "llvm/BinaryFormat/DXContainerConstants.def"
LLVM_MARK_AS_BITMASK_ENUM(Internal)
};
LLVM_ABI bool isValidCompilerVersionFlags(uint32_t V);
struct CompilerVersionHeader {
uint16_t Major;
uint16_t Minor;
CompilerVersionFlags Flags;
/// The number outputted by `git rev-list --count HEAD` in the compiler repo.
uint32_t CommitCount;
/// Byte size of CommitSha and CustomVersionString, padding not included.
uint32_t ContentSizeInBytes;
void swapBytes() {
sys::swapByteOrder(Major);
sys::swapByteOrder(Minor);
sys::swapByteOrder(Flags);
sys::swapByteOrder(CommitCount);
sys::swapByteOrder(ContentSizeInBytes);
}
};
static_assert(sizeof(CompilerVersionHeader) == 16,
"CompilerVersionHeader size incorrect.");
namespace SourceInfo {
struct Header {
/// Part size including this header. Aligned to a 4-byte boundary.
uint32_t AlignedSizeInBytes;
/// Reserved, must be zero.
uint16_t Flags;
/// Source info part must contain 3 sections. Each section is 4-byte aligned.
uint16_t SectionCount;
void swapBytes() {
sys::swapByteOrder(AlignedSizeInBytes);
sys::swapByteOrder(Flags);
sys::swapByteOrder(SectionCount);
}
};
static_assert(sizeof(Header) == 8, "SourceInfo::Header size incorrect.");
#define SOURCE_INFO_TYPE(Num, Val) Val = Num,
enum class SectionType : uint16_t {
#include "llvm/BinaryFormat/DXContainerConstants.def"
LLVM_MARK_AS_BITMASK_ENUM(Args)
};
LLVM_ABI ArrayRef<EnumEntry<SectionType>> getSectionTypes();
LLVM_ABI bool isValidSectionType(uint16_t V);
LLVM_ABI StringRef getSectionName(SectionType Type);
struct SectionHeader {
/// Section size including this header. Aligned to a 4-byte boundary.
uint32_t AlignedSizeInBytes;
/// Reserved, must be zero.
uint16_t Flags;
SectionType Type;
void swapBytes() {
sys::swapByteOrder(AlignedSizeInBytes);
sys::swapByteOrder(Flags);
sys::swapByteOrder(Type);
}
};
static_assert(sizeof(SectionHeader) == 8,
"SourceInfo::SectionHeader size incorrect.");
namespace Names {
LLVM_PACKED(struct HeaderOnDisk {
/// Reserved, must be zero.
uint32_t Flags;
/// The number of data entries.
uint32_t Count;
/// The total size of the data entries following this header. Each entry is
/// 4-byte padded.
uint16_t EntriesSizeInBytes;
});
static_assert(sizeof(HeaderOnDisk) == 10,
"SourceInfo::Names::HeaderOnDisk size incorrect.");
struct Entry {
/// Size of entry, including this header. Aligned to a 4-byte boundary.
uint32_t AlignedSizeInBytes;
/// Reserved, must be set to zero.
uint32_t Flags;
/// Size of the file name following this header, including the null
/// terminator, excluding entry padding.
uint32_t NameSizeInBytes;
/// Size of the file content, including the null terminator.
uint32_t ContentSizeInBytes;
/// Followed by a string of size NameSizeInBytes with HLSL source file name.
void swapBytes() {
sys::swapByteOrder(AlignedSizeInBytes);
sys::swapByteOrder(Flags);
sys::swapByteOrder(NameSizeInBytes);
sys::swapByteOrder(ContentSizeInBytes);
}
};
static_assert(sizeof(Entry) == 16, "SourceInfo::Names::Entry size incorrect.");
} // namespace Names
namespace Contents {
#define COMPRESSION_TYPE(Num, Val) Val = Num,
enum class CompressionType : uint16_t {
#include "llvm/BinaryFormat/DXContainerConstants.def"
LLVM_MARK_AS_BITMASK_ENUM(Zlib)
};
LLVM_ABI ArrayRef<EnumEntry<CompressionType>> getCompressionTypes();
LLVM_ABI bool isValidCompressionType(uint16_t V);
struct Header {
/// Size of the section including this header. Aligned to a 4-byte boundary.
/// In some implementations, it is unused and set to zero.
uint32_t AlignedSizeInBytes;
/// Reserved, must be zero.
uint16_t Flags;
/// Type of compression used to compress the whole section content.
CompressionType Type;
/// The size of the data entries following this header.
/// Aligned to a 4-byte boundary if Type is None.
/// Doesn’t have to be aligned otherwise.
uint32_t EntriesSizeInBytes;
/// Total size of the data entries when uncompressed. Aligned to a 4-byte
/// boundary.
uint32_t UncompressedEntriesSizeInBytes;
/// The number of data entries.
uint32_t Count;
void swapBytes() {
sys::swapByteOrder(AlignedSizeInBytes);
sys::swapByteOrder(Flags);
sys::swapByteOrder(Type);
sys::swapByteOrder(EntriesSizeInBytes);
sys::swapByteOrder(UncompressedEntriesSizeInBytes);
sys::swapByteOrder(Count);
}
};
static_assert(sizeof(Header) == 20,
"SourceInfo::Contents::Header size incorrect.");
struct Entry {
/// Size of entry, including this header. Aligned to a 4-byte boundary.
uint32_t AlignedSizeInBytes;
/// Reserved, must be zero.
uint32_t Flags;
/// Size of the file contents following this header, including the null
/// terminator, excluding entry padding.
uint32_t ContentSizeInBytes;
/// Followed by a string of length ContentSizeInBytes-1 with HLSL source file
/// content.
/// Entry is aligned to 4-bytes (in uncompressed form).
/// Entries of this section must be stored in the same order as the entries of
/// the Names section.
void swapBytes() {
sys::swapByteOrder(AlignedSizeInBytes);
sys::swapByteOrder(Flags);
sys::swapByteOrder(ContentSizeInBytes);
}
};
static_assert(sizeof(Entry) == 12,
"SourceInfo::Contents::Entry size incorrect.");
} // namespace Contents
namespace Args {
struct Header {
/// Reserved, must be zero.
uint32_t Flags;
/// Length of all argument pairs, including their null terminators, not
/// including this header.
uint32_t SizeInBytes;
/// Number of arguments.
uint32_t Count;
/// Followed by Count argument pairs, representing command line arguments of
/// the HLSL compiler invocation. Each pair consists of argument name and
/// argument value null-terminated strings. Padding is not applied to the
/// pairs.
void swapBytes() {
sys::swapByteOrder(Flags);
sys::swapByteOrder(SizeInBytes);
sys::swapByteOrder(Count);
}
};
static_assert(sizeof(Header) == 12, "SourceInfo::Args::Header size incorrect.");
} // namespace Args
} // namespace SourceInfo
} // namespace dxbc
} // namespace llvm
#endif // LLVM_BINARYFORMAT_DXCONTAINER_H