//===- DXILTranslateMetadata.cpp - Pass to emit DXIL metadata -------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "DXILTranslateMetadata.h" #include "DXILMetadata.h" #include "DXILResource.h" #include "DXILResourceAnalysis.h" #include "DXILShaderFlags.h" #include "DirectX.h" #include "llvm/ADT/StringSet.h" #include "llvm/Analysis/DXILMetadataAnalysis.h" #include "llvm/Analysis/DXILResource.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/TargetParser/Triple.h" using namespace llvm; using namespace llvm::dxil; static void emitResourceMetadata(Module &M, const DXILResourceMap &DRM, const dxil::Resources &MDResources) { LLVMContext &Context = M.getContext(); SmallVector SRVs, UAVs, CBufs, Smps; for (const ResourceInfo &RI : DRM.srvs()) SRVs.push_back(RI.getAsMetadata(Context)); for (const ResourceInfo &RI : DRM.uavs()) UAVs.push_back(RI.getAsMetadata(Context)); for (const ResourceInfo &RI : DRM.cbuffers()) CBufs.push_back(RI.getAsMetadata(Context)); for (const ResourceInfo &RI : DRM.samplers()) Smps.push_back(RI.getAsMetadata(Context)); Metadata *SRVMD = SRVs.empty() ? nullptr : MDNode::get(Context, SRVs); Metadata *UAVMD = UAVs.empty() ? nullptr : MDNode::get(Context, UAVs); Metadata *CBufMD = CBufs.empty() ? nullptr : MDNode::get(Context, CBufs); Metadata *SmpMD = Smps.empty() ? nullptr : MDNode::get(Context, Smps); bool HasResources = !DRM.empty(); if (MDResources.hasUAVs()) { assert(!UAVMD && "Old and new UAV representations can't coexist"); UAVMD = MDResources.writeUAVs(M); HasResources = true; } if (MDResources.hasCBuffers()) { assert(!CBufMD && "Old and new cbuffer representations can't coexist"); CBufMD = MDResources.writeCBuffers(M); HasResources = true; } if (!HasResources) return; NamedMDNode *ResourceMD = M.getOrInsertNamedMetadata("dx.resources"); ResourceMD->addOperand( MDNode::get(M.getContext(), {SRVMD, UAVMD, CBufMD, SmpMD})); } static void translateMetadata(Module &M, const DXILResourceMap &DRM, const dxil::Resources &MDResources, const ComputedShaderFlags &ShaderFlags) { dxil::ValidatorVersionMD ValVerMD(M); if (ValVerMD.isEmpty()) ValVerMD.update(VersionTuple(1, 0)); dxil::createShaderModelMD(M); dxil::createDXILVersionMD(M); emitResourceMetadata(M, DRM, MDResources); dxil::createEntryMD(M, static_cast(ShaderFlags)); } PreservedAnalyses DXILTranslateMetadata::run(Module &M, ModuleAnalysisManager &MAM) { const DXILResourceMap &DRM = MAM.getResult(M); const dxil::Resources &MDResources = MAM.getResult(M); const ComputedShaderFlags &ShaderFlags = MAM.getResult(M); translateMetadata(M, DRM, MDResources, ShaderFlags); return PreservedAnalyses::all(); } namespace { class DXILTranslateMetadataLegacy : public ModulePass { public: static char ID; // Pass identification, replacement for typeid explicit DXILTranslateMetadataLegacy() : ModulePass(ID) {} StringRef getPassName() const override { return "DXIL Translate Metadata"; } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); } bool runOnModule(Module &M) override { const DXILResourceMap &DRM = getAnalysis().getResourceMap(); const dxil::Resources &MDResources = getAnalysis().getDXILResource(); const ComputedShaderFlags &ShaderFlags = getAnalysis().getShaderFlags(); translateMetadata(M, DRM, MDResources, ShaderFlags); return true; } }; } // namespace char DXILTranslateMetadataLegacy::ID = 0; ModulePass *llvm::createDXILTranslateMetadataLegacyPass() { return new DXILTranslateMetadataLegacy(); } INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata", "DXIL Translate Metadata", false, false) INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass) INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper) INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper) INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, "dxil-translate-metadata", "DXIL Translate Metadata", false, false)