1 //===- HLSLRootSignature.h - HLSL Root Signature helper objects -----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file This file contains structure definitions of HLSL Root Signature 10 /// objects. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H 15 #define LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H 16 17 #include "llvm/BinaryFormat/DXContainer.h" 18 #include "llvm/Support/Compiler.h" 19 #include "llvm/Support/DXILABI.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include <limits> 22 #include <variant> 23 24 namespace llvm { 25 namespace hlsl { 26 namespace rootsig { 27 28 // Definitions of the in-memory data layout structures 29 30 // Models the different registers: bReg | tReg | uReg | sReg 31 enum class RegisterType { BReg, TReg, UReg, SReg }; 32 struct Register { 33 RegisterType ViewType; 34 uint32_t Number; 35 }; 36 37 // Models the parameter values of root constants 38 struct RootConstants { 39 uint32_t Num32BitConstants; 40 Register Reg; 41 uint32_t Space = 0; 42 dxbc::ShaderVisibility Visibility = dxbc::ShaderVisibility::All; 43 }; 44 45 enum class DescriptorType : uint8_t { SRV = 0, UAV, CBuffer }; 46 // Models RootDescriptor : CBV | SRV | UAV, by collecting like parameters 47 struct RootDescriptor { 48 DescriptorType Type; 49 Register Reg; 50 uint32_t Space = 0; 51 dxbc::ShaderVisibility Visibility = dxbc::ShaderVisibility::All; 52 dxbc::RootDescriptorFlags Flags; 53 setDefaultFlagsRootDescriptor54 void setDefaultFlags(dxbc::RootSignatureVersion Version) { 55 if (Version == dxbc::RootSignatureVersion::V1_0) { 56 Flags = dxbc::RootDescriptorFlags::DataVolatile; 57 return; 58 } 59 60 assert(Version == llvm::dxbc::RootSignatureVersion::V1_1 && 61 "Specified an invalid root signature version"); 62 switch (Type) { 63 case DescriptorType::CBuffer: 64 case DescriptorType::SRV: 65 Flags = dxbc::RootDescriptorFlags::DataStaticWhileSetAtExecute; 66 break; 67 case DescriptorType::UAV: 68 Flags = dxbc::RootDescriptorFlags::DataVolatile; 69 break; 70 } 71 } 72 }; 73 74 // Models the end of a descriptor table and stores its visibility 75 struct DescriptorTable { 76 dxbc::ShaderVisibility Visibility = dxbc::ShaderVisibility::All; 77 // Denotes that the previous NumClauses in the RootElement array 78 // are the clauses in the table. 79 uint32_t NumClauses = 0; 80 }; 81 82 static const uint32_t NumDescriptorsUnbounded = 0xffffffff; 83 static const uint32_t DescriptorTableOffsetAppend = 0xffffffff; 84 // Models DTClause : CBV | SRV | UAV | Sampler, by collecting like parameters 85 using ClauseType = llvm::dxil::ResourceClass; 86 struct DescriptorTableClause { 87 ClauseType Type; 88 Register Reg; 89 uint32_t NumDescriptors = 1; 90 uint32_t Space = 0; 91 uint32_t Offset = DescriptorTableOffsetAppend; 92 dxbc::DescriptorRangeFlags Flags; 93 setDefaultFlagsDescriptorTableClause94 void setDefaultFlags(dxbc::RootSignatureVersion Version) { 95 if (Version == dxbc::RootSignatureVersion::V1_0) { 96 Flags = dxbc::DescriptorRangeFlags::DescriptorsVolatile; 97 if (Type != ClauseType::Sampler) 98 Flags |= dxbc::DescriptorRangeFlags::DataVolatile; 99 return; 100 } 101 102 assert(Version == dxbc::RootSignatureVersion::V1_1 && 103 "Specified an invalid root signature version"); 104 switch (Type) { 105 case ClauseType::CBuffer: 106 case ClauseType::SRV: 107 Flags = dxbc::DescriptorRangeFlags::DataStaticWhileSetAtExecute; 108 break; 109 case ClauseType::UAV: 110 Flags = dxbc::DescriptorRangeFlags::DataVolatile; 111 break; 112 case ClauseType::Sampler: 113 Flags = dxbc::DescriptorRangeFlags::None; 114 break; 115 } 116 } 117 }; 118 119 struct StaticSampler { 120 Register Reg; 121 dxbc::SamplerFilter Filter = dxbc::SamplerFilter::Anisotropic; 122 dxbc::TextureAddressMode AddressU = dxbc::TextureAddressMode::Wrap; 123 dxbc::TextureAddressMode AddressV = dxbc::TextureAddressMode::Wrap; 124 dxbc::TextureAddressMode AddressW = dxbc::TextureAddressMode::Wrap; 125 float MipLODBias = 0.f; 126 uint32_t MaxAnisotropy = 16; 127 dxbc::ComparisonFunc CompFunc = dxbc::ComparisonFunc::LessEqual; 128 dxbc::StaticBorderColor BorderColor = dxbc::StaticBorderColor::OpaqueWhite; 129 float MinLOD = 0.f; 130 float MaxLOD = std::numeric_limits<float>::max(); 131 uint32_t Space = 0; 132 dxbc::ShaderVisibility Visibility = dxbc::ShaderVisibility::All; 133 }; 134 135 /// Models RootElement : RootFlags | RootConstants | RootParam 136 /// | DescriptorTable | DescriptorTableClause | StaticSampler 137 /// 138 /// A Root Signature is modeled in-memory by an array of RootElements. These 139 /// aim to map closely to their DSL grammar reprsentation defined in the spec. 140 /// 141 /// Each optional parameter has its default value defined in the struct, and, 142 /// each mandatory parameter does not have a default initialization. 143 /// 144 /// For the variants RootFlags, RootConstants, RootParam, StaticSampler and 145 /// DescriptorTableClause: each data member maps directly to a parameter in the 146 /// grammar. 147 /// 148 /// The DescriptorTable is modelled by having its Clauses as the previous 149 /// RootElements in the array, and it holds a data member for the Visibility 150 /// parameter. 151 using RootElement = 152 std::variant<dxbc::RootFlags, RootConstants, RootDescriptor, 153 DescriptorTable, DescriptorTableClause, StaticSampler>; 154 155 /// The following contains the serialization interface for root elements 156 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const dxbc::RootFlags &Flags); 157 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, 158 const RootConstants &Constants); 159 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, 160 const DescriptorTableClause &Clause); 161 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const DescriptorTable &Table); 162 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, 163 const RootDescriptor &Descriptor); 164 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, 165 const StaticSampler &StaticSampler); 166 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const RootElement &Element); 167 168 LLVM_ABI void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements); 169 170 } // namespace rootsig 171 } // namespace hlsl 172 } // namespace llvm 173 174 #endif // LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H 175