1*bdd1243dSDimitry Andric //===- DXILResource.h - DXIL Resource helper objects ----------------------===// 2*bdd1243dSDimitry Andric // 3*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bdd1243dSDimitry Andric // 7*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 8*bdd1243dSDimitry Andric /// 9*bdd1243dSDimitry Andric /// \file This file contains helper objects for working with DXIL Resources. 10*bdd1243dSDimitry Andric /// 11*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 12*bdd1243dSDimitry Andric 13*bdd1243dSDimitry Andric #ifndef LLVM_TARGET_DIRECTX_DXILRESOURCE_H 14*bdd1243dSDimitry Andric #define LLVM_TARGET_DIRECTX_DXILRESOURCE_H 15*bdd1243dSDimitry Andric 16*bdd1243dSDimitry Andric #include "llvm/ADT/SmallVector.h" 17*bdd1243dSDimitry Andric #include "llvm/ADT/StringRef.h" 18*bdd1243dSDimitry Andric #include "llvm/Frontend/HLSL/HLSLResource.h" 19*bdd1243dSDimitry Andric #include "llvm/IR/Metadata.h" 20*bdd1243dSDimitry Andric #include "llvm/Support/Compiler.h" 21*bdd1243dSDimitry Andric #include <cstdint> 22*bdd1243dSDimitry Andric 23*bdd1243dSDimitry Andric namespace llvm { 24*bdd1243dSDimitry Andric class Module; 25*bdd1243dSDimitry Andric class GlobalVariable; 26*bdd1243dSDimitry Andric 27*bdd1243dSDimitry Andric namespace dxil { 28*bdd1243dSDimitry Andric class CBufferDataLayout; 29*bdd1243dSDimitry Andric 30*bdd1243dSDimitry Andric class ResourceBase { 31*bdd1243dSDimitry Andric protected: 32*bdd1243dSDimitry Andric uint32_t ID; 33*bdd1243dSDimitry Andric GlobalVariable *GV; 34*bdd1243dSDimitry Andric StringRef Name; 35*bdd1243dSDimitry Andric uint32_t Space; 36*bdd1243dSDimitry Andric uint32_t LowerBound; 37*bdd1243dSDimitry Andric uint32_t RangeSize; 38*bdd1243dSDimitry Andric ResourceBase(uint32_t I, hlsl::FrontendResource R); 39*bdd1243dSDimitry Andric 40*bdd1243dSDimitry Andric void write(LLVMContext &Ctx, MutableArrayRef<Metadata *> Entries) const; 41*bdd1243dSDimitry Andric 42*bdd1243dSDimitry Andric void print(raw_ostream &O, StringRef IDPrefix, StringRef BindingPrefix) const; 43*bdd1243dSDimitry Andric using Kinds = hlsl::ResourceKind; 44*bdd1243dSDimitry Andric static StringRef getKindName(Kinds Kind); 45*bdd1243dSDimitry Andric static void printKind(Kinds Kind, unsigned Alignment, raw_ostream &OS, 46*bdd1243dSDimitry Andric bool SRV = false, bool HasCounter = false, 47*bdd1243dSDimitry Andric uint32_t SampleCount = 0); 48*bdd1243dSDimitry Andric 49*bdd1243dSDimitry Andric // The value ordering of this enumeration is part of the DXIL ABI. Elements 50*bdd1243dSDimitry Andric // can only be added to the end, and not removed. 51*bdd1243dSDimitry Andric enum class ComponentType : uint32_t { 52*bdd1243dSDimitry Andric Invalid = 0, 53*bdd1243dSDimitry Andric I1, 54*bdd1243dSDimitry Andric I16, 55*bdd1243dSDimitry Andric U16, 56*bdd1243dSDimitry Andric I32, 57*bdd1243dSDimitry Andric U32, 58*bdd1243dSDimitry Andric I64, 59*bdd1243dSDimitry Andric U64, 60*bdd1243dSDimitry Andric F16, 61*bdd1243dSDimitry Andric F32, 62*bdd1243dSDimitry Andric F64, 63*bdd1243dSDimitry Andric SNormF16, 64*bdd1243dSDimitry Andric UNormF16, 65*bdd1243dSDimitry Andric SNormF32, 66*bdd1243dSDimitry Andric UNormF32, 67*bdd1243dSDimitry Andric SNormF64, 68*bdd1243dSDimitry Andric UNormF64, 69*bdd1243dSDimitry Andric PackedS8x32, 70*bdd1243dSDimitry Andric PackedU8x32, 71*bdd1243dSDimitry Andric LastEntry 72*bdd1243dSDimitry Andric }; 73*bdd1243dSDimitry Andric 74*bdd1243dSDimitry Andric static StringRef getComponentTypeName(ComponentType CompType); 75*bdd1243dSDimitry Andric static void printComponentType(Kinds Kind, ComponentType CompType, 76*bdd1243dSDimitry Andric unsigned Alignment, raw_ostream &OS); 77*bdd1243dSDimitry Andric 78*bdd1243dSDimitry Andric public: 79*bdd1243dSDimitry Andric struct ExtendedProperties { 80*bdd1243dSDimitry Andric std::optional<ComponentType> ElementType; 81*bdd1243dSDimitry Andric 82*bdd1243dSDimitry Andric // The value ordering of this enumeration is part of the DXIL ABI. Elements 83*bdd1243dSDimitry Andric // can only be added to the end, and not removed. 84*bdd1243dSDimitry Andric enum Tags : uint32_t { 85*bdd1243dSDimitry Andric TypedBufferElementType = 0, 86*bdd1243dSDimitry Andric StructuredBufferElementStride, 87*bdd1243dSDimitry Andric SamplerFeedbackKind, 88*bdd1243dSDimitry Andric Atomic64Use 89*bdd1243dSDimitry Andric }; 90*bdd1243dSDimitry Andric 91*bdd1243dSDimitry Andric MDNode *write(LLVMContext &Ctx) const; 92*bdd1243dSDimitry Andric }; 93*bdd1243dSDimitry Andric }; 94*bdd1243dSDimitry Andric 95*bdd1243dSDimitry Andric class UAVResource : public ResourceBase { 96*bdd1243dSDimitry Andric ResourceBase::Kinds Shape; 97*bdd1243dSDimitry Andric bool GloballyCoherent; 98*bdd1243dSDimitry Andric bool HasCounter; 99*bdd1243dSDimitry Andric bool IsROV; 100*bdd1243dSDimitry Andric ResourceBase::ExtendedProperties ExtProps; 101*bdd1243dSDimitry Andric 102*bdd1243dSDimitry Andric void parseSourceType(StringRef S); 103*bdd1243dSDimitry Andric 104*bdd1243dSDimitry Andric public: 105*bdd1243dSDimitry Andric UAVResource(uint32_t I, hlsl::FrontendResource R); 106*bdd1243dSDimitry Andric 107*bdd1243dSDimitry Andric MDNode *write() const; 108*bdd1243dSDimitry Andric void print(raw_ostream &O) const; 109*bdd1243dSDimitry Andric }; 110*bdd1243dSDimitry Andric 111*bdd1243dSDimitry Andric class ConstantBuffer : public ResourceBase { 112*bdd1243dSDimitry Andric uint32_t CBufferSizeInBytes = 0; // Cbuffer used size in bytes. 113*bdd1243dSDimitry Andric public: 114*bdd1243dSDimitry Andric ConstantBuffer(uint32_t I, hlsl::FrontendResource R); 115*bdd1243dSDimitry Andric void setSize(CBufferDataLayout &DL); 116*bdd1243dSDimitry Andric MDNode *write() const; 117*bdd1243dSDimitry Andric void print(raw_ostream &O) const; 118*bdd1243dSDimitry Andric }; 119*bdd1243dSDimitry Andric 120*bdd1243dSDimitry Andric template <typename T> class ResourceTable { 121*bdd1243dSDimitry Andric StringRef MDName; 122*bdd1243dSDimitry Andric 123*bdd1243dSDimitry Andric llvm::SmallVector<T> Data; 124*bdd1243dSDimitry Andric 125*bdd1243dSDimitry Andric public: 126*bdd1243dSDimitry Andric ResourceTable(StringRef Name) : MDName(Name) {} 127*bdd1243dSDimitry Andric void collect(Module &M); 128*bdd1243dSDimitry Andric MDNode *write(Module &M) const; 129*bdd1243dSDimitry Andric void print(raw_ostream &O) const; 130*bdd1243dSDimitry Andric }; 131*bdd1243dSDimitry Andric 132*bdd1243dSDimitry Andric // FIXME: Fully computing the resource structures requires analyzing the IR 133*bdd1243dSDimitry Andric // because some flags are set based on what operations are performed on the 134*bdd1243dSDimitry Andric // resource. This partial patch handles some of the leg work, but not all of it. 135*bdd1243dSDimitry Andric // See issue https://github.com/llvm/llvm-project/issues/57936. 136*bdd1243dSDimitry Andric class Resources { 137*bdd1243dSDimitry Andric ResourceTable<UAVResource> UAVs = {"hlsl.uavs"}; 138*bdd1243dSDimitry Andric ResourceTable<ConstantBuffer> CBuffers = {"hlsl.cbufs"}; 139*bdd1243dSDimitry Andric 140*bdd1243dSDimitry Andric public: 141*bdd1243dSDimitry Andric void collect(Module &M); 142*bdd1243dSDimitry Andric void write(Module &M) const; 143*bdd1243dSDimitry Andric void print(raw_ostream &O) const; 144*bdd1243dSDimitry Andric LLVM_DUMP_METHOD void dump() const; 145*bdd1243dSDimitry Andric }; 146*bdd1243dSDimitry Andric 147*bdd1243dSDimitry Andric } // namespace dxil 148*bdd1243dSDimitry Andric } // namespace llvm 149*bdd1243dSDimitry Andric 150*bdd1243dSDimitry Andric #endif // LLVM_TARGET_DIRECTX_DXILRESOURCE_H 151