Ver código fonte

PIX passes: Centralize handle-generation code and update for 6.6 (#3628)

This is little more than a move of the "create-uav" code in lib/DxilPIXPasses/DxilShaderAccessTracking.cpp to PixPassHelpers.cpp, followed by a factoring-out of the parts that create a handle (either pre-SM6.6 fashion, or with the newer create-from-binding etc.).
All the other passes' near-identical code was then deleted and made to call the centralized function.
Jeff Noyle 4 anos atrás
pai
commit
ea1efe96ba

+ 3 - 53
lib/DxilPIXPasses/DxilAddPixelHitInstrumentation.cpp

@@ -21,6 +21,8 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/Transforms/Utils/Local.h"
 
+#include "PixPassHelpers.h"
+
 using namespace llvm;
 using namespace hlsl;
 
@@ -102,59 +104,7 @@ bool DxilAddPixelHitInstrumentation::runOnModule(Module &M) {
     IRBuilder<> Builder(
         dxilutil::FirstNonAllocaInsertionPt(DM.GetEntryFunction()));
 
-    unsigned int UAVResourceHandle =
-        static_cast<unsigned int>(DM.GetUAVs().size());
-
-    // Set up a UAV with structure of a single int
-    SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(Ctx)};
-    llvm::StructType *UAVStructTy =
-        llvm::StructType::create(Elements, "class.RWStructuredBuffer");
-    std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();
-    pUAV->SetGlobalName("PIX_CountUAVName");
-    pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
-    pUAV->SetID(UAVResourceHandle);
-    pUAV->SetSpaceID(
-        (unsigned int)-2); // This is the reserved-for-tools register space
-    pUAV->SetSampleCount(1);
-    pUAV->SetGloballyCoherent(false);
-    pUAV->SetHasCounter(false);
-    pUAV->SetCompType(CompType::getI32());
-    pUAV->SetLowerBound(0);
-    pUAV->SetRangeSize(1);
-    pUAV->SetKind(DXIL::ResourceKind::RawBuffer);
-    pUAV->SetRW(true);
-
-    auto pAnnotation = DM.GetTypeSystem().GetStructAnnotation(UAVStructTy);
-    if (pAnnotation == nullptr) {
-      pAnnotation = DM.GetTypeSystem().AddStructAnnotation(UAVStructTy);
-      pAnnotation->GetFieldAnnotation(0).SetCBufferOffset(0);
-      pAnnotation->GetFieldAnnotation(0).SetCompType(
-          hlsl::DXIL::ComponentType::I32);
-      pAnnotation->GetFieldAnnotation(0).SetFieldName("count");
-    }
-
-    ID = DM.AddUAV(std::move(pUAV));
-
-    assert((unsigned)ID == UAVResourceHandle);
-
-    // Create handle for the newly-added UAV
-    Function *CreateHandleOpFunc =
-        HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
-    Constant *CreateHandleOpcodeArg =
-        HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-    Constant *UAVArg = HlslOP->GetI8Const(
-        static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
-            DXIL::ResourceClass::UAV));
-    Constant *MetaDataArg =
-        HlslOP->GetU32Const(ID); // position of the metadata record in the
-                                 // corresponding metadata list
-    Constant *IndexArg = HlslOP->GetU32Const(0); //
-    Constant *FalseArg =
-        HlslOP->GetI1Const(0); // non-uniform resource index: false
-    HandleForUAV = Builder.CreateCall(
-        CreateHandleOpFunc,
-        {CreateHandleOpcodeArg, UAVArg, MetaDataArg, IndexArg, FalseArg},
-        "PIX_CountUAV_Handle");
+    HandleForUAV = PIXPassHelpers::CreateUAV(DM, Builder, 0, "PIX_CountUAV_Handle");
 
     DM.ReEmitDxilResources();
   }

+ 2 - 48
lib/DxilPIXPasses/DxilDebugInstrumentation.cpp

@@ -252,7 +252,6 @@ public:
 
 private:
   SystemValueIndices addRequiredSystemValues(BuilderContext &BC);
