[clang] [llvm] [DirectX] Start documenting DXIL Resource handling (PR #90553)
Damyan Pepper via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 30 09:27:15 PDT 2024
================
@@ -0,0 +1,799 @@
+======================
+DXIL Resource Handling
+======================
+
+.. contents::
+ :local:
+
+.. toctree::
+ :hidden:
+
+Introduction
+============
+
+Resources in DXIL are represented via ``TargetExtType`` in LLVM IR and
+eventually lowered by the DirectX backend into metadata in DXIL.
+
+In DXC and DXIL, static resources are represented as lists of SRVs (Shader
+Resource Views), UAVs (Uniform Access Views), CBVs (Constant Bffer Views), and
+Samplers. This metadata consists of a "resource record ID" which uniquely
+identifies a resource and type information. As of shader model 6.6, there are
+also dynamic resources, which forgo the metadata and are described via
+``annotateHandle`` operations in the instruction stream instead.
+
+In LLVM we attempt to unify some of the alternative representations that are
+present in DXC, with the aim of making handling of resources in the middle end
+of the compiler simpler and more consistent.
+
+Resource Type Information and Properties
+========================================
+
+There are a number of properties associated with a resource in DXIL.
+
+`Resource ID`
+ An arbitrary ID that must be unique per resource type (SRV, UAV, etc).
+
+ In LLVM we don't bother representing this, instead opting to generate it at
+ DXIL lowering time.
+
+`Binding information`
+ Information about where the resource comes from. This is either (a) a
+ binding space, lower bound in that space, and size of the binding, or (b) an
+ index into a dynamic resource heap.
+
+ In LLVM we represent binding information in the arguments of the
+ :ref:`handle creation intrinsics <dxil-resources-handles>`. When generating
+ DXIL we transform these calls to metadata, ``dx.op.createHandle``,
+ ``dx.op.createHandleFromBinding``, ``dx.op.createHandleFromHeap``, and
+ ``dx.op.createHandleForLib`` as needed.
+
+`Type information`
+ The type of data that's accessible via the resource. For buffers and
+ textures this can be a simple type like ``float`` or ``float4``, a struct,
+ or raw bytes. For constant buffers this is just a size. For samplers this is
+ the kind of sampler.
+
+ In LLVM we embed this information as a parameter on the ``target()`` type of
+ the resource. See :ref:`dxil-resources-types-of-resource`.
+
+`Resource kind information`
+ The kind of resource. In HLSL we have things like ``ByteAddressBuffer``,
+ ``RWTexture2D``, and ``RasterizerOrderedStructuredBuffer``. These map to a
+ set of DXIL kinds like ``RawBuffer`` and ``Texture2D`` with fields for
+ certain properties such as ``IsUAV`` and ``IsROV``.
+
+ In LLVM we represent this in the ``target()`` type. We omit information
+ that's deriveable from the type information, but we do have fields to encode
+ ``IsWriteable``, ``IsROV``, and ``SampleCount`` when needed.
+
+.. note:: TODO: There are two fields in the DXIL metadata that are not
+ represented as part of the target type: ``IsGloballyCoherent`` and
+ ``HasCounter``.
+
+ Since these are derived from analysis, storing them on the type would mean
+ we need to change the type during the compiler pipeline. That just isn't
+ practical. It isn't entirely clear to me that we need to serialize this info
+ into the IR during the compiler pipeline anyway - we can probably get away
+ with an analysis pass that can calculate the information when we need it.
+
+ If analysis is insufficient we'll need something akin to ``annotateHandle``
+ (but limited to these two properties) or to encode these in the handle
+ creation.
+
+.. _dxil-resources-types-of-resource:
+
+Types of Resource
+=================
+
+We define a set of ``TargetExtTypes`` that is similar to the HLSL
+representations for the various resources, albeit with a few things
+parameterized. This is different than DXIL, as simplifying the types to
+something like "dx.srv" and "dx.uav" types would mean the operations on these
+types would have to be overly generic.
+
+Samplers
+--------
+
+.. code-block:: llvm
+
+ target("dx.Sampler", SamplerType)
+
+The "dx.Sampler" type is used to represent sampler state. The sampler type is
+an enum value from the DXIL ABI, and these appear in sampling operations as
+well as LOD calculations and texture gather.
+
+Constant Buffers
+----------------
+
+.. code-block:: llvm
+
+ target("dx.CBuffer", BufferSize)
+
+The "dx.CBuffer" type is a constant buffer of the given size. Note that despite
+the name this is distinct from the buffer types, and can only be read using the
+"dx.CBufferLoad" and "dx.CBufferLoadLegacy" operations.
+
+Buffers
+-------
+
+.. code-block:: llvm
+
+ target("dx.Buffer", ElementType, IsWriteable, IsROV)
+
+There is only one buffer type. This can represent both UAVs and SRVs via the
+``IsWriteable`` field. Since the type that's encoded is an llvm type, it
+handles both ``Buffer`` and ``StructuredBuffer`` uniformly. For ``RawBuffer``,
+the type is ``i8``, which is unambiguous since ``char`` isn't a legal type in
+HLSL.
+
+These types are generally used by BufferLoad and BufferStore operations, as
+well as atomics.
+
+There are a few fields to describe variants of all of these types:
+
+.. list-table:: Buffer Fields
+ :header-rows: 1
+
+ * - Field
+ - Description
+ * - ElementType
+ - Type for a single element, such as ``i8``, ``v4f32``, or a structure
+ type.
+ * - IsWriteable
+ - Whether or not the field is writeable. This distinguishes SRVs (not
+ writeable) and UAVs (writeable).
+ * - IsROV
+ - Whether the UAV is a rasterizer ordered view. Always ``0`` for SRVs.
+
+Textures
+--------
+
+.. code-block:: llvm
+
+ target("dx.Texture1D", ElementType, IsWriteable, IsROV)
+ target("dx.Texture1D", ...)
+ target("dx.Texture1DArray", ...)
+ target("dx.Texture2D", ...)
+ target("dx.Texture2DArray", ...)
+ target("dx.Texture3D", ...)
+ target("dx.TextureCUBE", ...)
+ target("dx.TextureCUBEArray", ...)
+
+ target("dx.Texture2DMS", ElementType, IsWriteable, IsROV, SampleCount)
+ target("dx.Texture2DMSArray", ...)
+
+ target("dx.FeedbackTexture2D", ElementType, IsWriteable, IsROV, FeedbackType)
+ target("dx.FeedbackTexture2DArray", ...)
+
+There are a number of texture types, but they are mostly interestingly
+different in their dimensions. These are distinct so that we can overload the
+various sample and texture load/store operations such that their parameters are
+appropriate to the type.
+
+.. list-table:: Buffer Fields
----------------
damyanp wrote:
```suggestion
.. list-table:: Texture Fields
```
https://github.com/llvm/llvm-project/pull/90553
More information about the llvm-commits
mailing list