Browse Source

[spirv] Update SPIR-V.rst doc (#596)

Moved logistics and designs to the wiki page. Now the doc is only
for HLSL to SPIR-V mappings.

Also link to the doc and wiki page in the main README.md.
Lei Zhang 8 years ago
parent
commit
bc1301af13
2 changed files with 395 additions and 404 deletions
  1. 4 0
      README.md
  2. 391 404
      docs/SPIR-V.rst

+ 4 - 0
README.md

@@ -22,6 +22,10 @@ The Microsoft Windows SDK releases include a supported version of the compiler a
 
 The goal of the project is to allow the broader community of shader developers to contribute to the language and representation of shader programs, maintaining the principles of compatibility and supportability for the platform. It's currently in active development across two axes: language evolution (with no impact to DXIL representation), and surfacing hardware capabilities (with impact to DXIL, and thus requiring coordination with GPU implementations).
 
+### SPIR-V CodeGen
+
+As an example of community contribution, this project can also target the [SPIR-V](https://www.khronos.org/registry/spir-v/) intermediate representation. Please see the [doc](docs/SPIR-V.rst) for how HLSL features are mapped to SPIR-V, and the [wiki](https://github.com/Microsoft/DirectXShaderCompiler/wiki/SPIR%E2%80%90V-CodeGen) page for how to build, use, and contribute to the SPIR-V CodeGen.
+
 ## Building Sources
 
 Before you build, you will need to have some additional software installed. This is the most straightforward path - see [Building Sources](https://github.com/Microsoft/DirectXShaderCompiler/wiki/Building-Sources) on the Wiki for more options, including Visual Studio 2015 and Ninja support.

+ 391 - 404
docs/SPIR-V.rst

@@ -1,6 +1,6 @@
-==============
-SPIR-V Codegen
-==============
+=====================================
+HLSL to SPIR-V Feature Mapping Manual
+=====================================
 
 .. contents::
    :local:
@@ -9,11 +9,16 @@ SPIR-V Codegen
 Introduction
 ============
 
-This document describes the designs and logistics for supporting SPIR-V codegen
-functionality. `SPIR-V <https://www.khronos.org/registry/spir-v/>`_ is a binary
-intermediate language for representing graphical-shader stages and compute
-kernels for multiple Khronos APIs, such as Vulkan, OpenGL, and OpenCL. At the
-moment we only intend to support the Vulkan flavor of SPIR-V.
+This document describes the mappings from HLSL features to SPIR-V for Vulkan
+adopted by the SPIR-V codegen. For how to build, use, or contribute to the
+SPIR-V codegen and its internals, please see the
+`wiki <https://github.com/Microsoft/DirectXShaderCompiler/wiki/SPIR%E2%80%90V-CodeGen>`_
+page.
+
+`SPIR-V <https://www.khronos.org/registry/spir-v/>`_ is a binary intermediate
+language for representing graphical-shader stages and compute kernels for
+multiple Khronos APIs, such as Vulkan, OpenGL, and OpenCL. At the moment we
+only intend to support the Vulkan flavor of SPIR-V.
 
 DirectXShaderCompiler is the reference compiler for HLSL. Adding SPIR-V codegen
 in DirectXShaderCompiler will enable the usage of HLSL as a frontend language
@@ -23,139 +28,132 @@ developers. Moreover, developers will also have a unified compiler toolchain for
 targeting both DirectX and Vulkan. We believe this effort will benefit the
 general graphics ecosystem.
 
-Mapping From HLSL to SPIR-V for Vulkan
-======================================
-
-Due to the differences of semantics between DirectX and Vulkan, certain HLSL
-features do not have corresponding mappings in Vulkan, and certain Vulkan
-specific information does not have native ways to express in HLSL source code.
-This section will capture the mappings we use to conduct the translation.
-Specifically, it lists the mappings from HLSL shader model 6.0 to Vulkan flavor
-of SPIR-V.
+Note that this document is expected to be an ongoing effort and grow as we
+implement more and more HLSL features.
 
-Note that this section is expected to be an ongoing effort and grow as we
-implement more and more HLSL features. We are likely to extract the contents in
-this section into a new doc in the future.
+Vulkan Semantics
+================
 
 Note that the term "semantic" is overloaded. In HLSL, it can mean the string
 attached to shader input or output. For such cases, we refer it as "HLSL
 semantic" or "semantic string". For other cases, we just use the normal
 "semantic" term.
 
-Vulkan semantics
-----------------
+Due to the differences of semantics between DirectX and Vulkan, certain HLSL
+features do not have corresponding mappings in Vulkan, and certain Vulkan
+specific information does not have native ways to express in HLSL source code.
 
 To provide additional information required by Vulkan in HLSL, we need to extend
 the syntax of HLSL.
 `C++ attribute specifier sequence <http://en.cppreference.com/w/cpp/language/attributes>`_
 is a non-intrusive way of achieving such purpose.
 
-For example, to specify the layout of Vulkan resources:
+For example, to specify the layout of resource variables and the location of
+interface variables:
 
 .. code:: hlsl
 
-  [[vk::binding(X, Y)]]
-  tbuffer TbufOne {
-    [[vk::offset(Z)]]
-    float4 field;
-  };
+  struct S { ... };
 
-  [[vk::push_constant]]
-  tbuffer TbufTwo {
-    float4 field;
-  };
+  [[vk::binding(X, Y)]]
+  StructuredBuffer<S> mySBuffer;
 
-  [[vk::constant_id(M)]]
-  const int specConst = N;
+  [[vk::location(M)]] float4
+  main([[vk::location(N)]] float4 input: A) : B
+  { ... }
 
 The namespace ``vk`` will be used for all Vulkan attributes:
 
 - ``location(X)``: For specifying the location (``X``) numbers for stage
   input/output variables. Allowed on function parameters, function returns,
   and struct fields.
-- ``binding(X[, Y]): For specifying the descriptor set (``Y``) and binding
+- ``binding(X[, Y])``: For specifying the descriptor set (``Y``) and binding
   (``X``) numbers for resource variables. The descriptor set (``Y``) is
-  optional; if missing, it will be 0. Allowed on global variables.
+  optional; if missing, it will be set to 0. Allowed on global variables.
 
 Only ``vk::`` attributes in the above list are supported. Other attributes will
 result in warnings and be ignored by the compiler. All C++11 attributes will
 only trigger warnings and be ignored if not compiling towards SPIR-V.
 
-HLSL types
-----------
+HLSL Types
+==========
 
 This section lists how various HLSL types are mapped.
 
 Normal scalar types
-+++++++++++++++++++
+-------------------
 
 `Normal scalar types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509646(v=vs.85).aspx>`_
 in HLSL are relatively easy to handle and can be mapped directly to SPIR-V
-instructions:
+type instructions:
 
-================== ==================
-      HLSL               SPIR-V
-================== ==================
+================== ================== =========== ====================
+      HLSL               SPIR-V       Capability       Decoration
+================== ================== =========== ====================
 ``bool``           ``OpTypeBool``
 ``int``            ``OpTypeInt 32 1``
 ``uint``/``dword`` ``OpTypeInt 32 0``
-``half``           ``OpTypeFloat 16``
+``half``           ``OpTypeFloat 32``             ``RelexedPrecision``
 ``float``          ``OpTypeFloat 32``
-``double``         ``OpTypeFloat 64``
-================== ==================
+``double``         ``OpTypeFloat 64`` ``Float64``
+================== ================== =========== ====================
+
+Please note that ``half`` is translated into 32-bit floating point numbers
+right now because MSDN says that "this data type is provided only for language
+compatibility. Direct3D 10 shader targets map all ``half`` data types to
+``float`` data types." This may change in the future to map to 16-bit floating
+point numbers (possibly via a command-line option).
+
+Note: ``float`` and ``double`` not implemented yet
 
 Minimal precision scalar types
-++++++++++++++++++++++++++++++
+------------------------------
 
 HLSL also supports various
 `minimal precision scalar types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509646(v=vs.85).aspx>`_,
 which graphics drivers can implement by using any precision greater than or
 equal to their specified bit precision.
+There are no direct mappings in SPIR-V for these types. We translate them into
+the corresponding 32-bit scalar types with the ``RelexedPrecision`` decoration:
 
-- ``min16float`` - minimum 16-bit floating point value
-- ``min10float`` - minimum 10-bit floating point value
-- ``min16int`` - minimum 16-bit signed integer
-- ``min12int`` - minimum 12-bit signed integer
-- ``min16uint`` - minimum 16-bit unsigned integer
+============== ================== ====================
+    HLSL            SPIR-V            Decoration
+============== ================== ====================
+``min16float`` ``OpTypeFloat 32`` ``RelexedPrecision``
+``min10float`` ``OpTypeFloat 32`` ``RelexedPrecision``
+``min16int``   ``OpTypeInt 32 1`` ``RelexedPrecision``
+``min12int``   ``OpTypeInt 32 1`` ``RelexedPrecision``
+``min16uint``  ``OpTypeInt 32 0`` ``RelexedPrecision``
+============== ================== ====================
 
-There are no direct mapping in SPIR-V for these types. We may need to use
-``OpTypeFloat``/``OpTypeInt`` with ``RelaxedPrecision`` for some of them and
-issue warnings/errors for the rest.
+Note: not implemented yet
 
 Vectors and matrices
-++++++++++++++++++++
+--------------------
 
 `Vectors <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509707(v=vs.85).aspx>`_
 and `matrices <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509623(v=vs.85).aspx>`_
 are translated into:
 
-+-------------------------------------+---------------------------------------+
-|               HLSL                  |             SPIR-V                    |
-+=====================================+=======================================+
-| ``|type||count|``                   |                                       |
-+-------------------------------------+  ``OpTypeVector |type| |count|``      |
-| ``vector<|type|, |count|>``         |                                       |
-+-------------------------------------+---------------------------------------+
-| ``matrix<|type|, |row|, |column|>`` | ``%v = OpTypeVector |type| |column|`` |
-+-------------------------------------+                                       |
-| ``|type||row|x|column|``            | ``OpTypeMatrix %v |row|``             |
-+-------------------------------------+---------------------------------------+
-
-Note that vectors of size 1 are just translated into scalar values of the
-element types since SPIR-V mandates the size of vector to be at least 2.
-
-Also, matrices whose row or column count is 1 are translated into the
-corresponding vector types with the same element type. Matrices of size 1x1 are
-translated into scalars.
-
-A MxN HLSL matrix is translated into a SPIR-V matrix with M columns, each with
+==================================== ====================================================
+              HLSL                                         SPIR-V
+==================================== ====================================================
+``|type|N`` (``N`` > 1)              ``OpTypeVector |type| N``
+``|type|1``                          The scalar type for ``|type|``
+``|type|MxN`` (``M`` > 1, ``N`` > 1) ``%v = OpTypeVector |type| N`` ``OpTypeMatrix %v M``
+``|type|Mx1`` (``M`` > 1)            ``OpTypeVector |type| M``
+``|type|1xN`` (``N`` > 1)            ``OpTypeVector |type| N``
+``|type|1x1``                        The scalar type for ``|type|``
+==================================== ====================================================
+
+A MxN HLSL matrix is translated into a SPIR-V matrix with M vectors, each with
 N elements. Conceptually HLSL matrices are row-major while SPIR-V matrices are
 column-major, thus all HLSL matrices are represented by their transposes.
 Doing so may require special handling of certain matrix operations:
 
 - **Indexing**: no special handling required. ``matrix[m][n]`` will still access
   the correct element since ``m``/``n`` means the ``m``-th/``n``-th row/column
-  in HLSL but ``m``-th/``n``-th column/element in SPIR-V.
+  in HLSL but ``m``-th/``n``-th vector/element in SPIR-V.
 - **Per-element operation**: no special handling required.
 - **Matrix multiplication**: need to swap the operands. ``mat1 x mat2`` should
   be translated as ``transpose(mat2) x transpose(mat1)``. Then the result is
@@ -166,34 +164,60 @@ Doing so may require special handling of certain matrix operations:
   packed together, they should be loaded into a column/row correspondingly.
 
 Structs
-+++++++
+-------
 
 `Structs <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509668(v=vs.85).aspx>`_
 in HLSL are defined in the a format similar to C structs. They are translated
-into SPIR-V ``OpTypeStruct``. Semantics attached to struct members are handled
-in the `entry function wrapper`_.
+into SPIR-V ``OpTypeStruct``. Depending on the storage classes of the instances,
+a single struct definition may generate multiple ``OpTypeStruct`` instructions
+in SPIR-V. For example, for the following HLSL source code:
+
+.. code:: hlsl
+
+  struct S { ... }
+
+  ConstantBuffer<S>   myCBuffer;
+  StructuredBuffer<S> mySBuffer;
+
+  float4 main() : A {
+    S myLocalVar;
+    ...
+  }
 
-Structs can have optional interpolation modifiers for members:
+There will be there different ``OpTypeStruct`` generated, one for each variable
+defined in the above source code. This is because the ``OpTypeStruct`` for
+both ``myCBuffer`` and ``mySBuffer`` will have layout decorations (``Offset``,
+``MatrixStride``, ``ArrayStride``, ``RowMajor``, ``ColMajor``). However, their
+layout rules are different (by default); ``myCBuffer`` will use GLSL ``std140``
+while ``mySBuffer`` will use GLSL ``std430``. ``myLocalVar`` will have its
+``OpTypeStruct`` without layout decorations. Read more about storage classes
+in the `Buffers`_ section.
 
-=========================== =================
-HLSL Interpolation Modifier SPIR-V Decoration
-=========================== =================
+Structs used as stage inputs/outputs will have semantics attached to their
+members. These semantics are handled in the `entry function wrapper`_.
+
+Structs used as pixel shader inputs can have optional interpolation modifiers
+for their members, which will be translated according to the following table:
+
+=========================== ================= =====================
+HLSL Interpolation Modifier SPIR-V Decoration   SPIR-V Capability
+=========================== ================= =====================
 ``linear``                  <none>
 ``centroid``                ``Centroid``
 ``nointerpolation``         ``Flat``
 ``noperspective``           ``NoPerspective``
-``sample``                  ``Sample``
-=========================== =================
+``sample``                  ``Sample``        ``SampleRateShading``
+=========================== ================= =====================
 
 User-defined types
-++++++++++++++++++
+------------------
 
 `User-defined types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509702(v=vs.85).aspx>`_
 are type aliases introduced by typedef. No new types are introduced and we can
 rely on Clang to resolve to the original types.
 
 Samplers
-++++++++
+--------
 
 All `sampler types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509644(v=vs.85).aspx>`_
 will be translated into SPIR-V ``OpTypeSampler``.
@@ -202,33 +226,197 @@ SPIR-V ``OpTypeSampler`` is an opaque type that cannot be parameterized;
 therefore state assignments on sampler types is not supported (yet).
 
 Textures
-++++++++
+--------
 
 `Texture types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509700(v=vs.85).aspx>`_
 are translated into SPIR-V ``OpTypeImage``, with parameters:
 
-====================   ==== ===== ======= == ======= ============
-HLSL Texture Type      Dim  Depth Arrayed MS Sampled Image Format
-====================   ==== ===== ======= == ======= ============
-``Texture1D``          1D    0       0    0    1       Unknown
-``Texture2D``          2D    0       0    0    1       Unknown
-``Texture3D``          3D    0       0    0    1       Unknown
-``TextureCube``        Cube  0       0    0    1       Unknown
-``Texture1DArray``     1D    0       1    0    1       Unknown
-``Texture2DArray``     2D    0       1    0    1       Unknown
-``TextureCubeArray``   3D    0       1    0    1       Unknown
-====================   ==== ===== ======= == ======= ============
+====================   ========== ===== ======= == ======= ================ =================
+HLSL Texture Type          Dim    Depth Arrayed MS Sampled  Image Format       Capability
+====================   ========== ===== ======= == ======= ================ =================
+``Texture1D``          ``1D``      0       0    0    1     ``Unknown``
+``Texture2D``          ``2D``      0       0    0    1     ``Unknown``
+``Texture3D``          ``3D``      0       0    0    1     ``Unknown``
+``TextureCube``        ``Cube``    0       0    0    1     ``Unknown``
+``Texture1DArray``     ``1D``      0       1    0    1     ``Unknown``
+``Texture2DArray``     ``2D``      0       1    0    1     ``Unknown``
+``TextureCubeArray``   ``3D``      0       1    0    1     ``Unknown``
+``Buffer<T>``          ``Buffer``  0       0    0    1     Depends on ``T`` ``SampledBuffer``
+``RWBuffer<T>``        ``Buffer``  0       0    0    2     Depends on ``T`` ``SampledBuffer``
+====================   ========== ===== ======= == ======= ================ =================
 
 The meanings of the headers in the above table is explained in ``OpTypeImage``
 of the SPIR-V spec.
 
 Buffers
-+++++++
+-------
 
-[TODO]
+There are serveral buffer types in HLSL:
+
+- ``cbuffer`` and ``ConstantBuffer``
+- ``tbuffer`` and ``TextureBuffer``
+- ``StructuredBuffer`` and ``RWStructuredBuffer``
+- ``AppendStructuredBuffer`` and ``ConsumeStructuredBuffer``
+
+Please see the following sections for the details of each type. As a summary:
+
+=========================== ================== ========================== ==================== =================
+         HLSL Type          Vulkan Buffer Type Default Memory Layout Rule SPIR-V Storage Class SPIR-V Decoration
+=========================== ================== ========================== ==================== =================
+``cbuffer``                   Uniform Buffer      GLSL ``std140``            ``Uniform``        ``Block``
+``ConstantBuffer``            Uniform Buffer      GLSL ``std140``            ``Uniform``        ``Block``
+``StructuredBuffer``          Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
+``RWStructuredBuffer``        Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
+``AppendStructuredBuffer``    Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
+``ConsumeStructuredBuffer``   Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
+=========================== ================== ========================== ==================== =================
+
+To know more about the Vulkan buffer types, please refer to the Vulkan spec
+`13.1 Descriptor Types <https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/html/vkspec.html#descriptorsets-types>`_.
+
+``cbuffer`` and ``ConstantBuffer``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These two buffer types are treated as uniform buffers using Vulkan's
+terminology. They are translated into an ``OpTypeStruct`` with the
+necessary layout decorations (``Offset``, ``ArrayStride``, ``MatrixStride``,
+``RowMajor``, ``ColMajor``) and the ``Block`` decoration. The layout rule
+used is GLSL ``std140`` (by default). A variable declared as one of these
+types will be placed in the ``Uniform`` storage class.
+
+For example, for the following HLSL source code:
+
+.. code:: hlsl
+
+  struct T {
+    float  a;
+    float3 b;
+  };
+
+  ConstantBuffer<T> myCBuffer;
+
+will be translated into
+
+.. code:: spirv
+
+  ; Layout decoration
+  OpMemberDecorate %type_ConstantBuffer_T 0 Offset 0
+  OpMemberDecorate %type_ConstantBuffer_T 0 Offset 16
+  ; Block decoration
+  OpDecorate %type_ConstantBuffer_T Block
+
+  ; Types
+  %type_ConstantBuffer_T = OpTypeStruct %float %v3float
+  %_ptr_Uniform_type_ConstantBuffer_T = OpTypePointer Uniform %type_ConstantBuffer_T
+
+  ; Variable
+  %myCbuffer = OpVariable %_ptr_Uniform_type_ConstantBuffer_T Uniform
 
-HLSL variables and resources
-----------------------------
+``StructuredBuffer`` and ``RWStructuredBuffer``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``StructuredBuffer<T>``/``RWStructuredBuffer<T>`` is treated as storage buffer
+using Vulkan's terminology. It is translated into an ``OpTypeStruct`` containing
+an ``OpTypeRuntimeArray`` of type ``T``, with necessary layout decorations
+(``Offset``, ``ArrayStride``, ``MatrixStride``, ``RowMajor``, ``ColMajor``) and
+the ``BufferBlock`` decoration.  The default layout rule used is GLSL
+``std430``. A variable declared as one of these types will be placed in the
+``Uniform`` storage class.
+
+For example, for the following HLSL source code:
+
+.. code:: hlsl
+
+  struct T {
+    float  a;
+    float3 b;
+  };
+
+  StructuredBuffer<T> mySBuffer;
+
+will be translated into
+
+.. code:: spirv
+
+  ; Layout decoration
+  OpMemberDecorate %T 0 Offset 0
+  OpMemberDecorate %T 1 Offset 16
+  OpDecorate %_runtimearr_T ArrayStride 32
+  OpMemberDecorate %type_StructuredBuffer_T 0 Offset 0
+  OpMemberDecorate %type_StructuredBuffer_T 0 NoWritable
+  ; BufferBlock decoration
+  OpDecorate %type_StructuredBuffer_T BufferBlock
+
+  ; Types
+  %T = OpTypeStruct %float %v3float
+  %_runtimearr_T = OpTypeRuntimeArray %T
+  %type_StructuredBuffer_T = OpTypeStruct %_runtimearr_T
+  %_ptr_Uniform_type_StructuredBuffer_T = OpTypePointer Uniform %type_StructuredBuffer_T
+
+  ; Variable
+  %myCbuffer = OpVariable %_ptr_Uniform_type_ConstantBuffer_T Uniform
+
+``AppendStructuredBuffer`` and ``ConsumeStructuredBuffer``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``AppendStructuredBuffer<T>``/``ConsumeStructuredBuffer<T>`` is treated as
+storage buffer using Vulkan's terminology. It is translated into an
+``OpTypeStruct`` containing an ``OpTypeRuntimeArray`` of type ``T``, with
+necessary layout decorations (``Offset``, ``ArrayStride``, ``MatrixStride``,
+``RowMajor``, ``ColMajor``) and the ``BufferBlock`` decoration. The default
+layout rule used is GLSL ``std430``.
+
+A variable declared as one of these types will be placed in the ``Uniform``
+storage class. Besides, each variable will have an associated counter variable
+generated. The counter variable will be of ``OpTypeStruct`` type, which only
+contains a 32-bit integer. The counter variable takes its own binding number.
+``.Append()``/``.Consume()`` will use the counter variable as the index and
+adjust it accordingly.
+
+For example, for the following HLSL source code:
+
+.. code:: hlsl
+
+  struct T {
+    float  a;
+    float3 b;
+  };
+
+  AppendStructuredBuffer<T> mySBuffer;
+
+will be translated into
+
+.. code:: spirv
+
+  ; Layout decorations
+  OpMemberDecorate %T 0 Offset 0
+  OpMemberDecorate %T 1 Offset 16
+  OpDecorate %_runtimearr_T ArrayStride 32
+  OpMemberDecorate %type_AppendStructuredBuffer_T 0 Offset 0
+  OpDecorate %type_AppendStructuredBuffer_T BufferBlock
+  OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
+  OpDecorate %type_ACSBuffer_counter BufferBlock
+
+  ; Binding numbers
+  OpDecorate %myASbuffer DescriptorSet 0
+  OpDecorate %myASbuffer Binding 0
+  OpDecorate %counter_var_myASbuffer DescriptorSet 0
+  OpDecorate %counter_var_myASbuffer Binding 1
+
+  ; Types
+  %T = OpTypeStruct %float %v3float
+  %_runtimearr_T = OpTypeRuntimeArray %T
+  %type_AppendStructuredBuffer_T = OpTypeStruct %_runtimearr_T
+  %_ptr_Uniform_type_AppendStructuredBuffer_T = OpTypePointer Uniform %type_AppendStructuredBuffer_T
+  %type_ACSBuffer_counter = OpTypeStruct %int
+  %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
+
+  ; Variables
+  %myASbuffer = OpVariable %_ptr_Uniform_type_AppendStructuredBuffer_T Uniform
+  %counter_var_myASbuffer = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
+
+HLSL Variables and Resources
+============================
 
 This section lists how various HLSL variables and resources are mapped.
 
@@ -244,7 +432,7 @@ rules::
       [= InitialValue]
 
 Storage class
-+++++++++++++
+-------------
 
 Normal local variables (without any modifier) will be placed in the ``Function``
 SPIR-V storage class.
@@ -255,8 +443,8 @@ SPIR-V storage class.
 - Global variables with ``static`` modifier will be placed in the ``Private``
   SPIR-V storage class. Initalizers of such global variables will be translated
   into SPIR-V ``OpVariable`` initializers if possible; otherwise, they will be
-  initialized at the very beginning of the entry function wrapper using SPIR-V
-  ``OpStore``.
+  initialized at the very beginning of the `entry function wrapper`_ using
+  SPIR-V ``OpStore``.
 - Local variables with ``static`` modifier will also be placed in the
   ``Private`` SPIR-V storage class. initializers of such local variables will
   also be translated into SPIR-V ``OpVariable`` initializers if possible;
@@ -266,12 +454,12 @@ SPIR-V storage class.
   generated to mark its initialization status.
 
 Type modifier
-+++++++++++++
+-------------
 
 [TODO]
 
-HLSL semantic
-+++++++++++++
+HLSL semantic and Vulkan ``Loation``
+------------------------------------
 
 Direct3D uses HLSL "`semantics <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx>`_"
 to compose and match the interfaces between subsequent stages. These semantic
@@ -299,8 +487,8 @@ To translate HLSL to SPIR-V for Vulkan, semantic strings need to be mapped to
 Vulkan ``Location`` numbers properly. This can be done either explicitly via
 information provided by the developer or implicitly by the compiler.
 
-Explicit ``Location`` number assignment in source code
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Explicit ``Location`` number assignment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ``[[vk::location(X)]]`` can be attached to the entities where semantic are
 allowed to attach (struct fields, function parameters, and function returns).
@@ -344,23 +532,25 @@ Firstly, under certain `SigPoints <https://github.com/Microsoft/DirectXShaderCom
 some system-value (SV) semantic strings will be translated into SPIR-V
 ``BuiltIn`` decorations:
 
-+----------------------+----------+--------------------+-----------------------+
-| HLSL Semantic        | SigPoint | SPIR-V ``BuiltIn`` | SPIR-V Execution Mode |
-+======================+==========+====================+=======================+
-|                      | VSOut    | ``Position``       | N/A                   |
-| SV_Position          +----------+--------------------+-----------------------+
-|                      | PSIn     | ``FragCoord``      | N/A                   |
-+----------------------+----------+--------------------+-----------------------+
-| SV_VertexID          | VSIn     | ``VertexIndex``    | N/A                   |
-+----------------------+----------+--------------------+-----------------------+
-| SV_InstanceID        | VSIn     | ``InstanceIndex``  | N/A                   |
-+----------------------+----------+--------------------+-----------------------+
-| SV_Depth             | PSOut    | ``FragDepth``      | N/A                   |
-+----------------------+----------+--------------------+-----------------------+
-| SV_DepthGreaterEqual | PSOut    | ``FragDepth``      | ``DepthGreater``      |
-+----------------------+----------+--------------------+-----------------------+
-| SV_DepthLessEqual    | PSOut    | ``FragDepth``      | ``DepthLess``         |
-+----------------------+----------+--------------------+-----------------------+
++----------------------+----------+------------------------+-----------------------+
+| HLSL Semantic        | SigPoint | SPIR-V ``BuiltIn``     | SPIR-V Execution Mode |
++======================+==========+========================+=======================+
+|                      | VSOut    | ``Position``           | N/A                   |
+| SV_Position          +----------+------------------------+-----------------------+
+|                      | PSIn     | ``FragCoord``          | N/A                   |
++----------------------+----------+------------------------+-----------------------+
+| SV_VertexID          | VSIn     | ``VertexIndex``        | N/A                   |
++----------------------+----------+------------------------+-----------------------+
+| SV_InstanceID        | VSIn     | ``InstanceIndex``      | N/A                   |
++----------------------+----------+------------------------+-----------------------+
+| SV_Depth             | PSOut    | ``FragDepth``          | N/A                   |
++----------------------+----------+------------------------+-----------------------+
+| SV_DepthGreaterEqual | PSOut    | ``FragDepth``          | ``DepthGreater``      |
++----------------------+----------+------------------------+-----------------------+
+| SV_DepthLessEqual    | PSOut    | ``FragDepth``          | ``DepthLess``         |
++----------------------+----------+------------------------+-----------------------+
+| SV_DispatchThreadID  | CSIn     | ``GlobalInvocationId`` | N/A                   |
++----------------------+----------+------------------------+-----------------------+
 
 [TODO] add other SV semantic strings in the above
 
@@ -369,7 +559,7 @@ the above SV semantic strings attached, SPIR-V variables of the
 ``Input``/``Output`` storage class will be created. They will have the
 corresponding SPIR-V ``Builtin``  decorations according to the above table.
 
-SV semantic strings not translated into SPIR-V BuiltIn decorations will be
+SV semantic strings not translated into SPIR-V ``BuiltIn`` decorations will be
 handled similarly as non-SV (arbitrary) semantic strings: a SPIR-V variable
 of the ``Input``/``Output`` storage class will be created for each entity with
 such semantic string. Then sort all semantic strings according to declaration
@@ -382,7 +572,7 @@ There is an exception to the above rule for SV_Target[N]. It will always be
 mapped to ``Location`` number N.
 
 HLSL register and Vulkan binding
-++++++++++++++++++++++++++++++++
+--------------------------------
 
 In shaders for DirectX, resources are accessed via registers; while in shaders
 for Vulkan, it is done via descriptor set and binding numbers. The developer
@@ -391,37 +581,37 @@ numbers, or leave it to the compiler to derive implicitly from registers.
 The explicit way has precedence over the implicit way. However, a mix of both
 way is not allowed (yet).
 
-Explicit descriptor set and binding number assignment
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Explicit binding number assignment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ``[[vk::binding(X[, Y])]]`` can be attached to global variables to specify the
 descriptor set ``Y`` and binding ``X``. The descriptor set number is optional;
 if missing, it will be zero.
 
-Implicit descriptor set and binding number assignment
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Implicit binding number assignment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Without explicit annotations, the compiler will try to deduce descriptor set and
 binding numbers in the following way:
 
 If there is ``:register(xX, spaceY)`` specified for the given global variable,
 the corresponding resource will be assigned to descriptor set ``Y`` and binding
-number ``X``, regardless the resource type `x`. (Note that this can cause
-reassignment of the same set and binding number pair. TODO)
+number ``X``, regardless the resource type ``x``. (Note that this can cause
+reassignment of the same set and binding number pair. [TODO])
 
 If there is no register specification, the corresponding resource will be
 assigned to the next available binding number, starting from 0, in descriptor
 set #0.
 
-HLSL expressions
-----------------
+HLSL Expressions
+================
 
 Unless explicitly noted, matrix per-element operations will be conducted on
 each component vector and then collected into the result matrix. The following
 sections lists the SPIR-V opcodes for scalars and vectors.
 
 Arithmetic operators
-++++++++++++++++++++
+--------------------
 
 `Arithmetic operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Additive_and_Multiplicative_Operators>`_
 (``+``, ``-``, ``*``, ``/``, ``%``) are translated into their corresponding
@@ -456,7 +646,7 @@ operation ``OpVectorTimesScalar`` will be used. Similarly, for multiplications
 of float matrices and float scalars, ``OpMatrixTimesScalar`` will be generated.
 
 Bitwise operators
-+++++++++++++++++
+-----------------
 
 `Bitwise operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Bitwise_Operators>`_
 (``~``, ``&``, ``|``, ``^``, ``<<``, ``>>``) are translated into their
@@ -479,7 +669,7 @@ corresponding SPIR-V opcodes according to the following table.
 +--------+-----------------------------+-------------------------------+
 
 Comparison operators
-++++++++++++++++++++
+--------------------
 
 `Comparison operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Comparison_Operators>`_
 (``<``, ``<=``, ``>``, ``>=``, ``==``, ``!=``) are translated into their
@@ -505,7 +695,7 @@ Note that for comparison of (vectors of) floats, SPIR-V has two sets of
 instructions: ``OpFOrd*``, ``OpFUnord*``. We translate into ``OpFOrd*`` ones.
 
 Boolean math operators
-++++++++++++++++++++++
+----------------------
 
 `Boolean match operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Boolean_Math_Operators>`_
 (``&&``, ``||``, ``?:``) are translated into their corresponding SPIR-V opcodes
@@ -526,7 +716,7 @@ in C, HLSL expressions never short-circuit an evaluation because they are vector
 operations. All sides of the expression are always evaluated."
 
 Unary operators
-+++++++++++++++
+---------------
 
 For `unary operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Unary_Operators>`_:
 
@@ -537,7 +727,7 @@ For `unary operators <https://msdn.microsoft.com/en-us/library/windows/desktop/b
   integers and floats, respectively.
 
 Casts
-+++++
+-----
 
 Casting between (vectors) of scalar types is translated according to the following table:
 
@@ -554,7 +744,7 @@ Casting between (vectors) of scalar types is translated according to the followi
 +------------+-------------------+-------------------+-------------------+-------------------+
 
 Indexing operator
-+++++++++++++++++
+-----------------
 
 The ``[]`` operator can also be used to access elements in a matrix or vector.
 A matrix whose row and/or column count is 1 will be translated into a vector or
@@ -565,13 +755,13 @@ out-of-bound indexing triggers undefined behavior anyway. For example, for a
 ``OpAccessChain ... %mat %uint_0``. Similarly, variable index into a size 1
 vector will also be ignored and the only element will be always returned.
 
-HLSL control flows
-------------------
+HLSL Control Flows
+==================
 
 This section lists how various HLSL control flows are mapped.
 
 Switch statement
-++++++++++++++++
+----------------
 
 HLSL `switch statements <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509669(v=vs.85).aspx>`_
 are translated into SPIR-V using:
@@ -582,7 +772,7 @@ are translated into SPIR-V using:
   ``flatten``, ``branch``, or ``call`` attribute is specified)
 
 Loops (for, while, do)
-++++++++++++++++++++++
+----------------------
 
 HLSL `for statements <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509602(v=vs.85).aspx>`_,
 `while statements <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509708(v=vs.85).aspx>`_,
@@ -605,15 +795,15 @@ masks according to the following table:
 | ``allow_uav_condition`` |           Currently Unimplemented                |
 +-------------------------+--------------------------------------------------+
 
-HLSL functions
---------------
+HLSL Functions
+==============
 
 All functions reachable from the entry-point function will be translated into
 SPIR-V code. Functions not reachable from the entry-point function will be
 ignored.
 
 Entry function wrapper
-++++++++++++++++++++++
+----------------------
 
 HLSL entry functions takes in parameters and returns values. These parameters
 and return values can have semantics attached or if they are struct type,
@@ -707,7 +897,7 @@ manipulation in the wrapper function and handle the source code entry function
 just like other nomal functions.
 
 Function parameter
-++++++++++++++++++
+------------------
 
 For a function ``f`` which has a parameter of type ``T``, the generated SPIR-V
 signature will use type ``T*`` for the parameter. At every call site of ``f``,
@@ -755,7 +945,7 @@ This approach gives us unified handling of function parameters and local
 variables: both of them are accessed via load/store instructions.
 
 Intrinsic functions
-+++++++++++++++++++
+-------------------
 
 The following intrinsic HLSL functions are currently supported:
 
@@ -765,6 +955,9 @@ The following intrinsic HLSL functions are currently supported:
   vectors of integers, we multiply corresponding vector elementes using
   ``OpIMul`` and accumulate the results using ``OpIAdd`` to compute the dot
   product.
+- ``mul``: performs multiplications. Each argument may be a scalar, vector,
+  or matrix. Depending on the argument type, this will be translated into
+  one of the multiplication instructions.
 - ``all``: returns true if all components of the given scalar, vector, or
   matrix are true. Performs conversions to boolean where necessary. Uses SPIR-V
   ``OpAll`` for scalar arguments and vector arguments. For matrix arguments,
@@ -785,252 +978,46 @@ The following intrinsic HLSL functions are currently supported:
   or int into uint. Uses ``OpBitcast``. This method currently does not support
   conversion into unsigned integer matrices.
 
-- Using SPIR-V Extended Instructions for GLSL: the following intrinsic HLSL
-functions are translated using their equivalent instruction in the
-`GLSL extended instruction set <https://www.khronos.org/registry/spir-v/specs/1.0/GLSL.std.450.html>`_.
-
-+-----------------------------+-----------------------------------------------------+
-|   HLSL intrinsic function   |               GLSL Extended Instruction             |
-+=============================+=====================================================+
-|        ``abs``              |   ``SAbs`` for ints, and ``FAbs`` for floats        |
-+-----------------------------+-----------------------------------------------------+
-|        ``acos``             |                       ``Acos``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``asin``             |                       ``Asin``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``atan``             |                       ``Atan``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``ceil``             |                       ``Ceil``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``cos``              |                       ``Cos``                       |
-+-----------------------------+-----------------------------------------------------+
-|        ``cosh``             |                       ``Cosh``                      |
-+-----------------------------+-----------------------------------------------------+
-|       ``degrees``           |                      ``Degrees``                    |
-+-----------------------------+-----------------------------------------------------+
-|       ``radians``           |                      ``Radian``                     |
-+-----------------------------+-----------------------------------------------------+
-|    ``determinant``          |                   ``Determinant``                   |
-+-----------------------------+-----------------------------------------------------+
-|        ``exp``              |                       ``Exp``                       |
-+-----------------------------+-----------------------------------------------------+
-|        ``exp2``             |                       ``exp2``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``floor``            |                       ``Floor``                     |
-+-----------------------------+-----------------------------------------------------+
-|      ``length``             |                     ``Length``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``log``              |                       ``Log``                       |
-+-----------------------------+-----------------------------------------------------+
-|        ``log2``             |                       ``Log2``                      |
-+-----------------------------+-----------------------------------------------------+
-|     ``normalize``           |                   ``Normalize``                     |
-+-----------------------------+-----------------------------------------------------+
-|        ``round``            |                      ``Round``                      |
-+-----------------------------+-----------------------------------------------------+
-|       ``rsqrt``             |                  ``InverseSqrt``                    |
-+-----------------------------+-----------------------------------------------------+
-|       ``sign``              |   ``SSign`` for ints, and ``FSign`` for floats      |
-+-----------------------------+-----------------------------------------------------+
-|        ``sin``              |                       ``Sin``                       |
-+-----------------------------+-----------------------------------------------------+
-|        ``sinh``             |                       ``Sinh``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``tan``              |                       ``Tan``                       |
-+-----------------------------+-----------------------------------------------------+
-|        ``tanh``             |                       ``Tanh``                      |
-+-----------------------------+-----------------------------------------------------+
-|        ``sqrt``             |                       ``Sqrt``                      |
-+-----------------------------+-----------------------------------------------------+
-|       ``trunc``             |                      ``Trunc``                      |
-+-----------------------------+-----------------------------------------------------+
-
-Designs
-=======
-
-Various designs are driven by technical considerations together with the
-following guidelines for good citizenship within DirectXShaderCompiler:
-
-- Conduct minimal changes to existing interfaces and libraries
-- Perfer less intrusive solutions
-
-General approach
-----------------
-
-The general approach is to translate frontend AST directly into SPIR-V binary.
-We choose this approach considering that
-
-- Frontend AST is much more higher-level than DXIL. For example,
-  `DXIL scalarized vectors <https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/DXIL.rst#vectors>`_
-  but SPIR-V has native support.
-- DXIL has widely different semantics than Vulkan flavor of SPIR-V. For example,
-  `structured control flow is not preserved in DXIL <https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/DXIL.rst#control-flow-restrictions>`_
-  but SPIR-V for Vulkan requires it.
-- Frontend AST perserves the information in the source code better.
-- Also, the right place to generate error messages is in Clang's semantic
-  analysis step, which is when the compiler is still processing the AST.
-
-Therefore, it is easier to go from frontend AST to SPIR-V than from DXIL since
-we do not need to rediscover certain information.
-
-LLVM optimization passes
-++++++++++++++++++++++++
-
-Translating frontend AST directly into SPIR-V binary precludes the usage of
-existing LLVM optimization passes. This is expected since there are also subtle
-semantics differences between SPIR-V and LLVM IR. Certain concepts in SPIR-V
-do not have direct corresponding representation in LLVM IR and there are no
-existing translation schemes handling the differences. Using vanilla LLVM
-optimization passes will likely violate the requirements of SPIR-V and results
-in invalid SPIR-V modules.
-
-Instead, optimizations are available in the
-`SPIRV-Tools <https://github.com/KhronosGroup/SPIRV-Tools>`_ project.
-
-Library
--------
-
-On the library side, this means introducing a new ``ASTFrontendAction`` and a
-SPIR-V module builder.  The new frontend action will traverse the AST and call
-the SPIR-V module builder to construct SPIR-V words. These code should be
-placed at ``tools/clang/lib/SPIRV`` and packed into one library (or multiple
-libraries in the future).
-
-Detailed design will be revised to accommodate more and more HLSL features.
-At the moment, we have::
-
-                EmitSPIRVAction
-                     |
-                     | creates
-                     V
-                SPIRVEmitter
-                     |
-                     | contains
-                     |
-       +-------------+------------+
-       |                          |
-       |                          |
-       V         references       V
-  SPIRVContext <------------ ModuleBuilder
-                                  |
-                                  | contains
-                                  V
-                              InstBuilder
-                                  |
-                                  | depends on
-                                  V
-                             WordConsumer
-
-- ``SPIRVEmitter``: The derived ``ASTConsumer`` which acts on various frontend
-  AST nodes by calling corresponding ``ModuleBuilder`` methods to build SPIR-V
-  modules gradually.
-- ``ModuleBuilder``: Exposes API for constructing SPIR-V modules. Internally it
-  has structured representation of SPIR-V modules, functions, basic blocks as
-  well as various SPIR-V specific structs like entry points, debug names, and
-  so on.
-- ``SPIRVContext``: Responsible for <result-id> allocation and maintaining the
-  lifetime of objects allocated to represent types, decorations, and others.
-  It is used in conjunction with ``ModuleBuilder``.
-- ``InstBuilder``: The low-level interface for generating SPIR-V words for
-  various SPIR-V instructions. All SPIR-V instructions are eventually serialized
-  via ``InstBuilder``.
-- ``WordConsumer``: The consumer of generated SPIR-V words.
-
-Command-line tool
------------------
-
-On the command-line tool side, this means introducing a new binary,
-``hlsl2spirv`` to wrap around the library functionality.
-
-But as the initial scaffolding step, a new option, ``-spirv``, will be added
-into ``dxc`` for invoking the new SPIR-V codegen action.
-
-Testing
--------
-
-`GoogleTest <https://github.com/google/googletest>`_ will be used as both the
-unit test and the SPIR-V codegen test framework.
-
-Unit tests will be placed under the ``tools/clang/unittests/SPIRV/`` directory,
-while SPIR-V codegen tests will be placed under the
-``tools/clang/test/CodeGenSPIRV/`` directory.
-
-For SPIR-V codegen tests, there are two test fixtures: one for checking the
-whole disassembly of the generated SPIR-V code, the other is
-`FileCheck <https://llvm.org/docs/CommandGuide/FileCheck.html>`_-like, for
-partial pattern matching.
-
-- **Whole disassembly check**: These tests are in files with suffix
-  ``.hlsl2spv``. Each file consists of two parts, HLSL source code input and
-  expected SPIR-V disassembly ouput, delimited by ``// CHECK-WHOLE-SPIR-V:``.
-  The compiler takes in the whole file as input and compile its into SPIR-V
-  binary. The test fixture then disasembles the SPIR-V binary and compares the
-  disassembly with the expected disassembly listed after
-  ``// CHECK-WHOLE-SPIR-V``.
-- **Partial disassembly match**: These tests are in files with suffix ``.hlsl``.
-  `Effcee <https://github.com/google/effcee>`_ is used for the stateful pattern
-  matching. Effcee itself depends on a regular expression library,
-  `RE2 <https://github.com/google/re2>`_. See Effcee for supported ``CHECK``
-  syntax. They are largely the same as LLVM FileCheck.
-
-Dependencies
-------------
-
-SPIR-V codegen functionality will require two external projects:
-`SPIRV-Headers <https://github.com/KhronosGroup/SPIRV-Headers>`_
-(for ``spirv.hpp11``) and
-`SPIRV-Tools <https://github.com/KhronosGroup/SPIRV-Tools>`_
-(for SPIR-V disassembling). These two projects should be checked out under
-the ``external/`` directory.
-
-The three projects for testing, GoogleTest, Effcee, and RE2, should also be
-checked out under the ``external/`` directory.
-
-Build system
-------------
-
-SPIR-V codegen functionality will structured as an optional feature in
-DirectXShaderCompiler. Two new CMake options will be introduced to control the
-configuring and building SPIR-V codegen:
-
-- ``ENABLE_SPIRV_CODEGEN``: If turned on, enables the SPIR-V codegen
-  functionality. (Default: OFF)
-- ``SPIRV_BUILD_TESTS``: If turned on, enables building of SPIR-V related tests.
-  This option will also implicitly turn on ``ENABLE_SPIRV_CODEGEN``.
-  (Default: OFF)
-
-For building, ``hctbuild`` will be extended with two new switches, ``-spirv``
-and ``-spirvtest``, to turn on the above two options, respectively.
-
-For testing, ``hcttest spirv`` will run all existing tests together with SPIR-V
-tests, while ``htctest spirv_only`` will only trigger SPIR-V tests.
-
-Logistics
-=========
-
-Project planning
-----------------
-
-We use `GitHub Project feature in the Google fork repo <https://github.com/google/DirectXShaderCompiler/projects/1>`_
-to manage tasks and track progress.
-
-Pull requests and code review
------------------------------
-
-Pull requests are very welcome! However, the Google repo is only used for
-project planning. We do not intend to maintain a detached fork; so all pull
-requests should be sent against the original `Microsoft repo <https://github.com/Microsoft/DirectXShaderCompiler>`_.
-Code reviews will also happen there.
-
-For each pull request, please make sure
-
-- You express your intent in the Google fork to avoid duplicate work.
-- Tests are written to cover the modifications.
-- This doc is updated for newly supported features.
-
-Testing
--------
-
-We will use `googletest <https://github.com/google/googletest>`_ as the unit
-test and codegen test framework. Appveyor will be used to check regression of
-all pull requests.
+Using GLSL extended instructions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+the following intrinsic HLSL functions are translated using their equivalent
+instruction in the `GLSL extended instruction set <https://www.khronos.org/registry/spir-v/specs/1.0/GLSL.std.450.html>`_.
+
+======================= ===============================
+HLSL Intrinsic Function   GLSL Extended Instruction
+======================= ===============================
+``abs``                 ``SAbs``/``FAbs``
+``acos``                ``Acos``
+``asin``                ``Asin``
+``atan``                ``Atan``
+``ceil``                ``Ceil``
+``clamp``               ``SClamp``/``UClamp``/``FClamp``
+``cos``                 ``Cos``
+``cosh``                ``Cosh``
+``cross``                ``Cross``
+``degrees``             ``Degrees``
+``radians``             ``Radian``
+``determinant``         ``Determinant``
+``exp``                 ``Exp``
+``exp2``                ``exp2``
+``floor``               ``Floor``
+``length``              ``Length``
+``log``                 ``Log``
+``log2``                ``Log2``
+``max``                 ``SMax``/``UMax``/``FMax``
+``min``                 ``SMin``/``UMin``/``FMin``
+``normalize``           ``Normalize``
+``pow``                 ``Pow``
+``reflect``             ``Reflect``
+``round``               ``Round``
+``rsqrt``               ``InverseSqrt``
+``step``                ``Step``
+``sign``                ``SSign``/``FSign``
+``sin``                 ``Sin``
+``sinh``                ``Sinh``
+``tan``                 ``Tan``
+``tanh``                ``Tanh``
+``sqrt``                ``Sqrt``
+``trunc``               ``Trunc``
+======================= ===============================