DxilReduceMSAAToSingleSample.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilReduceMSAAToSingleSample.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. // Provides a pass to reduce all MSAA writes to single-sample writes //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include "dxc/DXIL/DxilOperations.h"
  12. #include "dxc/DXIL/DxilInstructions.h"
  13. #include "dxc/DXIL/DxilModule.h"
  14. #include "dxc/DxilPIXPasses/DxilPIXPasses.h"
  15. #include "dxc/HLSL/DxilGenerationPass.h"
  16. #include "llvm/IR/Constants.h"
  17. #include "llvm/IR/Instructions.h"
  18. #include "llvm/IR/PassManager.h"
  19. using namespace llvm;
  20. using namespace hlsl;
  21. class DxilReduceMSAAToSingleSample : public ModulePass {
  22. public:
  23. static char ID; // Pass identification, replacement for typeid
  24. explicit DxilReduceMSAAToSingleSample() : ModulePass(ID) {}
  25. const char *getPassName() const override {
  26. return "HLSL DXIL Reduce all MSAA reads to single-sample reads";
  27. }
  28. bool runOnModule(Module &M) override;
  29. };
  30. bool DxilReduceMSAAToSingleSample::runOnModule(Module &M) {
  31. DxilModule &DM = M.GetOrCreateDxilModule();
  32. LLVMContext &Ctx = M.getContext();
  33. OP *HlslOP = DM.GetOP();
  34. // FP16 type doesn't have its own identity, and is covered by float type...
  35. auto TextureLoadOverloads = std::vector<Type *>{
  36. Type::getFloatTy(Ctx), Type::getInt16Ty(Ctx), Type::getInt32Ty(Ctx)};
  37. bool Modified = false;
  38. for (const auto &Overload : TextureLoadOverloads) {
  39. Function *TexLoadFunction =
  40. HlslOP->GetOpFunc(DXIL::OpCode::TextureLoad, Overload);
  41. auto TexLoadFunctionUses = TexLoadFunction->uses();
  42. for (auto FI = TexLoadFunctionUses.begin();
  43. FI != TexLoadFunctionUses.end();) {
  44. auto &FunctionUse = *FI++;
  45. auto FunctionUser = FunctionUse.getUser();
  46. auto instruction = cast<Instruction>(FunctionUser);
  47. DxilInst_TextureLoad LoadInstruction(instruction);
  48. auto TextureHandle = LoadInstruction.get_srv();
  49. auto TextureHandleInst = cast<CallInst>(TextureHandle);
  50. DxilInst_CreateHandle createHandle(TextureHandleInst);
  51. // Dynamic rangeId is not supported
  52. if (isa<ConstantInt>(createHandle.get_rangeId())) {
  53. unsigned rangeId =
  54. cast<ConstantInt>(createHandle.get_rangeId())->getLimitedValue();
  55. if (static_cast<DXIL::ResourceClass>(
  56. createHandle.get_resourceClass_val()) ==
  57. DXIL::ResourceClass::SRV) {
  58. auto Resource = DM.GetSRV(rangeId);
  59. if (Resource.GetKind() == DXIL::ResourceKind::Texture2DMS ||
  60. Resource.GetKind() == DXIL::ResourceKind::Texture2DMSArray) {
  61. // "2" is the mip-level/sample-index operand index:
  62. // https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/DXIL.rst#textureload
  63. instruction->setOperand(2, HlslOP->GetI32Const(0));
  64. Modified = true;
  65. }
  66. }
  67. }
  68. }
  69. }
  70. return Modified;
  71. }
  72. char DxilReduceMSAAToSingleSample::ID = 0;
  73. ModulePass *llvm::createDxilReduceMSAAToSingleSamplePass() {
  74. return new DxilReduceMSAAToSingleSample();
  75. }
  76. INITIALIZE_PASS(DxilReduceMSAAToSingleSample, "hlsl-dxil-reduce-msaa-to-single",
  77. "HLSL DXIL Reduce all MSAA writes to single-sample writes",
  78. false, false)