brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.3 KiB · 46106ee Raw
449 lines · plain
1==============================================================2Specification of DXIL Operations using TableGen Representation3==============================================================4.. contents::5   :local:6 7.. toctree8   :hidden9 10Introduction11============12 13`DirectXShaderCompiler <https://github.com/microsoft/DirectXShaderCompiler>`_14encapsulates, among other information, various DXIL Operations in15`hctdb.py <https://github.com/microsoft/DirectXShaderCompiler/blob/main/utils/hct/hctdb.py>`_.16DXIL Operations are represented in one of the following `two ways17<https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst#operations>`_:18 19#. Using LLVM instructions.20#. Using LLVM External functions. These are represented in LLVM IR as follows:21 22   * "Standard" LLVM intrinsics (e.g., ``llvm.sin.*``) and23   * HLSL intrinsics (defined as LLVM intrinsics in ``llvm/include/llvm/IR/IntrinsicsDirectX.td``, e.g., ``llvm.dx.*``)24 25   These are  collectively referred to as `LLVM Intrinsics` in this note.26 27Following is the complete list of properties of DXIL Ops with the corresponding field name28as used in ``hctdb.py``. A DXIL Op is represented by a set of associated properties. These29are consumed in DXIL backend passes as well as in other usage scenarios such as validation,30DXIL reader, etc.31 32A. Properties consumed in DXIL backend passes33 34   1. Name of operation (``dxil_op``)35   2. A string that documents the operation (``doc``) - This is not strictly necessary but is included36      for readability and documentation of the operation.37   3. The generic or HLSL-specific intrinsic that maps to the operation (``llvm_name``).38   4. Unique Integer ID (``dxil_opid``)39   5. Operation Class signifying the name and function signature of the operation (``dxil_class``).40      This string is an integral part of the DXIL Op function name and is constructed in41      the format ``dx.op.<class-name>.<overload-type>``. Each DXIL Op call target function name42      is required to conform to this format per existing contract with the driver.43   6. List of valid overload types for the operation (``oload_types``).44   7. Required DXIL Version with support for the operation.45   8. Required minimum Shader Model (``shader_model``).46   9. Minimum shader model required with translation by linker (``shader_model_translated``)47   10.  List of shader stages applicable to (``shader_stages``), empty, if applicable to all stages.48   11.  Memory access attributes of the operation (``fn_attr``).49   12.  Boolean attributes of operation to indicate if it50 51        * is some kind of a derivative (``is_derivative``)52        * requires gradient calculation (``is_gradient``)53        * is a sampler feedback (``is_feedback``)54        * requires in-wave, cross-lane functionality (``is_wave``)55        * requires that all of its inputs are uniform across the wave (``requires_uniform_inputs``).56        * is a barrier operation (``is_barrier``).57 58Motivation59==========60 61DXIL backend passes depend on various properties of DXIL Operations. For example, ``DXILOpLowering``62pass will need information such as the DXIL operation an LLVM intrinsic is to be lowered to,63along with valid overload and argument types etc. The TableGen file -64``llvm/lib/Target/DirectX/DXIL.td`` - is used to represent DXIL Operations65by specifying their properties listed above. ``DXIL.td`` is designed to be the single source66of reference of DXIL Operations primarily for the implementation of passes in DXIL backend in67``llvm-project`` repo - analogous to ``hctdb.py`` for ``DirectXShadeCompiler`` repo. However,68the current design does not intend to encapsulate various validation rules, present in ``hctdb.py``,69but do not pertain to DXIL Operations. It needs to have a rich representation capabilities that70TableGen backends (such as ``DXILEmitter``) can rely on. Additionally, the DXIL Op specification71should be easy to read and comprehend.72 73This note provides the design of the specification DXIL Ops as TableGen class ``DXILOp``74by specifying its properties identified above.75 76DXIL Operation Specification77============================78 79The DXIL Operation is represented using the TableGen class ``DXILOp``. The DXIL operation80properties are specified as fields of the ``DXILOp`` class as described below.81 821. Each DXIL Operation is represented as a TableGen record. The name of each of the records83   signifies operation name.842. A documentation string for the operation.853. The LLVM Intrinsic that maps to the operation is represented as ``Intrinsic`` defined in86   `Intrinsics.td <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/Intrinsics.td>`_.874. The unique operation id is represented by an integer.885. DXIL Operation Class is represented as follows89 90   .. code-block::91 92        // Abstraction of DXIL Operation class.93        class DXILOpClass;94 95   Concrete operation records, such as ``unary`` are defined by inheriting from ``DXILOpClass``.966. A set of type names are defined that represent return and argument types,97   which all inherit from ``DXILOpParamType``. These represent simple types98   like ``int32Ty``, DXIL types like ``dx.types.Handle``, and a special99   ``overloadTy`` which can be any type allowed by ``Overloads``, described100   below.1017. Operation return type is represented as a ``DXILOpParamType``, and arguments102   are represented as a list of the same. An operation with no return value103   shall specify ``VoidTy`` as its return.1048. Valid operation overload types predicated on DXIL version are specified as105   a list of ``Overloads`` records. Representation of ``Overloads``106   class is described in a later section.1079.  Valid shader stages predicated on DXIL version are specified as a list of108    ``Stages`` records. Representation of ``Stages`` class is109    described in a later section.11010. Various attributes of the DXIL Operation are represented as a ``list`` of111    ``Attributes`` class records. Representation of ``Attributes``112    class is described in a later section.113 114Types specific to DXIL115----------------------116 117Type notation used in this document viz., ``<size>Ty`` corresponds to TableGen records for118LLVM types ``llvm_<size>_ty``. Apart from ``overloadTy`` described above, ``resRetF32Ty`` is119used to denote resource return type and ``handleTy`` is used to denote handle type.120 121Specification of DXIL Operation122================================123 124A DXIL Operation is represented by the following TableGen class that encapsulates the various125TableGen representations of its properties described above.126 127.. code-block::128 129   // Abstraction DXIL Operation130   class DXILOp<int opcode, DXILOpClass opclass> {131     // A short description of the operation132     string Doc = "";133 134     // Opcode of DXIL Operation135     int OpCode = opcode;136 137     // Class of DXIL Operation.138     DXILOpClass OpClass = opclass;139 140     // LLVM Intrinsic DXIL Operation maps to141     Intrinsic LLVMIntrinsic = ?;142 143     // Result type of the op.144     DXILOpParamType result;145 146     // List of argument types of the op. Default to 0 arguments.147     list<DXILOpParamType> arguments = [];148 149     // List of valid overload types predicated by DXIL version150     list<Overloads> overloads;151 152     // List of valid shader stages predicated by DXIL version153    list<Stages> stages;154 155     // List of valid attributes predicated by DXIL version156     list<Attributes> attributes = [];157   }158 159Version Specification160=====================161 162DXIL version is used to specify various version-dependent operation properties in163place of Shader Model version.164 165A ``Version`` class encapsulating ``Major`` and ``Minor`` version number is defined166as follows:167 168.. code-block::169 170   // Abstract class to represent major and minor version values171   class Version<int major, int minor> {172     int Major = major;173     int Minor = minor;174   }175 176 177Concrete representations of valid DXIL versions are defined as follows:178 179.. code-block::180 181   // Definition of DXIL Version 1.0 - 1.8182   foreach i = 0...8 in {183     def DXIL1_#i : Version<1, i>;184   }185 186Shader Stage Specification187==========================188 189Various shader stages such as ``compute``, ``pixel``, ``vertex``, etc., are represented190as follows191 192.. code-block::193 194   // Shader stages195   class DXILShaderStage;196 197   def compute : DXILShaderStage;198   def pixel : DXILShaderStage;199   def vertex : DXILShaderStage;200   ...201 202Shader Attribute Specification203==============================204 205Various operation memory access and boolean attributes such as ``ReadNone``,206``IsWave`` etc., are represented as follows207 208.. code-block::209 210  class DXILAttribute;211 212  def ReadOnly : DXILOpAttributes;213  def ReadNone : DXILOpAttributes;214  def IsWave : DXILOpAttributes;215  ...216 217Versioned Property Specification218================================219 220DXIL Operation properties such as valid overload types, shader stages and221attributes are predicated on DXIL version. These are represented as list of222versioned properties.223 224Overload Type Specification225---------------------------226 227``overloads`` field of ``class DXILOp`` is used to represent valid operation228overloads predicated on DXIL version as list of records of the following class229 230.. code-block::231 232   class Overloads<Version minver, list<DXILOpParamType> ols> {233     Version dxil_version = minver;234     list<DXILOpParamType> overload_types = ols;235   }236 237Following is an example specification of valid overload types for ``DXIL1_0`` and238``DXIL1_2``.239 240.. code-block::241 242   overloads = [243                 Overloads<DXIL1_0, [halfTy, floatTy]>,244                 Overloads<DXIL1_2, [halfTy, floatTy, doubleTy]>245               ];246 247An empty list signifies that the operation supports no overload types.248 249 250Stages Specification251--------------------252 253``stages`` field of ``class DXILOp`` is used to represent valid operation254stages predicated on DXIL version as list of records of the following class255 256.. code-block::257 258   class Stages<Version minver, list<DXILShaderStage> sts> {259     Version dxil_version = minver;260     list<DXILShaderStage> shader_stages = sts;261   }262 263Following is an example specification of valid stages for ``DXIL1_0``,264``DXIL1_2``, ``DXIL1_4`` and ``DXIL1_6``.265 266.. code-block::267 268   stages = [269             Stages<DXIL1_0, [compute, pixel]>,270             Stages<DXIL1_2, [compute, pixel, mesh]>,271             Stages<DXIL1_4, [all_stages]>,272             Stages<DXIL1_6, [removed]>273            ];274 275The following two pseudo stage records in addition to standard shader stages276are defined.277 2781. ``all_stages`` signifies that the operation is valid for all stages in the279   specified DXIL version and later.2802. ``removed`` signifies removal of support for the operation in the specified281   DXIL version and later.282 283A non-empty list of supported stages is required to be specified. If an operation284is supported in all DXIL versions and all stages it is required to be specified as285 286.. code-block::287 288   stages = [Stages<DXIL1_0, [all_stages]>];289 290 291Attribute Specification292-----------------------293 294``attributes`` field of ``class DXILOp`` is used to represent valid operation295attributes predicated on DXIL version as list of records of the following class296 297.. code-block::298 299  class Attributes<MinVersion minver, list<DXILAttribute> attrs> {300    MinVersion dxil_version = ver;301    list<DXILAttribute> attributes = attrs;302  }303 304Following is an example specification of valid attributes for ``DXIL1_0``.305 306.. code-block::307 308   attributes = [Attributes<DXIL1_0, [ReadNone]];309 310A null list of ``attributes`` signifies no operation attributes.311 312Interpretation of Multiple Versioned Properties313-----------------------------------------------314 315Each of the versioned properties states that the specified overload type, stage or316attribute records are valid for the predicated DXIL version. Only317the properties corresponding to latest minimal DXIL version are applicable.318Note as in the above example, any overload types, stages or attributes,319that remain valid in a later DXIL version need to be specified in full.320For example, consider the following specification of valid overload types:321 322.. code-block::323 324   overloads = [325                Overloads<DXIL1_0, [halfTy, floatTy]>,326                Overloads<DXIL1_2, [halfTy, floatTy, doubleTy]>327               ];328 329It specifies that the overload types ``halfTy`` and ``floatTy`` are valid for DXIL330version 1.0 and later. It also specifies that  ``doubleTy`` is additionally supported331in DXIL version 1.2 and later.332 333This provides the flexibility to specify properties independent of other334versioned specifications in the list.335 336 337DXIL Operation Specification Examples338=====================================339 340Following examples illustrate the specification of some of the DXIL Ops.341 342``Sin`` operation - an operation valid in all DXIL versions and all stages343and has valid overload types predicated on DXIL version.344 345.. code-block::346 347  def Sin : DXILOp<13, unary> {348    let Doc = "Returns sine(theta) for theta in radians.";349    let LLVMIntrinsic = int_sin;350    let result = overloadTy;351    let arguments = [overloadTy];352    let overloads = [Overloads<DXIL1_0, [halfTy, floatTy]>];353    let stages = [Stages<DXIL1_0, [all_stages]>];354    let attributes = [Attributes<DXIL1_0, [ReadNone]>];355  }356 357``FlattenedThreadIdInGroup`` - an operation with no arguments, no358overload types, and valid stages and attributes predicated by DXIL Version.359 360.. code-block::361 362   def FlattenedThreadIdInGroup :  DXILOp<96, flattenedThreadIdInGroup> {363    let Doc = "Provides a flattened index for a given thread within a given "364              "group (SV_GroupIndex)";365    let LLVMIntrinsic = int_dx_flattened_thread_id_in_group;366    let result = i32Ty;367    let stages = [Stages<DXIL1_0, [compute, mesh, amplification, node]>];368    let attributes = [Attributes<DXIL1_0, [ReadNone]>];369   }370 371``RawBufferStore`` - an operation with ``void`` return type, valid overload types372predicated by DXIL Version and valid in all DXIL versions and stages.373 374.. code-block::375 376   def RawBufferStore : DXILOp<140, rawBufferStore> {377     let Doc = "Writes to a RWByteAddressBuffer or RWStructuredBuffer.";378     let result = voidTy;379     let arguments = [dxil_resource_ty, i32Ty, i32Ty, overloadTy,380                      overloadTy, overloadTy, overloadTy, i8Ty, i32Ty];381     let overloads = [382                      Overloads<DXIL1_2, [halfTy, floatTy, i16Ty, i32Ty]>,383                      Overloads<DXIL1_3>,[halfTy, floatTy, doubleTy,384                                                   i16Ty, i32Ty, i64Ty]>385                     ];386      let stages = [Stages<DXIL1_2, all_stages>];387      let attributes = [Attributes<DXIL1_0, [ReadOnly]>];388   }389 390``DerivCoarseX`` - an operation with no overload types and stages predicated391by DXIL Version.392 393.. code-block::394 395   def DerivCoarseX : DXILOp<83, unary> {396    let doc = "Computes the rate of change per stamp in x direction.";397    let LLVMIntrinsic = int_dx_ddx;398    let result = overloadTy;399    let arguments = [overloadTy];400    let stages = [401                   Stages<DXIL1_0, [library, pixel]>,402                   Stages<DXIL1_6, [library, pixel, amplification, compute, mesh]>403                 ];404    let attributes = [Attributes<DXIL1_0, [ReadNone]>];405   }406 407``CreateHandle`` - an operation with no overload types, no associated ``LLVMIntrinsic``408and stages predicated  by DXIL Version.409 410.. code-block::411 412   def CreateHandle : DXILOp<57, createHandle> {413     let doc = "Creates the handle to a resource";414     let result = i32Ty;415     let arguments = [i8Ty, i32Ty, i32Ty, i1Ty];416     let stages = [417                   Stages<DXIL1_0, [all_stages]>,418                   Stages<DXIL1_6, [removed]419                  ];420     let attributes = [Attributes<DXIL1_0, [ReadOnly]>];421   }422 423``Sample`` - an operation with valid overload types, stages and attributes424predicated by DXIL version.425 426.. code-block::427 428   def Sample : DXILOp<60, sample> {429     let Doc = "Samples a texture";430     let LLVMIntrinsic = int_dx_sample;431     let result = resRetF32Ty;432     let arguments = [handleTy, handleTy, floatTy, floatTy, floatTy, floatTy,433                      i32Ty, i32Ty, i32Ty, floatTy];434     let overloads = [Overloads<DXIL1_0, [halfTy, floatTy, i16Ty, i32Ty]>];435     let stages = [436                   Stages<DXIL1_0, [library, pixel]>,437                   Stages<DXIL1_6, [library, pixel, amplification, compute, mesh]>438                  ];439     let attributes = [Attributes<DXIL1_0, [ReadOnly]>];440   }441 442Summary443=======444 445This note sketches the design of a readable and maintainable TableGen specification of446DXIL Ops in ``DXIL.td`` intended to serve as a single source of reference for TableGen447backends (such as ``DXILEmitter``) that generate C++ representations used in DXIL448backend passes.449