Lei Zhang 8 лет назад
Родитель
Сommit
809495a4c2
1 измененных файлов с 145 добавлено и 21 удалено
  1. 145 21
      docs/SPIR-V.rst

+ 145 - 21
docs/SPIR-V.rst

@@ -180,7 +180,7 @@ in SPIR-V. For example, for the following HLSL source code:
     ...
   }
 
-There will be there different ``OpTypeStruct`` generated, one for each variable
+There will be three 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
@@ -260,6 +260,10 @@ There are serveral buffer types in HLSL:
 - ``tbuffer`` and ``TextureBuffer``
 - ``StructuredBuffer`` and ``RWStructuredBuffer``
 - ``AppendStructuredBuffer`` and ``ConsumeStructuredBuffer``
+- ``ByteAddressBuffer`` and ``RWByteAddressBuffer``
+
+Note that ``Buffer`` and ``RWBuffer`` are considered as texture object in HLSL.
+They are listed in the above section.
 
 Please see the following sections for the details of each type. As a summary:
 
@@ -272,6 +276,8 @@ Please see the following sections for the details of each type. As a summary:
 ``RWStructuredBuffer``        Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
 ``AppendStructuredBuffer``    Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
 ``ConsumeStructuredBuffer``   Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
+``ByteAddressBuffer``         Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
+``RWByteAddressBuffer``       Storage Buffer      GLSL ``std430``            ``Uniform``        ``BufferBlock``
 =========================== ================== ========================== ==================== =================
 
 To know more about the Vulkan buffer types, please refer to the Vulkan spec
@@ -372,7 +378,8 @@ 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.
+contains a 32-bit integer. The integer is the total number of elements in the
+buffer. The counter variable takes its own binding number.
 ``.Append()``/``.Consume()`` will use the counter variable as the index and
 adjust it accordingly.
 
@@ -418,6 +425,54 @@ will be translated into
   %myASbuffer = OpVariable %_ptr_Uniform_type_AppendStructuredBuffer_T Uniform
   %counter_var_myASbuffer = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
 
+``ByteAddressBuffer`` and ``RWByteAddressBuffer``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``ByteAddressBuffer``/``RWByteAddressBuffer`` is treated as storage buffer using
+Vulkan's terminology. It is translated into an ``OpTypeStruct`` containing an
+``OpTypeRuntimeArray`` of 32-bit unsigned integers, with ``BufferBlock``
+decoration.
+
+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
+
+  ByteAddressBuffer   myBuffer1;
+  RWByteAddressBuffer myBuffer2;
+
+will be translated into
+
+.. code:: spirv
+
+  ; Layout decorations
+
+  OpDecorate %_runtimearr_uint ArrayStride 4
+
+  OpDecorate %type_ByteAddressBuffer BufferBlock
+  OpMemberDecorate %type_ByteAddressBuffer 0 Offset 0
+  OpMemberDecorate %type_ByteAddressBuffer 0 NonWritable
+
+  OpDecorate %type_RWByteAddressBuffer BufferBlock
+  OpMemberDecorate %type_RWByteAddressBuffer 0 Offset 0
+
+  ; Types
+
+  %_runtimearr_uint = OpTypeRuntimeArray %uint
+
+  %type_ByteAddressBuffer = OpTypeStruct %_runtimearr_uint
+  %_ptr_Uniform_type_ByteAddressBuffer = OpTypePointer Uniform %type_ByteAddressBuffer
+
+  %type_RWByteAddressBuffer = OpTypeStruct %_runtimearr_uint
+  %_ptr_Uniform_type_RWByteAddressBuffer = OpTypePointer Uniform %type_RWByteAddressBuffer
+
+  ; Variables
+
+  %myBuffer1 = OpVariable %_ptr_Uniform_type_ByteAddressBuffer Uniform
+  %myBuffer2 = OpVariable %_ptr_Uniform_type_RWByteAddressBuffer Uniform
+
 HLSL Variables and Resources
 ============================
 
@@ -758,6 +813,32 @@ 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.
 
+Assignment operators
+--------------------
+
+Assigning to struct object may involve decomposing the source struct object and
+assign each element separately and recursively. This happens when the source
+struct object is of different memory layout from the destination struct object.
+For example, for the following source code:
+
+.. code:: hlsl
+
+  struct S {
+    float    a;
+    float2   b;
+    float2x3 c;
+  };
+
+      ConstantBuffer<S> cbuf;
+  RWStructuredBuffer<S> sbuf;
+
+  ...
+  sbuf[0] = cbuf[0];
+  ...
+
+We need to assign each element because ``ConstantBuffer`` and
+``RWStructuredBuffer`` has different memory layout.
+
 HLSL Control Flows
 ==================
 
