Bladeren bron

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 jaren geleden
bovenliggende
commit
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];
+}