-  void addUAV(BuilderContext &BC);
   void addInvocationSelectionProlog(BuilderContext &BC,
                                     SystemValueIndices SVIndices);
   Value *addPixelShaderProlog(BuilderContext &BC, SystemValueIndices SVIndices);
@@ -548,52 +547,6 @@ DxilDebugInstrumentation::addPixelShaderProlog(BuilderContext &BC,
   return ComparePos;
 }
 
-void DxilDebugInstrumentation::addUAV(BuilderContext &BC) {
-  // Set up a UAV with structure of a single int
-  unsigned int UAVResourceHandle =
-      static_cast<unsigned int>(BC.DM.GetUAVs().size());
-  SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(BC.Ctx)};
-  llvm::StructType *UAVStructTy =
-      llvm::StructType::create(Elements, "PIX_DebugUAV_Type");
-  std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();
-  pUAV->SetGlobalName("PIX_DebugUAVName");
-  pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
-  pUAV->SetID(UAVResourceHandle);
-  pUAV->SetSpaceID(
-      (unsigned int)-2); // This is the reserved-for-tools register space
-  pUAV->SetSampleCount(1);
-  pUAV->SetGloballyCoherent(false);
-  pUAV->SetHasCounter(false);
-  pUAV->SetCompType(CompType::getI32());
-  pUAV->SetLowerBound(0);
-  pUAV->SetRangeSize(1);
-  pUAV->SetKind(DXIL::ResourceKind::RawBuffer);
-  pUAV->SetRW(true);
-
-  auto ID = BC.DM.AddUAV(std::move(pUAV));
-  assert(ID == UAVResourceHandle);
-
-  BC.DM.m_ShaderFlags.SetEnableRawAndStructuredBuffers(true);
-
-  // Create handle for the newly-added UAV
-  Function *CreateHandleOpFunc =
-      BC.HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(BC.Ctx));
-  Constant *CreateHandleOpcodeArg =
-      BC.HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-  Constant *UAVVArg = BC.HlslOP->GetI8Const(
-      static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
-          DXIL::ResourceClass::UAV));
-  Constant *MetaDataArg = BC.HlslOP->GetU32Const(
-      ID); // position of the metadata record in the corresponding metadata list
-  Constant *IndexArg = BC.HlslOP->GetU32Const(0); //
-  Constant *FalseArg =
-      BC.HlslOP->GetI1Const(0); // non-uniform resource index: false
-  m_HandleForUAV = BC.Builder.CreateCall(
-      CreateHandleOpFunc,
-      {CreateHandleOpcodeArg, UAVVArg, MetaDataArg, IndexArg, FalseArg},
-      "PIX_DebugUAV_Handle");
-}
-
 void DxilDebugInstrumentation::addInvocationSelectionProlog(
     BuilderContext &BC, SystemValueIndices SVIndices) {
   auto ShaderModel = BC.DM.GetShaderModel();
@@ -959,7 +912,8 @@ bool DxilDebugInstrumentation::runOnModule(Module &M) {
 
   BuilderContext BC{M, DM, Ctx, HlslOP, Builder};
 
-  addUAV(BC);
+  m_HandleForUAV = PIXPassHelpers::CreateUAV(BC.DM, BC.Builder, 0, "PIX_DebugUAV_Handle");
+
   auto SystemValues = addRequiredSystemValues(BC);
   addInvocationSelectionProlog(BC, SystemValues);
   addInvocationStartMarker(BC);

+ 6 - 19
lib/DxilPIXPasses/DxilOutputColorBecomesConstant.cpp

@@ -20,6 +20,8 @@
 #include "llvm/Transforms/Utils/Local.h"
 #include <array>
 
+#include "PixPassHelpers.h"
+
 using namespace llvm;
 using namespace hlsl;
 
@@ -166,8 +168,6 @@ bool DxilOutputColorBecomesConstant::runOnModule(Module &M) {
     pCBuf->SetRangeSize(1);
     pCBuf->SetSize(4);
 
-    ID = DM.AddCBuffer(std::move(pCBuf));
-
     Instruction *entryPointInstruction =
         &*(DM.GetEntryFunction()->begin()->begin());
     IRBuilder<> Builder(entryPointInstruction);
@@ -175,23 +175,10 @@ bool DxilOutputColorBecomesConstant::runOnModule(Module &M) {
     // Create handle for the newly-added constant buffer (which is achieved via
     // a function call)
     auto ConstantBufferName = "PIX_Constant_Color_CB_Handle";
-    Function *createHandle =
-        HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
-    Constant *CreateHandleOpcodeArg =
-        HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-    Constant *CBVArg = HlslOP->GetI8Const(
-        static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
-            DXIL::ResourceClass::CBuffer));
-    Constant *MetaDataArg =
-        HlslOP->GetU32Const(ID); // position of the metadata record in the
-                                 // corresponding metadata list
-    Constant *IndexArg = HlslOP->GetU32Const(0); //
-    Constant *FalseArg =
-        HlslOP->GetI1Const(0); // non-uniform resource index: false
-    CallInst *callCreateHandle = Builder.CreateCall(
-        createHandle,
-        {CreateHandleOpcodeArg, CBVArg, MetaDataArg, IndexArg, FalseArg},
-        ConstantBufferName);
+
+    CallInst* callCreateHandle = PIXPassHelpers::CreateHandleForResource(DM, Builder, pCBuf.get(), ConstantBufferName);
+
+    DM.AddCBuffer(std::move(pCBuf));
 
     DM.ReEmitDxilResources();
 

+ 3 - 49
lib/DxilPIXPasses/DxilPIXMeshShaderOutputInstrumentation.cpp

@@ -28,6 +28,8 @@
 #include <winerror.h>
 #endif
 
+#include "PixPassHelpers.h"
+
 // Keep these in sync with the same-named value in the debugger application's
 // WinPixShaderUtils.h
 
@@ -72,7 +74,6 @@ private:
     IRBuilder<> &Builder;
   };
 
-  CallInst *addUAV(BuilderContext &BC);
   Value *insertInstructionsToCalculateFlattenedGroupIdXandY(BuilderContext &BC);
   Value *insertInstructionsToCalculateGroupIdZ(BuilderContext &BC);
   Value *reserveDebugEntrySpace(BuilderContext &BC, uint32_t SpaceInBytes);
@@ -92,53 +93,6 @@ uint32_t DxilPIXMeshShaderOutputInstrumentation::UAVDumpingGroundOffset()
   return static_cast<uint32_t>(m_UAVSize - DebugBufferDumpingGroundSize);
 }
 
-CallInst *DxilPIXMeshShaderOutputInstrumentation::addUAV(BuilderContext &BC) 
-{
-  // Set up a UAV with structure of a single int
-  unsigned int UAVResourceHandle =
-      static_cast<unsigned int>(BC.DM.GetUAVs().size());
-  SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(BC.Ctx)};
-  llvm::StructType *UAVStructTy =
-      llvm::StructType::create(Elements, "PIX_DebugUAV_Type");
-  std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();
-  pUAV->SetGlobalName("PIX_DebugUAVName");
-  pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
-  pUAV->SetID(UAVResourceHandle);
-  pUAV->SetSpaceID(
-      (unsigned int)-2); // This is the reserved-for-tools register space
-  pUAV->SetSampleCount(1);
-  pUAV->SetGloballyCoherent(false);
-  pUAV->SetHasCounter(false);
-  pUAV->SetCompType(CompType::getI32());
-  pUAV->SetLowerBound(0);
-  pUAV->SetRangeSize(1);
-  pUAV->SetKind(DXIL::ResourceKind::RawBuffer);
-  pUAV->SetRW(true);
-
-  auto ID = BC.DM.AddUAV(std::move(pUAV));
-  assert(ID == UAVResourceHandle);
-
-  BC.DM.m_ShaderFlags.SetEnableRawAndStructuredBuffers(true);
-
-  // Create handle for the newly-added UAV
-  Function *CreateHandleOpFunc =
-      BC.HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(BC.Ctx));
-  Constant *CreateHandleOpcodeArg =
-      BC.HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-  Constant *UAVVArg = BC.HlslOP->GetI8Const(
-      static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
-          DXIL::ResourceClass::UAV));
-  Constant *MetaDataArg = BC.HlslOP->GetU32Const(
-      ID); // position of the metadata record in the corresponding metadata list
-  Constant *IndexArg = BC.HlslOP->GetU32Const(0); //
-  Constant *FalseArg =
-      BC.HlslOP->GetI1Const(0); // non-uniform resource index: false
-  return BC.Builder.CreateCall(
-      CreateHandleOpFunc,
-      {CreateHandleOpcodeArg, UAVVArg, MetaDataArg, IndexArg, FalseArg},
-      "PIX_DebugUAV_Handle");
-}
-
 Value *DxilPIXMeshShaderOutputInstrumentation::
     insertInstructionsToCalculateFlattenedGroupIdXandY(BuilderContext &BC)
 {
@@ -275,7 +229,7 @@ bool DxilPIXMeshShaderOutputInstrumentation::runOnModule(Module &M)
 
   m_OffsetMask = BC.HlslOP->GetU32Const(UAVDumpingGroundOffset() - 1);
 
-  m_OutputUAV = addUAV(BC);
+  m_OutputUAV = PIXPassHelpers::CreateUAV(DM, Builder, 0, "PIX_DebugUAV_Handle");
 
   auto GroupIdXandY = insertInstructionsToCalculateFlattenedGroupIdXandY(BC);
   auto GroupIdZ = insertInstructionsToCalculateGroupIdZ(BC);

+ 4 - 103
lib/DxilPIXPasses/DxilShaderAccessTracking.cpp

@@ -25,6 +25,8 @@
 #include "llvm/Transforms/Utils/Local.h"
 #include <deque>
 
+#include "PixPassHelpers.h"
+
 #ifdef _WIN32
 #include <winerror.h>
 #endif
@@ -620,104 +622,6 @@ DxilShaderAccessTracking::GetResourceFromHandle(Value *resHandle,
   return ret;
 }
 
-static bool IsDynamicResourceShaderModel(DxilModule& DM) {
-  return DM.GetShaderModel()->IsSMAtLeast(6, 6);
-}
-
-// Set up a UAV with structure of a single int
-static llvm::CallInst* CreateUAV(DxilModule & DM, IRBuilder<> & Builder, unsigned int UAVResourceHandle, unsigned int bind, const char * name)
-{
-    LLVMContext& Ctx = DM.GetModule()->getContext();
-
-    SmallVector<llvm::Type*, 1> Elements{ Type::getInt32Ty(Ctx) };
-    llvm::StructType* UAVStructTy =
-        llvm::StructType::create(Elements, "class.RWStructuredBuffer");
-    std::unique_ptr<DxilResource> pUAV =
-        llvm::make_unique<DxilResource>();
-    pUAV->SetGlobalName((std::string("PIX_CountUAVName")+ std::to_string(UAVResourceHandle)).c_str());
-    pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
-    pUAV->SetID(UAVResourceHandle);
-    pUAV->SetRW(true); //sets UAV class
-    pUAV->SetSpaceID((
-        unsigned int)-2); // This is the reserved-for-tools register space
-    pUAV->SetSampleCount(1);
-    pUAV->SetGloballyCoherent(false);
-    pUAV->SetHasCounter(false);
-    pUAV->SetCompType(CompType::getI32());
-    pUAV->SetLowerBound(0);
-    pUAV->SetRangeSize(1);
-    pUAV->SetKind(DXIL::ResourceKind::RawBuffer);
-
-    auto pAnnotation =
-        DM.GetTypeSystem().GetStructAnnotation(UAVStructTy);
-    if (pAnnotation == nullptr) {
-
-        pAnnotation = DM.GetTypeSystem().AddStructAnnotation(UAVStructTy);
-        pAnnotation->GetFieldAnnotation(0).SetCBufferOffset(0);
-        pAnnotation->GetFieldAnnotation(0).SetCompType(
-            hlsl::DXIL::ComponentType::I32);
-        pAnnotation->GetFieldAnnotation(0).SetFieldName("count");
-    }
-
-    OP *HlslOP = DM.GetOP();
-
-    // Create handle for the newly-added UAV
-    if (IsDynamicResourceShaderModel(DM)) {
-      Function *CreateHandleFromBindingOpFunc =
-          HlslOP->GetOpFunc(DXIL::OpCode::CreateHandleFromBinding, Type::getVoidTy(Ctx));
-      Constant *CreateHandleFromBindingOpcodeArg =
-          HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandleFromBinding);
-      DxilResourceBinding binding =
-          resource_helper::loadBindingFromResourceBase(pUAV.get());
-      Value *bindingV = resource_helper::getAsConstant(
-          binding, HlslOP->GetResourceBindingType(), *DM.GetShaderModel());
-
-      Value *registerIndex = HlslOP->GetU32Const(UAVResourceHandle);
-
-      Value *isUniformRes = HlslOP->GetI1Const(0);
-
-      Value *createHandleFromBindingArgs[] = { CreateHandleFromBindingOpcodeArg, bindingV, registerIndex,
-                                              isUniformRes};
-
-      auto * handle = Builder.CreateCall(
-          CreateHandleFromBindingOpFunc,
-          createHandleFromBindingArgs,
-          name);
-
-      Function *annotHandleFn = HlslOP->GetOpFunc(DXIL::OpCode::AnnotateHandle, Type::getVoidTy(Ctx));
-      Value *annotHandleArg = HlslOP->GetI32Const((unsigned)DXIL::OpCode::AnnotateHandle);
-      DxilResourceProperties RP = resource_helper::loadPropsFromResourceBase(pUAV.get());
-      Type *resPropertyTy = HlslOP->GetResourcePropertiesType();
-      Value *propertiesV = resource_helper::getAsConstant(RP, resPropertyTy, *DM.GetShaderModel());
-
-      unsigned int ID = DM.AddUAV(std::move(pUAV));
-      DXASSERT_LOCALVAR_NOMSG(ID, (unsigned)ID == UAVResourceHandle);
-
-      return Builder.CreateCall(annotHandleFn, {annotHandleArg, handle, propertiesV});
-    } else {
-      unsigned int ID = DM.AddUAV(std::move(pUAV));
-      DXASSERT_NOMSG((unsigned)ID == UAVResourceHandle);
-
-      Function* CreateHandleOpFunc = HlslOP->GetOpFunc(
-          DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
-      Constant* CreateHandleOpcodeArg =
-          HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
-      Constant* UAVArg = HlslOP->GetI8Const(
-          static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
-              DXIL::ResourceClass::UAV));
-      Constant* MetaDataArg =
-          HlslOP->GetU32Const(ID); // position of the metadata record in the
-                                   // corresponding metadata list
-      Constant* IndexArg = HlslOP->GetU32Const(0); //
-      Constant* FalseArg =
-          HlslOP->GetI1Const(0); // non-uniform resource index: false
-      return Builder.CreateCall(
-          CreateHandleOpFunc,
-          { CreateHandleOpcodeArg, UAVArg, MetaDataArg, IndexArg, FalseArg },
-          name);
-    }
-}
-
 static uint32_t EncodeShaderModel(DXIL::ShaderKind kind)
 {
     DXASSERT_NOMSG(static_cast<int>(DXIL::ShaderKind::Invalid) <= 16);
@@ -771,15 +675,12 @@ bool DxilShaderAccessTracking::runOnModule(Module &M) {
           FOS << "ShouldAssumeDsvAccess";
         }
       }