@@ -859,34 +940,34 @@ output/builtin variables created according to semantics. For example:
 
   ; Wrapper function starts
 
-  %main    = OpFunction %void None {{%\d+}}
-  {{%\d+}} = OpLabel
+  %main    = OpFunction %void None ...
+  ...      = OpLabel
 
   %param_var_input = OpVariable %_ptr_Function_T Function
 
   ; Load stage input variables and group into the expected composite
 
-  [[inA:%\d+]]     = OpLoad %bool %in_var_A
-  [[inB:%\d+]]     = OpLoad %v2uint %in_var_B
-  [[inC:%\d+]]     = OpLoad %mat2v3float %in_var_C
-  [[inS:%\d+]]     = OpCompositeConstruct %S [[inA]] [[inB]] [[inC]]
-  [[inD:%\d+]]     = OpLoad %int %in_var_D
-  [[inT:%\d+]]     = OpCompositeConstruct %T [[inS]] [[inD]]
-                     OpStore %param_var_input [[inT]]
+  %inA = OpLoad %bool %in_var_A
+  %inB = OpLoad %v2uint %in_var_B
+  %inC = OpLoad %mat2v3float %in_var_C
+  %inS = OpCompositeConstruct %S %inA %inB %inC
+  %inD = OpLoad %int %in_var_D
+  %inT = OpCompositeConstruct %T %inS %inD
+         OpStore %param_var_input %inT
 
-  [[ret:%\d+]]  = OpFunctionCall %T %src_main %param_var_input
+  %ret = OpFunctionCall %T %src_main %param_var_input
 
   ; Extract component values from the composite and store into stage output variables
 
-  [[outS:%\d+]] = OpCompositeExtract %S [[ret]] 0
-  [[outA:%\d+]] = OpCompositeExtract %bool [[outS]] 0
-                  OpStore %out_var_A [[outA]]
-  [[outB:%\d+]] = OpCompositeExtract %v2uint [[outS]] 1
-                  OpStore %out_var_B [[outB]]
-  [[outC:%\d+]] = OpCompositeExtract %mat2v3float [[outS]] 2
-                  OpStore %out_var_C [[outC]]
-  [[outD:%\d+]] = OpCompositeExtract %int [[ret]] 1
-                  OpStore %out_var_D [[outD]]
+  %outS = OpCompositeExtract %S %ret 0
+  %outA = OpCompositeExtract %bool %outS 0
+          OpStore %out_var_A %outA
+  %outB = OpCompositeExtract %v2uint %outS 1
+          OpStore %out_var_B %outB
+  %outC = OpCompositeExtract %mat2v3float %outS 2
+          OpStore %out_var_C %outC
+  %outD = OpCompositeExtract %int %ret 1
+          OpStore %out_var_D %outD
 
   OpReturn
   OpFunctionEnd
@@ -1024,3 +1105,46 @@ HLSL Intrinsic Function   GLSL Extended Instruction
 ``sqrt``                ``Sqrt``
 ``trunc``               ``Trunc``
 ======================= ===============================
+
+HLSL Methods
+============
+
+This section lists how various HLSL methods are mapped.
+
+``AppendStructuredBuffer``
+--------------------------
+
+``.Append()``
+~~~~~~~~~~~~~
+
+The associated counter number will be increased by 1 using ``OpAtomicIAdd``.
+The return value of ``OpAtomicIAdd``, which is the original count number, will
+be used as the index for storing the new element. E.g., for ``buf.Append(vec)``:
+
+.. code:: spirv
+
+  %counter = OpAccessChain %_ptr_Uniform_int %counter_var_buf %uint_0
+    %index = OpAtomicIAdd %uint %counter %uint_1 %uint_0 %uint_1
+      %ptr = OpAccessChain %_ptr_Uniform_v4float %buf %uint_0 %index
+      %val = OpLoad %v4float %vec
+             OpStore %ptr %val
+
+``ConsumeStructuredBuffer``
+---------------------------
+
+``.Consume()``
+~~~~~~~~~~~~~
+
+The associated counter number will be decreased by 1 using ``OpAtomicISub``.
+The return value of ``OpAtomicISub`` minus 1, which is the new count number,
+will be used as the index for reading the new element. E.g., for
+``buf.Consume(vec)``:
+
+.. code:: spirv
+
+  %counter = OpAccessChain %_ptr_Uniform_int %counter_var_buf %uint_0
+     %prev = OpAtomicISub %uint %counter %uint_1 %uint_0 %uint_1
+    %index = OpISub %uint %prev %uint_1
+      %ptr = OpAccessChain %_ptr_Uniform_v4float %buf %uint_0 %index
+      %val = OpLoad %v4float %vec
+             OpStore %ptr %val