PixPassHelpers.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // PixPassHelpers.cpp //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "dxc/DXIL/DxilOperations.h"
  10. #include "dxc/DXIL/DxilInstructions.h"
  11. #include "dxc/DXIL/DxilModule.h"
  12. #include "dxc/DXIL/DxilResourceBinding.h"
  13. #include "dxc/DXIL/DxilResourceProperties.h"
  14. #include "dxc/HLSL/DxilSpanAllocator.h"
  15. #include "llvm/IR/IRBuilder.h"
  16. #include "llvm/IR/Module.h"
  17. #include "llvm/IR/PassManager.h"
  18. #include "llvm/Pass.h"
  19. using namespace llvm;
  20. using namespace hlsl;
  21. namespace PIXPassHelpers {
  22. bool IsAllocateRayQueryInstruction(llvm::Value *Val) {
  23. if (Val != nullptr) {
  24. if (llvm::Instruction *Inst = llvm::dyn_cast<llvm::Instruction>(Val)) {
  25. return hlsl::OP::IsDxilOpFuncCallInst(Inst,
  26. hlsl::OP::OpCode::AllocateRayQuery);
  27. }
  28. }
  29. return false;
  30. }
  31. static unsigned int
  32. GetNextRegisterIdForClass(hlsl::DxilModule &DM,
  33. DXIL::ResourceClass resourceClass) {
  34. switch (resourceClass) {
  35. case DXIL::ResourceClass::CBuffer:
  36. return static_cast<unsigned int>(DM.GetCBuffers().size());
  37. case DXIL::ResourceClass::UAV:
  38. return static_cast<unsigned int>(DM.GetUAVs().size());
  39. default:
  40. DXASSERT(false, "Unexpected resource class");
  41. return 0;
  42. }
  43. }
  44. static bool IsDynamicResourceShaderModel(DxilModule &DM) {
  45. return DM.GetShaderModel()->IsSMAtLeast(6, 6);
  46. }
  47. llvm::CallInst *CreateHandleForResource(hlsl::DxilModule &DM,
  48. llvm::IRBuilder<> &Builder,
  49. hlsl::DxilResourceBase *resource,
  50. const char *name) {
  51. OP *HlslOP = DM.GetOP();
  52. LLVMContext &Ctx = DM.GetModule()->getContext();
  53. DXIL::ResourceClass resourceClass = resource->GetClass();
  54. unsigned int resourceMetaDataId =
  55. GetNextRegisterIdForClass(DM, resourceClass);
  56. // Create handle for the newly-added resource
  57. if (IsDynamicResourceShaderModel(DM)) {
  58. Function *CreateHandleFromBindingOpFunc = HlslOP->GetOpFunc(
  59. DXIL::OpCode::CreateHandleFromBinding, Type::getVoidTy(Ctx));
  60. Constant *CreateHandleFromBindingOpcodeArg =
  61. HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandleFromBinding);
  62. DxilResourceBinding binding =
  63. resource_helper::loadBindingFromResourceBase(resource);
  64. Value *bindingV = resource_helper::getAsConstant(
  65. binding, HlslOP->GetResourceBindingType(), *DM.GetShaderModel());
  66. Value *registerIndex = HlslOP->GetU32Const(resourceMetaDataId);
  67. Value *isUniformRes = HlslOP->GetI1Const(0);
  68. Value *createHandleFromBindingArgs[] = {CreateHandleFromBindingOpcodeArg,
  69. bindingV, registerIndex,
  70. isUniformRes};
  71. auto *handle = Builder.CreateCall(CreateHandleFromBindingOpFunc,
  72. createHandleFromBindingArgs, name);
  73. Function *annotHandleFn =
  74. HlslOP->GetOpFunc(DXIL::OpCode::AnnotateHandle, Type::getVoidTy(Ctx));
  75. Value *annotHandleArg =
  76. HlslOP->GetI32Const((unsigned)DXIL::OpCode::AnnotateHandle);
  77. DxilResourceProperties RP =
  78. resource_helper::loadPropsFromResourceBase(resource);
  79. Type *resPropertyTy = HlslOP->GetResourcePropertiesType();
  80. Value *propertiesV =
  81. resource_helper::getAsConstant(RP, resPropertyTy, *DM.GetShaderModel());
  82. return Builder.CreateCall(annotHandleFn,
  83. {annotHandleArg, handle, propertiesV});
  84. } else {
  85. Function *CreateHandleOpFunc =
  86. HlslOP->GetOpFunc(DXIL::OpCode::CreateHandle, Type::getVoidTy(Ctx));
  87. Constant *CreateHandleOpcodeArg =
  88. HlslOP->GetU32Const((unsigned)DXIL::OpCode::CreateHandle);
  89. Constant *ClassArg = HlslOP->GetI8Const(
  90. static_cast<std::underlying_type<DxilResourceBase::Class>::type>(
  91. resourceClass));
  92. Constant *MetaDataArg = HlslOP->GetU32Const(
  93. resourceMetaDataId); // position of the metadata record in the
  94. // corresponding metadata list
  95. Constant *IndexArg = HlslOP->GetU32Const(0); //
  96. Constant *FalseArg =
  97. HlslOP->GetI1Const(0); // non-uniform resource index: false
  98. return Builder.CreateCall(
  99. CreateHandleOpFunc,
  100. {CreateHandleOpcodeArg, ClassArg, MetaDataArg, IndexArg, FalseArg}, name);
  101. }
  102. }
  103. // Set up a UAV with structure of a single int
  104. llvm::CallInst *CreateUAV(DxilModule &DM, IRBuilder<> &Builder,
  105. unsigned int registerId, const char *name) {
  106. LLVMContext &Ctx = DM.GetModule()->getContext();
  107. SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(Ctx)};
  108. llvm::StructType *UAVStructTy =
  109. llvm::StructType::create(Elements, "class.RWStructuredBuffer");
  110. std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();
  111. pUAV->SetGlobalName(name);
  112. pUAV->SetGlobalSymbol(UndefValue::get(UAVStructTy->getPointerTo()));
  113. pUAV->SetID(GetNextRegisterIdForClass(DM, DXIL::ResourceClass::UAV));
  114. pUAV->SetRW(true); // sets UAV class
  115. pUAV->SetSpaceID(
  116. (unsigned int)-2); // This is the reserved-for-tools register space
  117. pUAV->SetSampleCount(1);
  118. pUAV->SetGloballyCoherent(false);
  119. pUAV->SetHasCounter(false);
  120. pUAV->SetCompType(CompType::getI32());
  121. pUAV->SetLowerBound(0);
  122. pUAV->SetRangeSize(1);
  123. pUAV->SetKind(DXIL::ResourceKind::RawBuffer);
  124. auto pAnnotation = DM.GetTypeSystem().GetStructAnnotation(UAVStructTy);
  125. if (pAnnotation == nullptr) {
  126. pAnnotation = DM.GetTypeSystem().AddStructAnnotation(UAVStructTy);
  127. pAnnotation->GetFieldAnnotation(0).SetCBufferOffset(0);
  128. pAnnotation->GetFieldAnnotation(0).SetCompType(
  129. hlsl::DXIL::ComponentType::I32);
  130. pAnnotation->GetFieldAnnotation(0).SetFieldName("count");
  131. }
  132. auto *handle = CreateHandleForResource(DM, Builder, pUAV.get(), name);
  133. DM.AddUAV(std::move(pUAV));
  134. return handle;
  135. }
  136. } // namespace PIXPassHelpers