Browse Source

Fix validation error when element size for array of struct is not aligned (#2295)

* Fix validation error when element size for array of struct is not 16 aligned.

* Remove outdated comment.
Xiang Li 6 years ago
parent
commit
cd0e61e77b

+ 7 - 6
lib/HLSL/DxilValidation.cpp

@@ -3724,19 +3724,20 @@ CollectCBufferRanges(DxilStructAnnotation *annotation,
         arrayCount *= EltTy->getArrayNumElements();
         EltTy = EltTy->getArrayElementType();
       }
-      unsigned arrayBase = base + offset;
+
+      // Base for array must be aligned.
+      unsigned alignedBase = ((base + 15) & ~(0xf));
+
+      unsigned arrayBase = alignedBase + offset;
 
       DxilStructAnnotation *EltAnnotation = nullptr;
       if (StructType *EltST = dyn_cast<StructType>(EltTy))
         EltAnnotation = typeSys.GetStructAnnotation(EltST);
 
       for (unsigned idx = 0; idx < arrayCount; idx++) {
-        // 16 bytes align except last component.
-        if (idx < (arrayCount - 1)) {
-          arrayBase = (arrayBase + 15) & ~(0xf);
-        }
+        arrayBase = (arrayBase + 15) & ~(0xf);
 
-        if (arrayBase > (base + cbSize)) {
+        if (arrayBase > (alignedBase + cbSize)) {
           bOutOfBound = true;
           break;
         }

+ 37 - 0
tools/clang/test/CodeGenHLSL/batch/validation/array1.hlsl

@@ -0,0 +1,37 @@
+// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+
+
+// CHECK: cbuffer $Globals
+// CHECK:{
+// CHECK:   struct $Globals
+// CHECK:{
+// CHECK:   struct struct.A
+// CHECK:{
+// CHECK: float4 x[2];                              ; Offset:    0
+// CHECK: uint y[1];                                ; Offset:   32
+// CHECK: } a[2];;                                      ; Offset:    0
+// CHECK: } $Globals;                                       ; Offset:    0 Size:    84
+
+// CHECK: cbuffer cb
+// CHECK: {
+// CHECK: struct cb
+// CHECK: {
+// CHECK: float b;                                      ; Offset:    0
+// CHECK: float c[1];                                   ; Offset:   16
+// CHECK: } cb;                                             ; Offset:    0 Size:    20
+
+struct A {
+  float4 x[2];
+  uint   y[1];
+};
+
+A a[2];
+
+cbuffer cb {
+  float b;
+  float c[1];
+}
+
+float main() : SV_Target {
+   return a[0].y[0] + c[0];
+}