Pārlūkot izejas kodu

Clear register binding for resource in cbuffer. (#2580)

TODO: use correct register binding if exist.
Xiang Li 5 gadi atpakaļ
vecāks
revīzija
462253a263

+ 5 - 2
include/dxc/HLSL/HLModule.h

@@ -39,6 +39,7 @@ class MDNode;
 class GlobalVariable;
 class DIGlobalVariable;
 class DebugInfoFinder;
+class GetElementPtrInst;
 }
 
 
@@ -178,8 +179,10 @@ public:
   llvm::MDNode *DxilUAVToMDNode(const DxilResource &UAV);
   llvm::MDNode *DxilCBufferToMDNode(const DxilCBuffer &CB);
   void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
-  void AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
-                                              llvm::MDNode *MD);
+  DxilResourceBase *AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
+                                                           llvm::MDNode *MD);
+  unsigned GetBindingForResourceInCB(llvm::GetElementPtrInst *CbPtr,
+                                     llvm::GlobalVariable *CbGV);
 
   // Type related methods.
   static bool IsStreamOutputPtrType(llvm::Type *Ty);

+ 18 - 2
lib/HLSL/HLModule.cpp

@@ -756,7 +756,7 @@ void HLModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
   return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
 }
 
-void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
+DxilResourceBase *HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
                                                       llvm::MDNode *MD) {
   IFTBOOL(MD->getNumOperands() >= DxilMDHelper::kHLDxilResourceAttributeNumFields,
           DXC_E_INCORRECT_DXIL_METADATA);
@@ -770,7 +770,7 @@ void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
   Type *Ty = GV->getType()->getPointerElementType();
   if (ArrayType *AT = dyn_cast<ArrayType>(Ty))
     rangeSize = AT->getNumElements();
-
+  DxilResourceBase *R = nullptr;
   switch (RC) {
   case DxilResource::Class::Sampler: {
     std::unique_ptr<DxilSampler> S = llvm::make_unique<DxilSampler>();
@@ -778,6 +778,7 @@ void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
     S->SetGlobalSymbol(GV);
     S->SetGlobalName(GV->getName());
     S->SetRangeSize(rangeSize);
+    R = S.get();
     AddSampler(std::move(S));
   } break;
   case DxilResource::Class::SRV: {
@@ -786,6 +787,7 @@ void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
     Res->SetGlobalSymbol(GV);
     Res->SetGlobalName(GV->getName());
     Res->SetRangeSize(rangeSize);
+    R = Res.get();
     AddSRV(std::move(Res));
   } break;
   case DxilResource::Class::UAV: {
@@ -794,11 +796,25 @@ void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
     Res->SetGlobalSymbol(GV);
     Res->SetGlobalName(GV->getName());
     Res->SetRangeSize(rangeSize);
+    R = Res.get();
     AddUAV(std::move(Res));
   } break;
   default:
     DXASSERT(0, "Invalid metadata for AddResourceWithGlobalVariableAndMDNode");
   }
+  return R;
+}
+
+unsigned HLModule::GetBindingForResourceInCB(GetElementPtrInst *CbPtr,
+                                             GlobalVariable *CbGV) {
+  DXIL::ResourceClass RC = GetResourceClass(CbPtr->getResultElementType());
+  for (auto &CB : m_CBuffers) {
+    if (CbGV != CB->GetGlobalSymbol())
+      continue;
+    RC = DXIL::ResourceClass::Invalid;
+    break;
+  }
+  return UINT_MAX;
 }
 
 // TODO: Don't check names.

+ 6 - 4
lib/HLSL/HLOperationLower.cpp

@@ -359,15 +359,17 @@ private:
     if (arraySize > 1) {
       Ty = ArrayType::get(Ty, arraySize);
     }
-
-    return CreateResourceGV(Ty, Name, MD);
+    unsigned ResBinding = HLM.GetBindingForResourceInCB(CbPtr, CbGV);
+    return CreateResourceGV(Ty, Name, MD, ResBinding);
   }
 
-  Value *CreateResourceGV(Type *Ty, StringRef Name, MDNode *MD) {
+  Value *CreateResourceGV(Type *Ty, StringRef Name, MDNode *MD, unsigned ResBinding) {
     Module &M = *HLM.GetModule();
     Constant *GV = M.getOrInsertGlobal(Name, Ty);
     // Create resource and set GV as globalSym.
-    HLM.AddResourceWithGlobalVariableAndMDNode(GV, MD);
+    DxilResourceBase *Res = HLM.AddResourceWithGlobalVariableAndMDNode(GV, MD);
+    DXASSERT(Res, "fail to create resource for global variable in cbuffer");
+    Res->SetLowerBound(ResBinding);
     return GV;
   }
 };

+ 24 - 0
tools/clang/test/HLSLFileCheck/hlsl/resource_binding/resource_in_cbuffer.hlsl

@@ -0,0 +1,24 @@
+// RUN: %dxc -E main -T ps_6_0 %s  | FileCheck %s
+// CHECK:tx0.s                             sampler      NA          NA      S0             s0     1
+// CHECK:tx1.s                             sampler      NA          NA      S1             s1     1
+// CHECK:tx0.t                             texture     f32          2d      T0             t0     1
+// CHECK:tx1.t                             texture     f32          2d      T1             t1     1
+
+struct LegacyTex
+{
+	Texture2D t;
+	SamplerState  s;
+};
+
+LegacyTex tx0;
+LegacyTex tx1;
+
+float4 tex2D(LegacyTex tx, float2 uv)
+{
+	return tx.t.Sample(tx.s,uv);
+}
+
+float4 main(float2 uv:UV) : SV_Target
+{
+	return tex2D(tx0,uv) + tex2D(tx1,uv);
+}