LLVM 22.0.0git
RootSignatureMetadata.cpp
Go to the documentation of this file.
1//===- RootSignatureMetadata.h - HLSL Root Signature helpers --------------===//
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 implements a library for working with HLSL Root Signatures
10/// and their metadata representation.
11///
12//===----------------------------------------------------------------------===//
13
16#include "llvm/IR/IRBuilder.h"
17#include "llvm/IR/Metadata.h"
20
21using namespace llvm;
22
23namespace llvm {
24namespace hlsl {
25namespace rootsig {
26
30template <typename T> char RootSignatureValidationError<T>::ID;
31
32static std::optional<uint32_t> extractMdIntValue(MDNode *Node,
33 unsigned int OpId) {
34 if (auto *CI =
35 mdconst::dyn_extract<ConstantInt>(Node->getOperand(OpId).get()))
36 return CI->getZExtValue();
37 return std::nullopt;
38}
39
40static std::optional<float> extractMdFloatValue(MDNode *Node,
41 unsigned int OpId) {
42 if (auto *CI = mdconst::dyn_extract<ConstantFP>(Node->getOperand(OpId).get()))
43 return CI->getValueAPF().convertToFloat();
44 return std::nullopt;
45}
46
47static std::optional<StringRef> extractMdStringValue(MDNode *Node,
48 unsigned int OpId) {
49 MDString *NodeText = dyn_cast<MDString>(Node->getOperand(OpId));
50 if (NodeText == nullptr)
51 return std::nullopt;
52 return NodeText->getString();
53}
54
56extractShaderVisibility(MDNode *Node, unsigned int OpId) {
57 if (std::optional<uint32_t> Val = extractMdIntValue(Node, OpId)) {
59 return make_error<RootSignatureValidationError<uint32_t>>(
60 "ShaderVisibility", *Val);
61 return dxbc::ShaderVisibility(*Val);
62 }
63 return make_error<InvalidRSMetadataValue>("ShaderVisibility");
64}
65
66namespace {
67
68// We use the OverloadVisit with std::visit to ensure the compiler catches if a
69// new RootElement variant type is added but it's metadata generation isn't
70// handled.
71template <class... Ts> struct OverloadedVisit : Ts... {
72 using Ts::operator()...;
73};
74template <class... Ts> OverloadedVisit(Ts...) -> OverloadedVisit<Ts...>;
75
76} // namespace
77
79 const auto Visitor = OverloadedVisit{
80 [this](const dxbc::RootFlags &Flags) -> MDNode * {
81 return BuildRootFlags(Flags);
82 },
83 [this](const RootConstants &Constants) -> MDNode * {
84 return BuildRootConstants(Constants);
85 },
86 [this](const RootDescriptor &Descriptor) -> MDNode * {
87 return BuildRootDescriptor(Descriptor);
88 },
89 [this](const DescriptorTableClause &Clause) -> MDNode * {
90 return BuildDescriptorTableClause(Clause);
91 },
92 [this](const DescriptorTable &Table) -> MDNode * {
93 return BuildDescriptorTable(Table);
94 },
95 [this](const StaticSampler &Sampler) -> MDNode * {
96 return BuildStaticSampler(Sampler);
97 },
98 };
99
100 for (const RootElement &Element : Elements) {
101 MDNode *ElementMD = std::visit(Visitor, Element);
102 assert(ElementMD != nullptr &&
103 "Root Element must be initialized and validated");
104 GeneratedMetadata.push_back(ElementMD);
105 }
106
107 return MDNode::get(Ctx, GeneratedMetadata);
108}
109
110MDNode *MetadataBuilder::BuildRootFlags(const dxbc::RootFlags &Flags) {
111 IRBuilder<> Builder(Ctx);
112 Metadata *Operands[] = {
113 MDString::get(Ctx, "RootFlags"),
114 ConstantAsMetadata::get(Builder.getInt32(to_underlying(Flags))),
115 };
116 return MDNode::get(Ctx, Operands);
117}
118
119MDNode *MetadataBuilder::BuildRootConstants(const RootConstants &Constants) {
120 IRBuilder<> Builder(Ctx);
121 Metadata *Operands[] = {
122 MDString::get(Ctx, "RootConstants"),
124 Builder.getInt32(to_underlying(Constants.Visibility))),
125 ConstantAsMetadata::get(Builder.getInt32(Constants.Reg.Number)),
126 ConstantAsMetadata::get(Builder.getInt32(Constants.Space)),
127 ConstantAsMetadata::get(Builder.getInt32(Constants.Num32BitConstants)),
128 };
129 return MDNode::get(Ctx, Operands);
130}
131
132MDNode *MetadataBuilder::BuildRootDescriptor(const RootDescriptor &Descriptor) {
133 IRBuilder<> Builder(Ctx);
134 StringRef ResName = dxil::getResourceClassName(Descriptor.Type);
135 assert(!ResName.empty() && "Provided an invalid Resource Class");
136 SmallString<7> Name({"Root", ResName});
137 Metadata *Operands[] = {
138 MDString::get(Ctx, Name),
140 Builder.getInt32(to_underlying(Descriptor.Visibility))),
141 ConstantAsMetadata::get(Builder.getInt32(Descriptor.Reg.Number)),
142 ConstantAsMetadata::get(Builder.getInt32(Descriptor.Space)),
144 Builder.getInt32(to_underlying(Descriptor.Flags))),
145 };
146 return MDNode::get(Ctx, Operands);
147}
148
149MDNode *MetadataBuilder::BuildDescriptorTable(const DescriptorTable &Table) {
150 IRBuilder<> Builder(Ctx);
151 SmallVector<Metadata *> TableOperands;
152 // Set the mandatory arguments
153 TableOperands.push_back(MDString::get(Ctx, "DescriptorTable"));
155 Builder.getInt32(to_underlying(Table.Visibility))));
156
157 // Remaining operands are references to the table's clauses. The in-memory
158 // representation of the Root Elements created from parsing will ensure that
159 // the previous N elements are the clauses for this table.
160 assert(Table.NumClauses <= GeneratedMetadata.size() &&
161 "Table expected all owned clauses to be generated already");
162 // So, add a refence to each clause to our operands
163 TableOperands.append(GeneratedMetadata.end() - Table.NumClauses,
164 GeneratedMetadata.end());
165 // Then, remove those clauses from the general list of Root Elements
166 GeneratedMetadata.pop_back_n(Table.NumClauses);
167
168 return MDNode::get(Ctx, TableOperands);
169}
170
171MDNode *MetadataBuilder::BuildDescriptorTableClause(
172 const DescriptorTableClause &Clause) {
173 IRBuilder<> Builder(Ctx);
175 assert(!ResName.empty() && "Provided an invalid Resource Class");
176 Metadata *Operands[] = {
177 MDString::get(Ctx, ResName),
178 ConstantAsMetadata::get(Builder.getInt32(Clause.NumDescriptors)),
179 ConstantAsMetadata::get(Builder.getInt32(Clause.Reg.Number)),
180 ConstantAsMetadata::get(Builder.getInt32(Clause.Space)),
181 ConstantAsMetadata::get(Builder.getInt32(Clause.Offset)),
182 ConstantAsMetadata::get(Builder.getInt32(to_underlying(Clause.Flags))),
183 };
184 return MDNode::get(Ctx, Operands);
185}
186
187MDNode *MetadataBuilder::BuildStaticSampler(const StaticSampler &Sampler) {
188 IRBuilder<> Builder(Ctx);
189 Metadata *Operands[] = {
190 MDString::get(Ctx, "StaticSampler"),
191 ConstantAsMetadata::get(Builder.getInt32(to_underlying(Sampler.Filter))),
193 Builder.getInt32(to_underlying(Sampler.AddressU))),
195 Builder.getInt32(to_underlying(Sampler.AddressV))),
197 Builder.getInt32(to_underlying(Sampler.AddressW))),
199 ConstantFP::get(Type::getFloatTy(Ctx), Sampler.MipLODBias)),
200 ConstantAsMetadata::get(Builder.getInt32(Sampler.MaxAnisotropy)),
202 Builder.getInt32(to_underlying(Sampler.CompFunc))),
204 Builder.getInt32(to_underlying(Sampler.BorderColor))),
206 ConstantFP::get(Type::getFloatTy(Ctx), Sampler.MinLOD)),
208 ConstantFP::get(Type::getFloatTy(Ctx), Sampler.MaxLOD)),
209 ConstantAsMetadata::get(Builder.getInt32(Sampler.Reg.Number)),
210 ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
212 Builder.getInt32(to_underlying(Sampler.Visibility))),
213 };
214 return MDNode::get(Ctx, Operands);
215}
216
217Error MetadataParser::parseRootFlags(mcdxbc::RootSignatureDesc &RSD,
218 MDNode *RootFlagNode) {
219 if (RootFlagNode->getNumOperands() != 2)
220 return make_error<InvalidRSMetadataFormat>("RootFlag Element");
221
222 if (std::optional<uint32_t> Val = extractMdIntValue(RootFlagNode, 1))
223 RSD.Flags = *Val;
224 else
225 return make_error<InvalidRSMetadataValue>("RootFlag");
226
227 return Error::success();
228}
229
230Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD,
231 MDNode *RootConstantNode) {
232 if (RootConstantNode->getNumOperands() != 5)
233 return make_error<InvalidRSMetadataFormat>("RootConstants Element");
234
236 extractShaderVisibility(RootConstantNode, 1);
237 if (auto E = Visibility.takeError())
238 return Error(std::move(E));
239
241 if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 2))
242 Constants.ShaderRegister = *Val;
243 else
244 return make_error<InvalidRSMetadataValue>("ShaderRegister");
245
246 if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 3))
247 Constants.RegisterSpace = *Val;
248 else
249 return make_error<InvalidRSMetadataValue>("RegisterSpace");
250
251 if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 4))
252 Constants.Num32BitValues = *Val;
253 else
254 return make_error<InvalidRSMetadataValue>("Num32BitValues");
255
256 RSD.ParametersContainer.addParameter(dxbc::RootParameterType::Constants32Bit,
257 *Visibility, Constants);
258
259 return Error::success();
260}
261
262Error MetadataParser::parseRootDescriptors(
263 mcdxbc::RootSignatureDesc &RSD, MDNode *RootDescriptorNode,
264 RootSignatureElementKind ElementKind) {
265 assert((ElementKind == RootSignatureElementKind::SRV ||
266 ElementKind == RootSignatureElementKind::UAV ||
267 ElementKind == RootSignatureElementKind::CBV) &&
268 "parseRootDescriptors should only be called with RootDescriptor "
269 "element kind.");
270 if (RootDescriptorNode->getNumOperands() != 5)
271 return make_error<InvalidRSMetadataFormat>("Root Descriptor Element");
272
274 switch (ElementKind) {
276 Type = dxbc::RootParameterType::SRV;
277 break;
279 Type = dxbc::RootParameterType::UAV;
280 break;
282 Type = dxbc::RootParameterType::CBV;
283 break;
284 default:
285 llvm_unreachable("invalid Root Descriptor kind");
286 break;
287 }
288
290 extractShaderVisibility(RootDescriptorNode, 1);
291 if (auto E = Visibility.takeError())
292 return Error(std::move(E));
293
294 mcdxbc::RootDescriptor Descriptor;
295 if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 2))
296 Descriptor.ShaderRegister = *Val;
297 else
298 return make_error<InvalidRSMetadataValue>("ShaderRegister");
299
300 if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 3))
301 Descriptor.RegisterSpace = *Val;
302 else
303 return make_error<InvalidRSMetadataValue>("RegisterSpace");
304
305 if (RSD.Version == 1) {
306 RSD.ParametersContainer.addParameter(Type, *Visibility, Descriptor);
307 return Error::success();
308 }
309 assert(RSD.Version > 1);
310
311 if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 4))
312 Descriptor.Flags = *Val;
313 else
314 return make_error<InvalidRSMetadataValue>("Root Descriptor Flags");
315
316 RSD.ParametersContainer.addParameter(Type, *Visibility, Descriptor);
317 return Error::success();
318}
319
320Error MetadataParser::parseDescriptorRange(mcdxbc::DescriptorTable &Table,
321 MDNode *RangeDescriptorNode) {
322 if (RangeDescriptorNode->getNumOperands() != 6)
323 return make_error<InvalidRSMetadataFormat>("Descriptor Range");
324
326
327 std::optional<StringRef> ElementText =
328 extractMdStringValue(RangeDescriptorNode, 0);
329
330 if (!ElementText.has_value())
331 return make_error<InvalidRSMetadataFormat>("Descriptor Range");
332
333 Range.RangeType =
334 StringSwitch<uint32_t>(*ElementText)
335 .Case("CBV", to_underlying(dxbc::DescriptorRangeType::CBV))
336 .Case("SRV", to_underlying(dxbc::DescriptorRangeType::SRV))
337 .Case("UAV", to_underlying(dxbc::DescriptorRangeType::UAV))
338 .Case("Sampler", to_underlying(dxbc::DescriptorRangeType::Sampler))
339 .Default(~0U);
340
341 if (Range.RangeType == ~0U)
342 return make_error<GenericRSMetadataError>("Invalid Descriptor Range type.",
343 RangeDescriptorNode);
344
345 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 1))
346 Range.NumDescriptors = *Val;
347 else
348 return make_error<GenericRSMetadataError>("Number of Descriptor in Range",
349 RangeDescriptorNode);
350
351 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 2))
352 Range.BaseShaderRegister = *Val;
353 else
354 return make_error<InvalidRSMetadataValue>("BaseShaderRegister");
355
356 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 3))
357 Range.RegisterSpace = *Val;
358 else
359 return make_error<InvalidRSMetadataValue>("RegisterSpace");
360
361 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 4))
362 Range.OffsetInDescriptorsFromTableStart = *Val;
363 else
364 return make_error<InvalidRSMetadataValue>(
365 "OffsetInDescriptorsFromTableStart");
366
367 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 5))
368 Range.Flags = *Val;
369 else
370 return make_error<InvalidRSMetadataValue>("Descriptor Range Flags");
371
372 Table.Ranges.push_back(Range);
373 return Error::success();
374}
375
376Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
377 MDNode *DescriptorTableNode) {
378 const unsigned int NumOperands = DescriptorTableNode->getNumOperands();
379 if (NumOperands < 2)
380 return make_error<InvalidRSMetadataFormat>("Descriptor Table");
381
383 extractShaderVisibility(DescriptorTableNode, 1);
384 if (auto E = Visibility.takeError())
385 return Error(std::move(E));
386
388
389 for (unsigned int I = 2; I < NumOperands; I++) {
390 MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I));
391 if (Element == nullptr)
392 return make_error<GenericRSMetadataError>(
393 "Missing Root Element Metadata Node.", DescriptorTableNode);
394
395 if (auto Err = parseDescriptorRange(Table, Element))
396 return Err;
397 }
398
399 RSD.ParametersContainer.addParameter(dxbc::RootParameterType::DescriptorTable,
400 *Visibility, Table);
401 return Error::success();
402}
403
404Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
405 MDNode *StaticSamplerNode) {
406 if (StaticSamplerNode->getNumOperands() != 14)
407 return make_error<InvalidRSMetadataFormat>("Static Sampler");
408
410 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 1))
411 Sampler.Filter = *Val;
412 else
413 return make_error<InvalidRSMetadataValue>("Filter");
414
415 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 2))
416 Sampler.AddressU = *Val;
417 else
418 return make_error<InvalidRSMetadataValue>("AddressU");
419
420 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 3))
421 Sampler.AddressV = *Val;
422 else
423 return make_error<InvalidRSMetadataValue>("AddressV");
424
425 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 4))
426 Sampler.AddressW = *Val;
427 else
428 return make_error<InvalidRSMetadataValue>("AddressW");
429
430 if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 5))
431 Sampler.MipLODBias = *Val;
432 else
433 return make_error<InvalidRSMetadataValue>("MipLODBias");
434
435 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 6))
436 Sampler.MaxAnisotropy = *Val;
437 else
438 return make_error<InvalidRSMetadataValue>("MaxAnisotropy");
439
440 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 7))
441 Sampler.ComparisonFunc = *Val;
442 else
443 return make_error<InvalidRSMetadataValue>("ComparisonFunc");
444
445 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 8))
446 Sampler.BorderColor = *Val;
447 else
448 return make_error<InvalidRSMetadataValue>("ComparisonFunc");
449
450 if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 9))
451 Sampler.MinLOD = *Val;
452 else
453 return make_error<InvalidRSMetadataValue>("MinLOD");
454
455 if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 10))
456 Sampler.MaxLOD = *Val;
457 else
458 return make_error<InvalidRSMetadataValue>("MaxLOD");
459
460 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 11))
461 Sampler.ShaderRegister = *Val;
462 else
463 return make_error<InvalidRSMetadataValue>("ShaderRegister");
464
465 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 12))
466 Sampler.RegisterSpace = *Val;
467 else
468 return make_error<InvalidRSMetadataValue>("RegisterSpace");
469
470 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 13))
471 Sampler.ShaderVisibility = *Val;
472 else
473 return make_error<InvalidRSMetadataValue>("ShaderVisibility");
474
475 RSD.StaticSamplers.push_back(Sampler);
476 return Error::success();
477}
478
479Error MetadataParser::parseRootSignatureElement(mcdxbc::RootSignatureDesc &RSD,
480 MDNode *Element) {
481 std::optional<StringRef> ElementText = extractMdStringValue(Element, 0);
482 if (!ElementText.has_value())
483 return make_error<InvalidRSMetadataFormat>("Root Element");
484
485 RootSignatureElementKind ElementKind =
495
496 switch (ElementKind) {
497
499 return parseRootFlags(RSD, Element);
501 return parseRootConstants(RSD, Element);
505 return parseRootDescriptors(RSD, Element, ElementKind);
507 return parseDescriptorTable(RSD, Element);
509 return parseStaticSampler(RSD, Element);
511 return make_error<GenericRSMetadataError>("Invalid Root Signature Element",
512 Element);
513 }
514
515 llvm_unreachable("Unhandled RootSignatureElementKind enum.");
516}
517
518Error MetadataParser::validateRootSignature(
519 const mcdxbc::RootSignatureDesc &RSD) {
520 Error DeferredErrs = Error::success();
522 DeferredErrs =
523 joinErrors(std::move(DeferredErrs),
524 make_error<RootSignatureValidationError<uint32_t>>(
525 "Version", RSD.Version));
526 }
527
529 DeferredErrs =
530 joinErrors(std::move(DeferredErrs),
531 make_error<RootSignatureValidationError<uint32_t>>(
532 "RootFlags", RSD.Flags));
533 }
534
535 for (const mcdxbc::RootParameterInfo &Info : RSD.ParametersContainer) {
536
537 switch (Info.Type) {
538 case dxbc::RootParameterType::Constants32Bit:
539 break;
540
541 case dxbc::RootParameterType::CBV:
542 case dxbc::RootParameterType::UAV:
543 case dxbc::RootParameterType::SRV: {
544 const mcdxbc::RootDescriptor &Descriptor =
547 DeferredErrs =
548 joinErrors(std::move(DeferredErrs),
549 make_error<RootSignatureValidationError<uint32_t>>(
550 "ShaderRegister", Descriptor.ShaderRegister));
551
553 DeferredErrs =
554 joinErrors(std::move(DeferredErrs),
555 make_error<RootSignatureValidationError<uint32_t>>(
556 "RegisterSpace", Descriptor.RegisterSpace));
557
558 if (RSD.Version > 1) {
560 Descriptor.Flags))
561 DeferredErrs =
562 joinErrors(std::move(DeferredErrs),
563 make_error<RootSignatureValidationError<uint32_t>>(
564 "RootDescriptorFlag", Descriptor.Flags));
565 }
566 break;
567 }
568 case dxbc::RootParameterType::DescriptorTable: {
569 const mcdxbc::DescriptorTable &Table =
571 for (const dxbc::RTS0::v2::DescriptorRange &Range : Table) {
573 DeferredErrs =
574 joinErrors(std::move(DeferredErrs),
575 make_error<RootSignatureValidationError<uint32_t>>(
576 "RangeType", Range.RangeType));
577
578 if (!hlsl::rootsig::verifyRegisterSpace(Range.RegisterSpace))
579 DeferredErrs =
580 joinErrors(std::move(DeferredErrs),
581 make_error<RootSignatureValidationError<uint32_t>>(
582 "RegisterSpace", Range.RegisterSpace));
583
584 if (!hlsl::rootsig::verifyNumDescriptors(Range.NumDescriptors))
585 DeferredErrs =
586 joinErrors(std::move(DeferredErrs),
587 make_error<RootSignatureValidationError<uint32_t>>(
588 "NumDescriptors", Range.NumDescriptors));
589
591 RSD.Version, Range.RangeType, Range.Flags))
592 DeferredErrs =
593 joinErrors(std::move(DeferredErrs),
594 make_error<RootSignatureValidationError<uint32_t>>(
595 "DescriptorFlag", Range.Flags));
596 }
597 break;
598 }
599 }
600 }
601
602 for (const dxbc::RTS0::v1::StaticSampler &Sampler : RSD.StaticSamplers) {
604 DeferredErrs =
605 joinErrors(std::move(DeferredErrs),
606 make_error<RootSignatureValidationError<uint32_t>>(
607 "Filter", Sampler.Filter));
608
610 DeferredErrs =
611 joinErrors(std::move(DeferredErrs),
612 make_error<RootSignatureValidationError<uint32_t>>(
613 "AddressU", Sampler.AddressU));
614
616 DeferredErrs =
617 joinErrors(std::move(DeferredErrs),
618 make_error<RootSignatureValidationError<uint32_t>>(
619 "AddressV", Sampler.AddressV));
620
622 DeferredErrs =
623 joinErrors(std::move(DeferredErrs),
624 make_error<RootSignatureValidationError<uint32_t>>(
625 "AddressW", Sampler.AddressW));
626
628 DeferredErrs = joinErrors(std::move(DeferredErrs),
629 make_error<RootSignatureValidationError<float>>(
630 "MipLODBias", Sampler.MipLODBias));
631
633 DeferredErrs =
634 joinErrors(std::move(DeferredErrs),
635 make_error<RootSignatureValidationError<uint32_t>>(
636 "MaxAnisotropy", Sampler.MaxAnisotropy));
637
638 if (!hlsl::rootsig::verifyComparisonFunc(Sampler.ComparisonFunc))
639 DeferredErrs =
640 joinErrors(std::move(DeferredErrs),
641 make_error<RootSignatureValidationError<uint32_t>>(
642 "ComparisonFunc", Sampler.ComparisonFunc));
643
645 DeferredErrs =
646 joinErrors(std::move(DeferredErrs),
647 make_error<RootSignatureValidationError<uint32_t>>(
648 "BorderColor", Sampler.BorderColor));
649
651 DeferredErrs = joinErrors(std::move(DeferredErrs),
652 make_error<RootSignatureValidationError<float>>(
653 "MinLOD", Sampler.MinLOD));
654
656 DeferredErrs = joinErrors(std::move(DeferredErrs),
657 make_error<RootSignatureValidationError<float>>(
658 "MaxLOD", Sampler.MaxLOD));
659
660 if (!hlsl::rootsig::verifyRegisterValue(Sampler.ShaderRegister))
661 DeferredErrs =
662 joinErrors(std::move(DeferredErrs),
663 make_error<RootSignatureValidationError<uint32_t>>(
664 "ShaderRegister", Sampler.ShaderRegister));
665
667 DeferredErrs =
668 joinErrors(std::move(DeferredErrs),
669 make_error<RootSignatureValidationError<uint32_t>>(
670 "RegisterSpace", Sampler.RegisterSpace));
671
672 if (!dxbc::isValidShaderVisibility(Sampler.ShaderVisibility))
673 DeferredErrs =
674 joinErrors(std::move(DeferredErrs),
675 make_error<RootSignatureValidationError<uint32_t>>(
676 "ShaderVisibility", Sampler.ShaderVisibility));
677 }
678
679 return DeferredErrs;
680}
681
684 Error DeferredErrs = Error::success();
686 RSD.Version = Version;
687 for (const auto &Operand : Root->operands()) {
688 MDNode *Element = dyn_cast<MDNode>(Operand);
689 if (Element == nullptr)
690 return joinErrors(std::move(DeferredErrs),
691 make_error<GenericRSMetadataError>(
692 "Missing Root Element Metadata Node.", nullptr));
693
694 if (auto Err = parseRootSignatureElement(RSD, Element))
695 DeferredErrs = joinErrors(std::move(DeferredErrs), std::move(Err));
696 }
697
698 if (auto Err = validateRootSignature(RSD))
699 DeferredErrs = joinErrors(std::move(DeferredErrs), std::move(Err));
700
701 if (DeferredErrs)
702 return std::move(DeferredErrs);
703
704 return std::move(RSD);
705}
706} // namespace rootsig
707} // namespace hlsl
708} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
std::string Name
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
This file contains the declarations for metadata subclasses.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:535
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
Tagged union holding either a T or a Error.
Definition: Error.h:485
Error takeError()
Take ownership of the stored error.
Definition: Error.h:612
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
Metadata node.
Definition: Metadata.h:1077
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1445
ArrayRef< MDOperand > operands() const
Definition: Metadata.h:1443
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1451
A single uniqued string.
Definition: Metadata.h:720
LLVM_ABI StringRef getString() const
Definition: Metadata.cpp:617
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:607
Root of the metadata hierarchy.
Definition: Metadata.h:63
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:684
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:68
R Default(T Value)
Definition: StringSwitch.h:177
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
LLVM_ABI MDNode * BuildRootSignature()
Iterates through elements and dispatches onto the correct Build* method.
LLVM_ABI llvm::Expected< llvm::mcdxbc::RootSignatureDesc > ParseRootSignature(uint32_t Version)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isValidShaderVisibility(uint32_t V)
Definition: DXContainer.h:222
LLVM_ABI StringRef getResourceClassName(ResourceClass RC)
Definition: DXILABI.cpp:21
LLVM_ABI bool verifyAddress(uint32_t Address)
static std::optional< uint32_t > extractMdIntValue(MDNode *Node, unsigned int OpId)
LLVM_ABI bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal)
std::variant< dxbc::RootFlags, RootConstants, RootDescriptor, DescriptorTable, DescriptorTableClause, StaticSampler > RootElement
Models RootElement : RootFlags | RootConstants | RootParam | DescriptorTable | DescriptorTableClause ...
LLVM_ABI bool verifyRegisterSpace(uint32_t RegisterSpace)
LLVM_ABI bool verifyComparisonFunc(uint32_t ComparisonFunc)
static Expected< dxbc::ShaderVisibility > extractShaderVisibility(MDNode *Node, unsigned int OpId)
LLVM_ABI bool verifySamplerFilter(uint32_t Value)
LLVM_ABI bool verifyVersion(uint32_t Version)
static std::optional< StringRef > extractMdStringValue(MDNode *Node, unsigned int OpId)
LLVM_ABI bool verifyRootFlag(uint32_t Flags)
LLVM_ABI bool verifyLOD(float LOD)
LLVM_ABI bool verifyBorderColor(uint32_t BorderColor)
LLVM_ABI bool verifyMipLODBias(float MipLODBias)
LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors)
LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type, uint32_t FlagsVal)
LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy)
LLVM_ABI bool verifyRangeType(uint32_t Type)
LLVM_ABI bool verifyRegisterValue(uint32_t RegisterValue)
static std::optional< float > extractMdFloatValue(MDNode *Node, unsigned int OpId)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:442
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition: Error.h:340
SmallVector< dxbc::RTS0::v2::DescriptorRange > Ranges
const RootDescriptor & getRootDescriptor(size_t Index) const
const DescriptorTable & getDescriptorTable(size_t Index) const
void addParameter(dxbc::RootParameterType Type, dxbc::ShaderVisibility Visibility, RootConstants Constant)
SmallVector< dxbc::RTS0::v1::StaticSampler > StaticSamplers
mcdxbc::RootParametersContainer ParametersContainer