588 lines · plain
1=================2DirectX Container3=================4 5.. contents::6 :local:7 8.. toctree::9 :hidden:10 11Overview12========13 14The DirectX Container (DXContainer) file format is the binary file format for15compiled shaders targeting the DirectX runtime. The file format is also called16the DXIL Container or DXBC file format. Because the file format can be used to17include either DXIL or DXBC compiled shaders, the nomenclature in LLVM is simply18DirectX Container.19 20DirectX Container files are read by the compiler and associated tools as well as21the DirectX runtime, profiling tools and other users. This document serves as a22companion to the implementation in LLVM to more completely document the file23format for its many users.24 25Basic Structure26===============27 28A DXContainer file begins with a header, and is then followed by a sequence of29"parts", which are analogous to object file sections. Each part contains a part30header, and some number of bytes of data after the header in a defined format.31 32DX Container data structures are encoded little-endian in the binary file.33 34The LLVM versions of all data structures described and/or referenced in this35file are defined in36`llvm/include/llvm/BinaryFormat/DXContainer.h37<https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/BinaryFormat/DXContainer.h>`_.38Some pseudo code is provided in blocks below to ease understanding of this39document, but reading it with the header available will provide the most40clarity.41 42File Header43-----------44 45.. code-block:: c46 47 struct Header {48 uint8_t Magic[4];49 uint8_t Digest[16];50 uint16_t MajorVersion;51 uint16_t MinorVersion;52 uint32_t FileSize;53 uint32_t PartCount;54 };55 56The DXContainer header matches the pseudo-definition above. It begins with a57four character code (magic number) with the value ``DXBC`` to denote the file58format.59 60The ``Digest`` is a 128bit hash digest computed with a proprietary algorithm and61encoded in the binary by the bytecode validator.62 63The ``MajorVersion`` and ``MinorVersion`` encode the file format version64``1.0``.65 66The remaining fields encode 32-bit unsigned integers for the file size and67number of parts.68 69Following the part header is an array of ``PartCount`` 32-bit unsigned integers70specifying the offsets of each part header.71 72Part Data73---------74 75.. code-block:: c76 77 struct PartHeader {78 uint8_t Name[4];79 uint32_t Size;80 }81 82Each part begins with a part header. A part header includes the 4-character part83name, and a 32-bit unsigned integer specifying the size of the part data. The84part header is followed by ``Size`` bytes of data comprising the part. The85format does not explicitly require 32-bit alignment of parts, although LLVM does86implement this restriction in the writer code (because it's a good idea). The87LLVM object reader code does not assume inputs are correctly aligned to avoid88undefined behavior caused by misaligned inputs generated by other compilers.89 90Part Formats91============92 93The part name indicates the format of the part data. There are 24 part headers94used by DXC and FXC. Not all compiled shaders contain all parts. In the list95below parts generated only by DXC are marked with †, and parts generated only by96FXC are marked with \*.97 98#. `DXIL`_† - Stores the DXIL bytecode.99#. `HASH`_† - Stores the shader MD5 hash.100#. ILDB† - Stores the DXIL bytecode with LLVM Debug Information embedded in the module.101#. ILDN† - Stores shader debug name for external debug information.102#. `ISG1`_ - Stores the input signature for Shader Model 5.1+.103#. ISGN\* - Stores the input signature for Shader Model 4 and earlier.104#. `OSG1`_ - Stores the output signature for Shader Model 5.1+.105#. OSG5\* - Stores the output signature for Shader Model 5.106#. OSGN\* - Stores the output signature for Shader Model 4 and earlier.107#. PCSG\* - Stores the patch constant signature for Shader Model 5.1 and earlier.108#. PDBI† - Stores PDB information.109#. PRIV - Stores arbitrary private data (Not encoded by either FXC or DXC).110#. `PSG1`_ - Stores the patch constant signature for Shader Model 6+.111#. `PSV0`_ - Stores Pipeline State Validation data.112#. RDAT† - Stores Runtime Data.113#. RDEF\* - Stores resource definitions.114#. `RTS0`_ - Stores compiled root signature.115#. `SFI0`_ - Stores shader feature flags.116#. SHDR\* - Stores compiled DXBC bytecode.117#. SHEX\* - Stores compiled DXBC bytecode.118#. DXBC\* - Stores compiled DXBC bytecode.119#. SRCI† - Stores shader source information.120#. STAT† - Stores shader statistics.121#. VERS† - Stores shader compiler version information.122 123DXIL Part124---------125.. _DXIL:126 127The DXIL part is comprised of three data structures: the ``ProgramHeader``, the128``BitcodeHeader`` and the bitcode serialized LLVM 3.7 IR Module.129 130The ``ProgramHeader`` contains the shader model version and pipeline stage131enumeration value. This identifies the target profile of the contained shader132bitcode.133 134The ``BitcodeHeader`` contains the DXIL version information and refers to the135start of the bitcode data.136 137HASH Part138---------139.. _HASH:140 141The HASH part contains a 32-bit unsigned integer with the shader hash flags, and142a 128-bit MD5 hash digest. The flags field can either have the value ``0`` to143indicate no flags, or ``1`` to indicate that the file hash was computed144including the source code that produced the binary.145 146Program Signature (SG1) Parts147-----------------------------148.. _ISG1:149.. _OSG1:150.. _PSG1:151 152.. code-block:: c153 154 struct ProgramSignatureHeader {155 uint32_t ParamCount;156 uint32_t FirstParamOffset;157 }158 159The program signature parts (ISG1, OSG1, & PSG1) all use the same data160structures to encode inputs, outputs and patch information. The161``ProgramSignatureHeader`` includes two 32-bit unsigned integers to specify the162number of signature parameters and the offset of the first parameter.163 164Beginning at ``FirstParamOffset`` bytes from the start of the165``ProgramSignatureHeader``, ``ParamCount`` ``ProgramSignatureElement``166structures are written. Following the ``ProgramSignatureElements`` is a string167table of null terminated strings padded to 32-byte alignment. This string table168matches the DWARF string table format as implemented by LLVM.169 170Each ``ProgramSignatureElement`` encodes a ``NameOffset`` value which specifies171the offset into the string table. A value of ``0`` denotes no name. The offsets172encoded here are from the beginning of the ``ProgramSignatureHeader`` not the173beginning of the string table.174 175The ``ProgramSignatureElement`` contains several enumeration fields which are176defined in `llvm/include/llvm/BinaryFormat/DXContainerConstants.def <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/BinaryFormat/DXContainerConstants.def>`_.177These fields encode the D3D system value, the type of data and its precision178requirements.179 180PSV0 Part181---------182.. _PSV0:183 184The Pipeline State Validation data encodes versioned runtime information185structures. These structures use a scheme where in lieu of encoding a version186number, they encode the size of the structure and each new version of the187structure is additive. This allows readers to infer the version of the structure188by comparing the encoded size with the size of known structures. If the encoded189size is larger than any known structure, the largest known structure can validly190parse the data represented in the known structure.191 192In LLVM we represent the versions of the associated data structures with193versioned namespaces under the ``llvm::dxbc::PSV`` namespace (e.g. ``v0``,194``v1``). Each structure in the ``v0`` namespace is the base version, the195structures in the ``v1`` namespace inherit from the ``v0`` namespace, and the196``v2`` structures inherit from the ``v1`` structures, and so on.197 198The high-level structure of the PSV data is:199 200#. ``RuntimeInfo`` structure201#. Resource bindings202#. Signature elements203#. Mask Vectors (Output, Input, InputPatch, PatchOutput)204 205Immediately following the part header for the PSV0 part is a 32-bit unsigned206integer specifying the size of the ``RuntimeInfo`` structure that follows.207 208Immediately following the ``RuntimeInfo`` structure is a 32-bit unsigned integer209specifying the number of resource bindings. If the number of resources is210greater than zero, another unsigned 32-bit integer follows to specify the size211of the ``ResourceBindInfo`` structure. This is followed by the specified number212of structures of the specified size (which infers the version of the structure).213 214For version 0 of the data this ends the part data.215 216PSV0 Signature Elements217~~~~~~~~~~~~~~~~~~~~~~~218 219The signature elements are conceptually a single concept but the data is encoded220in three different blocks. The first block is a string table, the second block221is an index table, and the third block is the elements themselves, which in turn222are separeated by input, output and patch constant or primitive elements.223 224Signature elements capture much of the same data captured in the :ref:`SG1225<ISG1>` parts. The use of an index table allows de-duplication of data for a more226compact final representation.227 228The string table begins with a 32-bit unsigned integer specifying the table229size. This string table uses the DXContainer format as implemented in LLVM. This230format prefixes the string table with a null byte so that offset ``0`` is a null231string, and pads to 32-byte alignment.232 233The index table begins with a 32-bit unsigned integer specifying the size of the234table, and is followed by that many 32-bit unsigned integers representing the235table. The index table may or may not deduplicate repeated sequences (both DXC236and Clang do). The indices signify the indices in the flattened aggregate237representation which the signature element describes. A single semantic may have238more than one entry in this table to denote the different attributes of its239members.240 241For example given the following code:242 243.. code-block:: c244 245 struct VSOut_1246 {247 float4 f3 : VOUT2;248 float3 f4 : VOUT3;249 };250 251 252 struct VSOut253 {254 float4 f1 : VOUT0;255 float2 f2[4] : VOUT1;256 VSOut_1 s;257 int4 f5 : VOUT4;258 };259 260 void main(out VSOut o1 : A) {261 }262 263The semantic ``A`` gets expanded into 5 output signature elements. Those264elements are:265 266.. note::267 268 In the example below, it is a coincidence that the rows match the indices, in269 more complicated examples with multiple semantics this is not the case.270 271#. Index 0 starts at row 0, contains 4 columns, and is float32. This represents272 ``f1`` in the source.273#. Index 1, 2, 3, and 4 starts at row 1, contains two columns and is float32.274 This represents ``f2`` in the source, and it spreads across rows 1 - 4.275#. Index 5 starts at row 5, contains 4 columns, and is float32. This represents276 ``f3`` in the source.277#. Index 6 starts at row 6, contains 3 columns, and is float32. This represents278 ``f4``.279#. Index 7 starts at row 7, contains 4 columns, and is signed 32-bit integer.280 This represents ``f5`` in the source.281 282The LLVM ``obj2yaml`` tool can parse this data out of the PSV and present it in283human-readable YAML. For the example above it produces the output:284 285.. code-block:: YAML286 287 SigOutputElements:288 - Name: A289 Indices: [ 0 ]290 StartRow: 0291 Cols: 4292 StartCol: 0293 Allocated: true294 Kind: Arbitrary295 ComponentType: Float32296 Interpolation: Linear297 DynamicMask: 0x0298 Stream: 0299 - Name: A300 Indices: [ 1, 2, 3, 4 ]301 StartRow: 1302 Cols: 2303 StartCol: 0304 Allocated: true305 Kind: Arbitrary306 ComponentType: Float32307 Interpolation: Linear308 DynamicMask: 0x0309 Stream: 0310 - Name: A311 Indices: [ 5 ]312 StartRow: 5313 Cols: 4314 StartCol: 0315 Allocated: true316 Kind: Arbitrary317 ComponentType: Float32318 Interpolation: Linear319 DynamicMask: 0x0320 Stream: 0321 - Name: A322 Indices: [ 6 ]323 StartRow: 6324 Cols: 3325 StartCol: 0326 Allocated: true327 Kind: Arbitrary328 ComponentType: Float32329 Interpolation: Linear330 DynamicMask: 0x0331 Stream: 0332 - Name: A333 Indices: [ 7 ]334 StartRow: 7335 Cols: 4336 StartCol: 0337 Allocated: true338 Kind: Arbitrary339 ComponentType: SInt32340 Interpolation: Constant341 DynamicMask: 0x0342 Stream: 0343 344The number of signature elements of each type is encoded in the345``llvm::dxbc::PSV::v1::RuntimeInfo`` structure. If any of the element count346values are non-zero, the size of the ``ProgramSignatureElement`` structure is347encoded next to allow versioning of that structure. Today there is only one348version. Following the size field is the specified number of signature elements349in the order input, output, then patch constant or primitive.350 351Following the signature elements is a sequence of mask vectors encoded as a352series of 32-bit integers. Each 32-bit integer in the mask encodes values for 8353input/output/patch or primitive elements. The mask vector is filled from least354significant bit to most significant bit with each added element shifting the355previous elements left. A reader needs to consult the total number of vectors356encoded in the ``RuntimeInfo`` structure to know how to read the mask vector.357 358If the shader has ``UsesViewID`` enabled in the ``RuntimeInfo`` an output mask359vector will be included. The output mask vector is four arrays of 32-bit360unsigned integers. Each of the four arrays corresponds to an output stream.361Geometry shaders have a maximum of four output streams, all other shader stages362only support one output stream. Each bit in the mask vector identifies one363column of an output from the output signature depends on the ViewID.364 365If the shader has ``UsesViewID`` enabled, it is a hull shader, and it has patch366constant or primitive vector elements, a patch constant or primitive vector mask367will be included. It is identical in structure to the output mask vector. Each368bit in the mask vector identifies one column of a patch constant output which369depends on the ViewID.370 371The next series of mask vectors are similar in structure to the output mask372vector, but they contain an extra dimension.373 374The output/input map is encoded next if the shader has inputs and outputs. The375output/input mask encodes which outputs are impacted by each column of each376input. The size for each mask vector is the size of the output max vector * the377number of inputs * 4 (for each component). Each bit in the mask vector378identifies one column of an output and a column of an input. A value of 1 means379the output is impacted by the input.380 381If the shader is a hull shader, and it has inputs and patch outputs, an input to382patch map will be included next. This is identical in structure to the383output/input map. The dimensions are defined by the size of the patch constant384or primitive vector mask * the number of inputs * 4 (for each component). Each385bit in the mask vector identifies one column of a patch constant output and a386column of an input. A value of 1 means the output is impacted by the input.387 388If the shader is a domain shader, and it has outputs and patch outputs, an389output patch map will be included next. This is identical in structure to the390output/input map. The dimensions are defined by the size of the patch constant391or primitive vector mask * the number of outputs * 4 (for each component). Each392bit in the mask vector identifies one column of a patch constant input and a393column of an output. A value of 1 means the output is impacted by the primitive394input.395 396Root Signature (RTS0) Part397--------------------------398.. _RTS0:399 400The Root Signature data defines the shader's resource interface with Direct3D 40112, specifying what resources the shader needs to access and how they're 402organized and bound to the pipeline. 403 404The RTS0 part comprises three data structures: ``RootSignatureHeader``, 405``RootParameters`` and ``StaticSamplers``. The details of each will be described 406in the following sections. All ``RootParameters`` will be serialized following 407the order they were defined in the metadata representation.408 409The table below summarizes the data being serialized as well as it's size. The 410details of it part will be discussed in further details on the next sections 411of this document.412 413======================== =========================================== =============================414Part Name Size In Bytes Maximum number of Instances 415======================== =========================================== =============================416Root Signature Header 24 1 417Root Parameter Headers 12 Many 418Root Parameter ================================ === Many419 Root Constants 12 420 Root Descriptor Version 1.0 8 421 Root Descriptor Version 1.1 12 422 Descriptors Tables Version 1.0 20 423 Descriptors Tables Version 1.1 24 424 ================================ === 425 426Static Samplers 52 Many 427======================== =========================================== =============================428 429 430Root Signature Header431~~~~~~~~~~~~~~~~~~~~~432 433The root signature header is 24 bytes long, consisting of six 32-bit values434representing the version, number and offset of parameters, number and offset 435of static samplers, and a flags field for global behaviours:436 437.. code-block:: c438 439 struct RootSignatureHeader {440 uint32_t Version;441 uint32_t NumParameters;442 uint32_t ParametersOffset;443 uint32_t NumStaticSamplers;444 uint32_t StaticSamplerOffset;445 uint32_t Flags;446 }447 448 449Root Parameters450~~~~~~~~~~~~~~~451 452Root parameters define how resources are bound to the shader pipeline, each 453type having different size and fields. 454 455The slot of root parameters is preceded by a variable size section containing 456the header information for such parameters. Such structure is 12 bytes long, 457composed of three 32-bit values, representing the parameter type, a flag458encoding the pipeline stages where the data is visible, and an offset 459calculated from the start of RTS0 section.460 461.. code-block:: c462 463 struct RootParameterHeader {464 uint32_t ParameterType;465 uint32_t ShaderVisibility;466 uint32_t ParameterOffset;467 };468 469After the header information has been serialized, the actual data for each of the470root parameters is layout in a single continuous blob. The parameters can be fetch 471from such using the offset information, present in the header.472 473The following sections will describe each of the root parameters types and their 474encodings.475 476Root Constants477''''''''''''''478 479The root constants are inline 32-bit values that show up in the shader 480as a constant buffer. It is a 12 bytes long structure, two 32-bit values481encoding the register and space the constant is assigned to, and 482the last 32 bits encode the number of constants being defined in the buffer.483 484.. code-block:: c485 486 struct RootConstants {487 uint32_t Register;488 uint32_t Space;489 uint32_t NumOfConstants;490 };491 492Root Descriptor493'''''''''''''''494 495Root descriptors provide direct GPU memory addresses to resources.496 497In version 1.0, the root descriptor is 8 bytes. It encodes the register and498space as 2 32-bit values.499 500In version 1.1, the root descriptor is 12 bytes. It matches the 1.0 descriptor501but adds a 32-bit access flag.502 503.. code-block:: c504 505 struct RootDescriptor_V1_0 {506 uint32_t ShaderRegister;507 uint32_t RegisterSpace;508 };509 510 struct RootDescriptor_V1_1 {511 uint32_t ShaderRegister;512 uint32_t RegisterSpace; 513 uint32_t Flags;514 };515 516Root Descriptor Table517'''''''''''''''''''''518 519Descriptor tables let shaders access multiple resources through a single pointer 520to a descriptor heap. 521 522The tables are made of a collection of descriptor ranges. In Version 1.0, the 523descriptor range is 20 bytes, containing five 32-bit values. It encodes a range524of registers, including the register type, range length, register numbers and 525space within range and the offset locating each range inside the table.526 527In version 1.1, the descriptor range is 24 bytes. It matches the 1.0 descriptor528but adds a 32-bit access flag.529 530.. code-block:: c531 532 struct DescriptorRange_V1_0 {533 dxil::ResourceClass RangeType;534 uint32_t NumDescriptors;535 uint32_t BaseShaderRegister;536 uint32_t RegisterSpace;537 uint32_t OffsetInDescriptorsFromTableStart;538 };539 540 struct DescriptorRange_V1_1 {541 dxil::ResourceClass RangeType;542 uint32_t NumDescriptors;543 uint32_t BaseShaderRegister;544 uint32_t RegisterSpace;545 uint32_t Flags;546 uint32_t OffsetInDescriptorsFromTableStart; 547 };548 549Static Samplers550~~~~~~~~~~~~~~~551 552Static samplers are predefined filtering settings built into the root signature, 553avoiding descriptor heap lookups. 554 555This section also has a variable size, since it can contain multiple static 556samplers definitions. However, the definition is a fixed sized struct, 557containing 13 32-byte fields of various enum, float, and integer values. 558 559In version 1.2, the static sampler is 17 bytes. It matches the 1.0 static sampler560but adds a 32-bit access flag. In Version 1.1, it matches static sampler 561version 1.0.562 563.. code-block:: c564 565 struct StaticSamplerDesc {566 dxbc::FilterMode Filter; 567 dxbc::TextureAddressMode AddressU;568 dxbc::TextureAddressMode AddressV;569 dxbc::TextureAddressMode AddressW;570 float MipLODBias;571 uint32_t MaxAnisotropy;572 dxbc::ComparisonFunc ComparisonFunc; 573 dxbc::StaticBorderColor BorderColor;574 float MinLOD;575 float MaxLOD;576 uint32_t ShaderRegister;577 uint32_t RegisterSpace;578 dxbc::ShaderVisibility ShaderVisibility;579 };580 581SFI0 Part582---------583.. _SFI0:584 585The SFI0 part encodes a 64-bit unsigned integer bitmask of the feature flags.586This denotes which optional features the shader requires. The flag values are587defined in `llvm/include/llvm/BinaryFormat/DXContainerConstants.def <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/BinaryFormat/DXContainerConstants.def>`_.588