-
+      int uavRegId = 0;
       for (llvm::Function &F : M.functions()) {
         if (!F.getBasicBlockList().empty()) {
           IRBuilder<> Builder(F.getEntryBlock().getFirstInsertionPt());
 
-          unsigned int UAVResourceHandle =
-              static_cast<unsigned int>(DM.GetUAVs().size());
-
-          m_FunctionToUAVHandle[&F] = CreateUAV(DM, Builder, UAVResourceHandle, 0, "PIX_CountUAV_Handle");
+          m_FunctionToUAVHandle[&F] = PIXPassHelpers::CreateUAV(DM, Builder, uavRegId++, "PIX_CountUAV_Handle");
           auto const* shaderModel = DM.GetShaderModel();
           auto shaderKind = shaderModel->GetKind();
           OP *HlslOP = DM.GetOP();

+ 145 - 9
lib/DxilPIXPasses/PixPassHelpers.cpp

@@ -8,15 +8,151 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/DXIL/DxilOperations.h"
+#include "dxc/DXIL/DxilInstructions.h"
+#include "dxc/DXIL/DxilModule.h"
+#include "dxc/DXIL/DxilResourceBinding.h"
+#include "dxc/DXIL/DxilResourceProperties.h"
+#include "dxc/HLSL/DxilSpanAllocator.h"
+
+#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/Pass.h"
 
-namespace PIXPassHelpers
-{
-    bool IsAllocateRayQueryInstruction(llvm::Value* Val) {
-        if (llvm::Instruction* Inst = llvm::dyn_cast<llvm::Instruction>(Val)) {
-            return hlsl::OP::IsDxilOpFuncCallInst(Inst, hlsl::OP::OpCode::AllocateRayQuery);
-        }
-        return false;
-    }
-}
+using namespace llvm;
+using namespace hlsl;
+
+namespace PIXPassHelpers {
+bool IsAllocateRayQueryInstruction(llvm::Value *Val) {
+  if (llvm::Instruction *Inst = llvm::dyn_cast<llvm::Instruction>(Val)) {
+    return hlsl::OP::IsDxilOpFuncCallInst(Inst,
+                                          hlsl::OP::OpCode::AllocateRayQuery);
+  }
+  return false;
+}
+
+static unsigned int
+GetNextRegisterIdForClass(hlsl::DxilModule &DM,
+                          DXIL::ResourceClass resourceClass) {
+  switch (resourceClass) {
+  case DXIL::ResourceClass::CBuffer:
+    return static_cast<unsigned int>(DM.GetCBuffers().size());
+  case DXIL::ResourceClass::UAV:
+    return static_cast<unsigned int>(DM.GetUAVs().size());
+  default:
+    DXASSERT(false, "Unexpected resource class");
+    return 0;
+  }
+}
+
+static bool IsDynamicResourceShaderModel(DxilModule &DM) {
+  return DM.GetShaderModel()->IsSMAtLeast(6, 6);
+}
+
+llvm::CallInst *CreateHandleForResource(hlsl::DxilModule &DM,
+                                        llvm::IRBuilder<> &Builder,
+                                        hlsl::DxilResourceBase *resource,
+                                        const char *name) {
+
+  OP *HlslOP = DM.GetOP();
+  LLVMContext &Ctx = DM.GetModule()->getContext();
+
+  DXIL::ResourceClass resourceClass = resource->GetClass();
+
+  unsigned int resourceMetaDataId =
+      GetNextRegisterIdForClass(DM, resourceClass);
+
+  // Create handle for the newly-added resource
+  if (IsDynamicResourceShaderModel(DM)) {
+    Function *CreateHandleFromBindingOpFunc = HlslOP->GetOpFunc(
+        DXIL::OpCode::CreateHandleFromBinding, Type::getVoidTy(Ctx));
+    Constant *CreateHandleFromBindingOpcodeArg =
+        HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandleFromBinding);
+    DxilResourceBinding binding =
+        resource_helper::loadBindingFromResourceBase(resource);
+    Value *bindingV = resource_helper::getAsConstant(
+        binding, HlslOP->GetResourceBindingType(), *DM.GetShaderModel());
+
+    Value *registerIndex = HlslOP->GetU32Const(resourceMetaDataId);
+
+    Value *isUniformRes = HlslOP->GetI1Const(0);
+
+    Value *createHandleFromBindingArgs[] = {CreateHandleFromBindingOpcodeArg,
+                                            bindingV, registerIndex,
+                                            isUniformRes};
+
+    auto *handle = Builder.CreateCall(CreateHandleFromBindingOpFunc,
+                                      createHandleFromBindingArgs, name);
+
+    Function *annotHandleFn =
+        HlslOP->GetOpFunc(DXIL::OpCode::AnnotateHandle, Type::getVoidTy(Ctx));
+    Value *annotHandleArg =
+        HlslOP->GetI32Const((unsigned)DXIL::OpCode::AnnotateHandle);
+    DxilResourceProperties RP =
+        resource_helper::loadPropsFromResourceBase(resource);
+    Type *resPropertyTy = HlslOP->GetResourcePropertiesType();
+    Value *propertiesV =
+        resource_helper::getAsConstant(RP, resPropertyTy, *DM.GetShaderModel());
+
+    return Builder.CreateCall(annotHandleFn,
+                              {annotHandleArg, handle, propertiesV});
+  } else {
+    Function *CreateHandleOpFunc =
+        HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
+    Constant *CreateHandleOpcodeArg =
+        HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
+    Constant *ClassArg = HlslOP->GetI8Const(
+        static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
+            resourceClass));
+    Constant *MetaDataArg = HlslOP->GetU32Const(
+        resourceMetaDataId); // position of the metadata record in the
+                             // corresponding metadata list
+    Constant *IndexArg = HlslOP->GetU32Const(0); //
+    Constant *FalseArg =
+        HlslOP->GetI1Const(0); // non-uniform resource index: false
+    return Builder.CreateCall(
+        CreateHandleOpFunc,
+        {CreateHandleOpcodeArg, ClassArg, MetaDataArg, IndexArg, FalseArg}, name);
+  }
+}
+
+// Set up a UAV with structure of a single int
+llvm::CallInst *CreateUAV(DxilModule &DM, IRBuilder<> &Builder,
+                          unsigned int registerId, const char *name) {
+  LLVMContext &Ctx = DM.GetModule()->getContext();
+
+  SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(Ctx)};
+  llvm::StructType *UAVStructTy =
+      llvm::StructType::create(Elements, "class.RWStructuredBuffer");
+  std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();
+  pUAV->SetGlobalName(name);
+  pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
+  pUAV->SetID(GetNextRegisterIdForClass(DM, DXIL::ResourceClass::UAV));
+  pUAV->SetRW(true); // sets UAV class
+  pUAV->SetSpaceID(
+      (unsigned int)-2); // This is the reserved-for-tools register space
+  pUAV->SetSampleCount(1);
+  pUAV->SetGloballyCoherent(false);
+  pUAV->SetHasCounter(false);
+  pUAV->SetCompType(CompType::getI32());
+  pUAV->SetLowerBound(0);
+  pUAV->SetRangeSize(1);
+  pUAV->SetKind(DXIL::ResourceKind::RawBuffer);
+
+  auto pAnnotation = DM.GetTypeSystem().GetStructAnnotation(UAVStructTy);
+  if (pAnnotation == nullptr) {
+
+    pAnnotation = DM.GetTypeSystem().AddStructAnnotation(UAVStructTy);
+    pAnnotation->GetFieldAnnotation(0).SetCBufferOffset(0);
+    pAnnotation->GetFieldAnnotation(0).SetCompType(
+        hlsl::DXIL::ComponentType::I32);
+    pAnnotation->GetFieldAnnotation(0).SetFieldName("count");
+  }
+
+  auto *handle = CreateHandleForResource(DM, Builder, pUAV.get(), name);
+
+  DM.AddUAV(std::move(pUAV));
+
+  return handle;
+}
+} // namespace PIXPassHelpers

+ 5 - 0
lib/DxilPIXPasses/PixPassHelpers.h

@@ -12,4 +12,9 @@
 namespace PIXPassHelpers
 {
 	bool IsAllocateRayQueryInstruction(llvm::Value* Val);
+    llvm::CallInst* CreateUAV(hlsl::DxilModule& DM, llvm::IRBuilder<>& Builder,
+                                  unsigned int registerId, const char *name);
+    llvm::CallInst* CreateHandleForResource(hlsl::DxilModule& DM, llvm::IRBuilder<>& Builder,
+        hlsl::DxilResourceBase * resource,
+        const char* name);
 }