浏览代码

Fix NonUniform indexing of CBV array (#3095)

CBV array index uses special HL CreateHandle intrinsic for indexing
instead of GEP.  When TranslateNonUniformResourceIndex is marking GEPs
with metadata, there was no GEP to mark for CBV array.  This change
also marks HL CreateHandle calls when direct users of this intrinsic.
Later, in DxilGenerationPass, this HL CreateHandle call with the index
is translated to a GEP + CreateHandleForLib call.  This now adds the
non-uniform metadata to the GEP if the indexed HL CreateHandle call
being translated had it.
Tex Riddell 5 年之前
父节点
当前提交
530958e4b7

+ 3 - 0
lib/HLSL/DxilGenerationPass.cpp

@@ -565,6 +565,9 @@ void DxilGenerationPass::GenerateDxilCBufferHandles() {
         }
         // Add GEP for cbv array use.
         Value *GEP = Builder.CreateGEP(GV, {zeroIdx, CBIndex});
+        if (DxilMDHelper::IsMarkedNonUniform(CI)) {
+          DxilMDHelper::MarkNonUniform(cast<Instruction>(GEP));
+        }
         Value *V = Builder.CreateLoad(GEP);
         CallInst *handle = Builder.CreateCall(createHandle, {opArg, V}, handleName);
         CI->replaceAllUsesWith(handle);

+ 3 - 0
lib/HLSL/HLOperationLower.cpp

@@ -550,6 +550,9 @@ Value *TranslateNonUniformResourceIndex(CallInst *CI, IntrinsicOp IOP, OP::OpCod
             DxilMDHelper::MarkNonUniform(I);
         }
       }
+    } else if (CallInst *CI = dyn_cast<CallInst>(U)) {
+      if (hlsl::GetHLOpcodeGroup(CI->getCalledFunction()) == hlsl::HLOpcodeGroup::HLCreateHandle)
+        DxilMDHelper::MarkNonUniform(CI);
     }
   }
   return nullptr;

+ 18 - 0
tools/clang/test/HLSLFileCheck/hlsl/objects/Cbuffer/NonUniform-ConstantBuffer.hlsl

@@ -0,0 +1,18 @@
+// RUN: %dxc -E main -T cs_6_0 %s  | FileCheck %s
+
+// Expect non-uniform resource index (i1 true):
+// CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 {{.*}}, i1 true)
+
+struct CBType
+{
+  float cbvals[4];
+};
+
+ConstantBuffer<CBType> CBs[100] : register(b0);
+RWBuffer<uint> Output;
+
+[numthreads(4,1,1)]
+void main(uint index : SV_GroupThreadID)
+{
+  Output[index] = CBs[NonUniformResourceIndex(index)].cbvals[0];
+}