@@ -96,7 +96,7 @@ Buffers
9696
9797.. code-block :: llvm
9898
99- target("dx.TypedBuffer", ElementType, IsWriteable, IsROV)
99+ target("dx.TypedBuffer", ElementType, IsWriteable, IsROV, IsSigned )
100100 target("dx.RawBuffer", ElementType, IsWriteable, IsROV)
101101
102102 We need two separate buffer types to account for the differences between the
@@ -106,9 +106,14 @@ used for DXIL's RawBuffers and StructuredBuffers. We call the latter
106106"RawBuffer" to match the naming of the operations, but it can represent both
107107the Raw and Structured variants.
108108
109- For TypedBuffer, the element type must be an integer or floating point type.
110- For RawBuffer the type can be an integer, floating point, or struct type.
111- HLSL's ByteAddressBuffer is represented by an `i8 ` element type.
109+ HLSL's Buffer and RWBuffer are represented as a TypedBuffer with an element
110+ type that is a scalar integer or floating point type, or a vector of at most 4
111+ such types. HLSL's ByteAddressBuffer is a RawBuffer with an `i8 ` element type.
112+ HLSL's StructuredBuffers are RawBuffer with a struct, vector, or scalar type.
113+
114+ One unfortunate necessity here is that TypedBuffer needs an extra parameter to
115+ differentiate signed vs unsigned ints. The is because in LLVM IR int types
116+ don't have a sign, so to keep this information we need a side channel.
112117
113118These types are generally used by BufferLoad and BufferStore operations, as
114119well as atomics.
@@ -128,6 +133,8 @@ There are a few fields to describe variants of all of these types:
128133 writeable) and UAVs (writeable).
129134 * - IsROV
130135 - Whether the UAV is a rasterizer ordered view. Always ``0 `` for SRVs.
136+ * - IsSigned
137+ - Whether an int element type is signed ("dx.TypedBuffer" only)
131138
132139.. _bufferLoad : https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst#bufferload
133140.. _bufferStore : https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst#bufferstore
@@ -197,23 +204,23 @@ Examples:
197204.. code-block :: llvm
198205
199206 ; RWBuffer<float4> Buf : register(u5, space3)
200- %buf = call target("dx.TypedBuffer", float, 1, 0)
207+ %buf = call target("dx.TypedBuffer", <4 x float> , 1, 0 , 0)
201208 @llvm.dx.handle.fromBinding.tdx.TypedBuffer_f32_1_0(
202209 i32 3, i32 5, i32 1, i32 0, i1 false)
203210
204- ; RWBuffer<uint > Buf : register(u7, space2)
205- %buf = call target("dx.TypedBuffer", i32, 1, 0)
211+ ; RWBuffer<int > Buf : register(u7, space2)
212+ %buf = call target("dx.TypedBuffer", i32, 1, 0, 1 )
206213 @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_1_0t(
207214 i32 2, i32 7, i32 1, i32 0, i1 false)
208215
209216 ; Buffer<uint4> Buf[24] : register(t3, space5)
210- %buf = call target("dx.TypedBuffer", i32, 0, 0)
217+ %buf = call target("dx.TypedBuffer", <4 x i32>, 0 , 0, 0)
211218 @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_0_0t(
212219 i32 2, i32 7, i32 24, i32 0, i1 false)
213220
214221 ; struct S { float4 a; uint4 b; };
215222 ; StructuredBuffer<S> Buf : register(t2, space4)
216- %buf = call target("dx.RawBuffer", {<4 x f32 >, <4 x i32>}, 0, 0)
223+ %buf = call target("dx.RawBuffer", {<4 x float >, <4 x i32>}, 0, 0)
217224 @llvm.dx.handle.fromBinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
218225 i32 4, i32 2, i32 1, i32 0, i1 false)
219226
0 commit comments