Browse Source

Merged PR 99: Fix indexing of 16-bit-type vectors in CBuffer

Fix indexing of 16-bit-type vectors in CBuffer

Fixes #17967102
Helena Kotas 7 years ago
parent
commit
43a0f6f88c

+ 21 - 8
lib/HLSL/HLOperationLower.cpp

@@ -5557,14 +5557,27 @@ void TranslateCBGepLegacy(GetElementPtrInst *GEP, Value *handle,
       // Indexing on vector.
       if (bImmIdx) {
         unsigned tempOffset = size * immIdx;
-        unsigned channelInc = tempOffset >> 2;
-        DXASSERT((channel + channelInc)<=4, "vector should not cross cb register");
-        channel += channelInc;
-        if (channel == 4) {
-          // Get to another row.
-          // Update index and channel.
-          channel = 0;
-          legacyIndex = Builder.CreateAdd(legacyIndex, Builder.getInt32(1));
+        if (size == 2) { // 16-bit types
+          unsigned channelInc = tempOffset >> 1;
+          DXASSERT((channel + channelInc) <= 8, "vector should not cross cb register (8x16bit)");
+          channel += channelInc;
+          if (channel == 8) {
+            // Get to another row.
+            // Update index and channel.
+            channel = 0;
+            legacyIndex = Builder.CreateAdd(legacyIndex, Builder.getInt32(1));
+          }
+        }
+        else {
+          unsigned channelInc = tempOffset >> 2;
+          DXASSERT((channel + channelInc) <= 4, "vector should not cross cb register (8x32bit)");
+          channel += channelInc;
+          if (channel == 4) {
+            // Get to another row.
+            // Update index and channel.
+            channel = 0;
+            legacyIndex = Builder.CreateAdd(legacyIndex, Builder.getInt32(1));
+          }
         }
       } else {
         Type *EltTy = GEPIt->getVectorElementType();

+ 24 - 0
tools/clang/test/CodeGenHLSL/quick-test/cbuffer_half_vect_idx.hlsl

@@ -0,0 +1,24 @@
+// RUN: %dxc -E main -T ps_6_2 -enable-16bit-types %s | FileCheck %s
+
+// CHECK: call %dx.types.CBufRet.f16.8 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %constants_cbuffer, i32 0)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: extractvalue %dx.types.CBufRet.f16.8 %0, 0
+// CHECK: extractvalue %dx.types.CBufRet.f16.8 %0, 1
+// CHECK: call %dx.types.CBufRet.f16.8 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %constants_cbuffer, i32 1)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: extractvalue %dx.types.CBufRet.f16.8 %3, 6
+// CHECK: extractvalue %dx.types.CBufRet.f16.8 %3, 7
+
+cbuffer constants : register(b0)
+{
+    half2 h2_1;
+    float3 f3_1;
+    float3 f3_2;
+    half2 h2_2;
+}
+
+float main() : SV_TARGET
+{
+    half res1 = h2_1[0] + h2_1[1];
+    half res2 = h2_2[0] + h2_2[1];
+    float f = f3_2[1];
+    return res1 + res2 + f;
+}