Thanks to visit codestin.com
Credit goes to llvm.org

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
55template <typename T, typename = std::enable_if_t<
56 std::is_enum_v<T> &&
57 std::is_same_v<std::underlying_type_t<T>, uint32_t>>>
58Expected<T> extractEnumValue(MDNode *Node, unsigned int OpId, StringRef ErrText,
59 llvm::function_ref<bool(uint32_t)> VerifyFn) {
60 if (std::optional<uint32_t> Val = extractMdIntValue(Node, OpId)) {
61 if (!VerifyFn(*Val))
63 return static_cast<T>(*Val);
64 }
65 return make_error<InvalidRSMetadataValue>("ShaderVisibility");
66}
67
68namespace {
69
70// We use the OverloadVisit with std::visit to ensure the compiler catches if a
71// new RootElement variant type is added but it's metadata generation isn't
72// handled.
73template <class... Ts> struct OverloadedVisit : Ts... {
74 using Ts::operator()...;
75};
76template <class... Ts> OverloadedVisit(Ts...) -> OverloadedVisit<Ts...>;
77
78} // namespace
79
81 const auto Visitor = OverloadedVisit{
82 [this](const dxbc::RootFlags &Flags) -> MDNode * {
83 return BuildRootFlags(Flags);
84 },
85 [this](const RootConstants &Constants) -> MDNode * {
86 return BuildRootConstants(Constants);
87 },
88 [this](const RootDescriptor &Descriptor) -> MDNode * {
89 return BuildRootDescriptor(Descriptor);
90 },
91 [this](const DescriptorTableClause &Clause) -> MDNode * {
92 return BuildDescriptorTableClause(Clause);
93 },
94 [this](const DescriptorTable &Table) -> MDNode * {
95 return BuildDescriptorTable(Table);
96 },
97 [this](const StaticSampler &Sampler) -> MDNode * {
98 return BuildStaticSampler(Sampler);
99 },
100 };
101
102 for (const RootElement &Element : Elements) {
103 MDNode *ElementMD = std::visit(Visitor, Element);
104 assert(ElementMD != nullptr &&
105 "Root Element must be initialized and validated");
106 GeneratedMetadata.push_back(ElementMD);
107 }
108
109 return MDNode::get(Ctx, GeneratedMetadata);
110}
111
112MDNode *MetadataBuilder::BuildRootFlags(const dxbc::RootFlags &Flags) {
113 IRBuilder<> Builder(Ctx);
114 Metadata *Operands[] = {
115 MDString::get(Ctx, "RootFlags"),
116 ConstantAsMetadata::get(Builder.getInt32(to_underlying(Flags))),
117 };
118 return MDNode::get(Ctx, Operands);
119}
120
121MDNode *MetadataBuilder::BuildRootConstants(const RootConstants &Constants) {
122 IRBuilder<> Builder(Ctx);
123 Metadata *Operands[] = {
124 MDString::get(Ctx, "RootConstants"),
126 Builder.getInt32(to_underlying(Constants.Visibility))),
127 ConstantAsMetadata::get(Builder.getInt32(Constants.Reg.Number)),
128 ConstantAsMetadata::get(Builder.getInt32(Constants.Space)),
129 ConstantAsMetadata::get(Builder.getInt32(Constants.Num32BitConstants)),
130 };
131 return MDNode::get(Ctx, Operands);
132}
133
134MDNode *MetadataBuilder::BuildRootDescriptor(const RootDescriptor &Descriptor) {
135 IRBuilder<> Builder(Ctx);
136 StringRef ResName = dxil::getResourceClassName(Descriptor.Type);
137 assert(!ResName.empty() && "Provided an invalid Resource Class");
138 SmallString<7> Name({"Root", ResName});
139 Metadata *Operands[] = {
140 MDString::get(Ctx, Name),
142 Builder.getInt32(to_underlying(Descriptor.Visibility))),
143 ConstantAsMetadata::get(Builder.getInt32(Descriptor.Reg.Number)),
144 ConstantAsMetadata::get(Builder.getInt32(Descriptor.Space)),
146 Builder.getInt32(to_underlying(Descriptor.Flags))),
147 };
148 return MDNode::get(Ctx, Operands);
149}
150
151MDNode *MetadataBuilder::BuildDescriptorTable(const DescriptorTable &Table) {
152 IRBuilder<> Builder(Ctx);
153 SmallVector<Metadata *> TableOperands;
154 // Set the mandatory arguments
155 TableOperands.push_back(MDString::get(Ctx, "DescriptorTable"));
157 Builder.getInt32(to_underlying(Table.Visibility))));
158
159 // Remaining operands are references to the table's clauses. The in-memory
160 // representation of the Root Elements created from parsing will ensure that
161 // the previous N elements are the clauses for this table.
162 assert(Table.NumClauses <= GeneratedMetadata.size() &&
163 "Table expected all owned clauses to be generated already");
164 // So, add a refence to each clause to our operands
165 TableOperands.append(GeneratedMetadata.end() - Table.NumClauses,
166 GeneratedMetadata.end());
167 // Then, remove those clauses from the general list of Root Elements
168 GeneratedMetadata.pop_back_n(Table.NumClauses);
169
170 return MDNode::get(Ctx, TableOperands);
171}
172
173MDNode *MetadataBuilder::BuildDescriptorTableClause(
174 const DescriptorTableClause &Clause) {
175 IRBuilder<> Builder(Ctx);
176 StringRef ResName = dxil::getResourceClassName(Clause.Type);
177 assert(!ResName.empty() && "Provided an invalid Resource Class");
178 Metadata *Operands[] = {
179 MDString::get(Ctx, ResName),
180 ConstantAsMetadata::get(Builder.getInt32(Clause.NumDescriptors)),
181 ConstantAsMetadata::get(Builder.getInt32(Clause.Reg.Number)),
182 ConstantAsMetadata::get(Builder.getInt32(Clause.Space)),
183 ConstantAsMetadata::get(Builder.getInt32(Clause.Offset)),
184 ConstantAsMetadata::get(Builder.getInt32(to_underlying(Clause.Flags))),
185 };
186 return MDNode::get(Ctx, Operands);
187}
188
189MDNode *MetadataBuilder::BuildStaticSampler(const StaticSampler &Sampler) {
190 IRBuilder<> Builder(Ctx);
191 Metadata *Operands[] = {
192 MDString::get(Ctx, "StaticSampler"),
193 ConstantAsMetadata::get(Builder.getInt32(to_underlying(Sampler.Filter))),
195 Builder.getInt32(to_underlying(Sampler.AddressU))),
197 Builder.getInt32(to_underlying(Sampler.AddressV))),
199 Builder.getInt32(to_underlying(Sampler.AddressW))),
201 ConstantFP::get(Type::getFloatTy(Ctx), Sampler.MipLODBias)),
202 ConstantAsMetadata::get(Builder.getInt32(Sampler.MaxAnisotropy)),
204 Builder.getInt32(to_underlying(Sampler.CompFunc))),
206 Builder.getInt32(to_underlying(Sampler.BorderColor))),
208 ConstantFP::get(Type::getFloatTy(Ctx), Sampler.MinLOD)),
210 ConstantFP::get(Type::getFloatTy(Ctx), Sampler.MaxLOD)),
211 ConstantAsMetadata::get(Builder.getInt32(Sampler.Reg.Number)),
212 ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
214 Builder.getInt32(to_underlying(Sampler.Visibility))),
215 };
216 return MDNode::get(Ctx, Operands);
217}
218
219Error MetadataParser::parseRootFlags(mcdxbc::RootSignatureDesc &RSD,
220 MDNode *RootFlagNode) {
221 if (RootFlagNode->getNumOperands() != 2)
222 return make_error<InvalidRSMetadataFormat>("RootFlag Element");
223
224 if (std::optional<uint32_t> Val = extractMdIntValue(RootFlagNode, 1))
225 RSD.Flags = *Val;
226 else
227 return make_error<InvalidRSMetadataValue>("RootFlag");
228
229 return Error::success();
230}
231
232Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD,
233 MDNode *RootConstantNode) {
234 if (RootConstantNode->getNumOperands() != 5)
235 return make_error<InvalidRSMetadataFormat>("RootConstants Element");
236
237 Expected<dxbc::ShaderVisibility> Visibility =
239 "ShaderVisibility",
241 if (auto E = Visibility.takeError())
242 return Error(std::move(E));
243
244 mcdxbc::RootConstants Constants;
245 if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 2))
246 Constants.ShaderRegister = *Val;
247 else
248 return make_error<InvalidRSMetadataValue>("ShaderRegister");
249
250 if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 3))
251 Constants.RegisterSpace = *Val;
252 else
253 return make_error<InvalidRSMetadataValue>("RegisterSpace");
254
255 if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 4))
256 Constants.Num32BitValues = *Val;
257 else
258 return make_error<InvalidRSMetadataValue>("Num32BitValues");
259
260 RSD.ParametersContainer.addParameter(dxbc::RootParameterType::Constants32Bit,
261 *Visibility, Constants);
262
263 return Error::success();
264}
265
266Error MetadataParser::parseRootDescriptors(
267 mcdxbc::RootSignatureDesc &RSD, MDNode *RootDescriptorNode,
268 RootSignatureElementKind ElementKind) {
269 assert((ElementKind == RootSignatureElementKind::SRV ||
270 ElementKind == RootSignatureElementKind::UAV ||
271 ElementKind == RootSignatureElementKind::CBV) &&
272 "parseRootDescriptors should only be called with RootDescriptor "
273 "element kind.");
274 if (RootDescriptorNode->getNumOperands() != 5)
275 return make_error<InvalidRSMetadataFormat>("Root Descriptor Element");
276
278 switch (ElementKind) {
280 Type = dxbc::RootParameterType::SRV;
281 break;
283 Type = dxbc::RootParameterType::UAV;
284 break;
286 Type = dxbc::RootParameterType::CBV;
287 break;
288 default:
289 llvm_unreachable("invalid Root Descriptor kind");
290 break;
291 }
292
293 Expected<dxbc::ShaderVisibility> Visibility =
294 extractEnumValue<dxbc::ShaderVisibility>(RootDescriptorNode, 1,
295 "ShaderVisibility",
297 if (auto E = Visibility.takeError())
298 return Error(std::move(E));
299
300 mcdxbc::RootDescriptor Descriptor;
301 if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 2))
302 Descriptor.ShaderRegister = *Val;
303 else
304 return make_error<InvalidRSMetadataValue>("ShaderRegister");
305
306 if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 3))
307 Descriptor.RegisterSpace = *Val;
308 else
309 return make_error<InvalidRSMetadataValue>("RegisterSpace");
310
311 if (RSD.Version == 1) {
312 RSD.ParametersContainer.addParameter(Type, *Visibility, Descriptor);
313 return Error::success();
314 }
315 assert(RSD.Version > 1);
316
317 if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 4))
318 Descriptor.Flags = *Val;
319 else
320 return make_error<InvalidRSMetadataValue>("Root Descriptor Flags");
321
322 RSD.ParametersContainer.addParameter(Type, *Visibility, Descriptor);
323 return Error::success();
324}
325
326Error MetadataParser::parseDescriptorRange(mcdxbc::DescriptorTable &Table,
327 MDNode *RangeDescriptorNode) {
328 if (RangeDescriptorNode->getNumOperands() != 6)
329 return make_error<InvalidRSMetadataFormat>("Descriptor Range");
330
331 mcdxbc::DescriptorRange Range;
332
333 std::optional<StringRef> ElementText =
334 extractMdStringValue(RangeDescriptorNode, 0);
335
336 if (!ElementText.has_value())
337 return make_error<InvalidRSMetadataFormat>("Descriptor Range");
338
339 if (*ElementText == "CBV")
341 else if (*ElementText == "SRV")
343 else if (*ElementText == "UAV")
345 else if (*ElementText == "Sampler")
347 else
348 return make_error<GenericRSMetadataError>("Invalid Descriptor Range type.",
349 RangeDescriptorNode);
350
351 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 1))
352 Range.NumDescriptors = *Val;
353 else
354 return make_error<GenericRSMetadataError>("Number of Descriptor in Range",
355 RangeDescriptorNode);
356
357 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 2))
358 Range.BaseShaderRegister = *Val;
359 else
360 return make_error<InvalidRSMetadataValue>("BaseShaderRegister");
361
362 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 3))
363 Range.RegisterSpace = *Val;
364 else
365 return make_error<InvalidRSMetadataValue>("RegisterSpace");
366
367 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 4))
368 Range.OffsetInDescriptorsFromTableStart = *Val;
369 else
371 "OffsetInDescriptorsFromTableStart");
372
373 if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 5))
374 Range.Flags = *Val;
375 else
376 return make_error<InvalidRSMetadataValue>("Descriptor Range Flags");
377
378 Table.Ranges.push_back(Range);
379 return Error::success();
380}
381
382Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
383 MDNode *DescriptorTableNode) {
384 const unsigned int NumOperands = DescriptorTableNode->getNumOperands();
385 if (NumOperands < 2)
386 return make_error<InvalidRSMetadataFormat>("Descriptor Table");
387
388 Expected<dxbc::ShaderVisibility> Visibility =
389 extractEnumValue<dxbc::ShaderVisibility>(DescriptorTableNode, 1,
390 "ShaderVisibility",
392 if (auto E = Visibility.takeError())
393 return Error(std::move(E));
394
395 mcdxbc::DescriptorTable Table;
396
397 for (unsigned int I = 2; I < NumOperands; I++) {
398 MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I));
399 if (Element == nullptr)
401 "Missing Root Element Metadata Node.", DescriptorTableNode);
402
403 if (auto Err = parseDescriptorRange(Table, Element))
404 return Err;
405 }
406
407 RSD.ParametersContainer.addParameter(dxbc::RootParameterType::DescriptorTable,
408 *Visibility, Table);
409 return Error::success();
410}
411
412Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
413 MDNode *StaticSamplerNode) {
414 if (StaticSamplerNode->getNumOperands() != 14)
415 return make_error<InvalidRSMetadataFormat>("Static Sampler");
416
417 mcdxbc::StaticSampler Sampler;
418
419 Expected<dxbc::SamplerFilter> Filter = extractEnumValue<dxbc::SamplerFilter>(
420 StaticSamplerNode, 1, "Filter", dxbc::isValidSamplerFilter);
421 if (auto E = Filter.takeError())
422 return Error(std::move(E));
423 Sampler.Filter = *Filter;
424
425 Expected<dxbc::TextureAddressMode> AddressU =
427 StaticSamplerNode, 2, "AddressU", dxbc::isValidAddress);
428 if (auto E = AddressU.takeError())
429 return Error(std::move(E));
430 Sampler.AddressU = *AddressU;
431
432 Expected<dxbc::TextureAddressMode> AddressV =
434 StaticSamplerNode, 3, "AddressV", dxbc::isValidAddress);
435 if (auto E = AddressV.takeError())
436 return Error(std::move(E));
437 Sampler.AddressV = *AddressV;
438
439 Expected<dxbc::TextureAddressMode> AddressW =
441 StaticSamplerNode, 4, "AddressW", dxbc::isValidAddress);
442 if (auto E = AddressW.takeError())
443 return Error(std::move(E));
444 Sampler.AddressW = *AddressW;
445
446 if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 5))
447 Sampler.MipLODBias = *Val;
448 else
449 return make_error<InvalidRSMetadataValue>("MipLODBias");
450
451 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 6))
452 Sampler.MaxAnisotropy = *Val;
453 else
454 return make_error<InvalidRSMetadataValue>("MaxAnisotropy");
455
456 Expected<dxbc::ComparisonFunc> ComparisonFunc =
458 StaticSamplerNode, 7, "ComparisonFunc", dxbc::isValidComparisonFunc);
459 if (auto E = ComparisonFunc.takeError())
460 return Error(std::move(E));
461 Sampler.ComparisonFunc = *ComparisonFunc;
462
463 Expected<dxbc::StaticBorderColor> BorderColor =
465 StaticSamplerNode, 8, "BorderColor", dxbc::isValidBorderColor);
466 if (auto E = BorderColor.takeError())
467 return Error(std::move(E));
468 Sampler.BorderColor = *BorderColor;
469
470 if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 9))
471 Sampler.MinLOD = *Val;
472 else
473 return make_error<InvalidRSMetadataValue>("MinLOD");
474
475 if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 10))
476 Sampler.MaxLOD = *Val;
477 else
478 return make_error<InvalidRSMetadataValue>("MaxLOD");
479
480 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 11))
481 Sampler.ShaderRegister = *Val;
482 else
483 return make_error<InvalidRSMetadataValue>("ShaderRegister");
484
485 if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 12))
486 Sampler.RegisterSpace = *Val;
487 else
488 return make_error<InvalidRSMetadataValue>("RegisterSpace");
489
490 Expected<dxbc::ShaderVisibility> Visibility =
491 extractEnumValue<dxbc::ShaderVisibility>(StaticSamplerNode, 13,
492 "ShaderVisibility",
494 if (auto E = Visibility.takeError())
495 return Error(std::move(E));
496 Sampler.ShaderVisibility = *Visibility;
497
498 RSD.StaticSamplers.push_back(Sampler);
499 return Error::success();
500}
501
502Error MetadataParser::parseRootSignatureElement(mcdxbc::RootSignatureDesc &RSD,
503 MDNode *Element) {
504 std::optional<StringRef> ElementText = extractMdStringValue(Element, 0);
505 if (!ElementText.has_value())
506 return make_error<InvalidRSMetadataFormat>("Root Element");
507
508 RootSignatureElementKind ElementKind =
509 StringSwitch<RootSignatureElementKind>(*ElementText)
510 .Case("RootFlags", RootSignatureElementKind::RootFlags)
511 .Case("RootConstants", RootSignatureElementKind::RootConstants)
512 .Case("RootCBV", RootSignatureElementKind::CBV)
513 .Case("RootSRV", RootSignatureElementKind::SRV)
514 .Case("RootUAV", RootSignatureElementKind::UAV)
515 .Case("DescriptorTable", RootSignatureElementKind::DescriptorTable)
516 .Case("StaticSampler", RootSignatureElementKind::StaticSamplers)
518
519 switch (ElementKind) {
520
522 return parseRootFlags(RSD, Element);
524 return parseRootConstants(RSD, Element);
528 return parseRootDescriptors(RSD, Element, ElementKind);
530 return parseDescriptorTable(RSD, Element);
532 return parseStaticSampler(RSD, Element);
534 return make_error<GenericRSMetadataError>("Invalid Root Signature Element",
535 Element);
536 }
537
538 llvm_unreachable("Unhandled RootSignatureElementKind enum.");
539}
540
541Error MetadataParser::validateRootSignature(
542 const mcdxbc::RootSignatureDesc &RSD) {
543 Error DeferredErrs = Error::success();
545 DeferredErrs =
546 joinErrors(std::move(DeferredErrs),
547 make_error<RootSignatureValidationError<uint32_t>>(
548 "Version", RSD.Version));
549 }
550
552 DeferredErrs =
553 joinErrors(std::move(DeferredErrs),
554 make_error<RootSignatureValidationError<uint32_t>>(
555 "RootFlags", RSD.Flags));
556 }
557
558 for (const mcdxbc::RootParameterInfo &Info : RSD.ParametersContainer) {
559
560 switch (Info.Type) {
561 case dxbc::RootParameterType::Constants32Bit:
562 break;
563
564 case dxbc::RootParameterType::CBV:
565 case dxbc::RootParameterType::UAV:
566 case dxbc::RootParameterType::SRV: {
567 const mcdxbc::RootDescriptor &Descriptor =
570 DeferredErrs =
571 joinErrors(std::move(DeferredErrs),
572 make_error<RootSignatureValidationError<uint32_t>>(
573 "ShaderRegister", Descriptor.ShaderRegister));
574
576 DeferredErrs =
577 joinErrors(std::move(DeferredErrs),
578 make_error<RootSignatureValidationError<uint32_t>>(
579 "RegisterSpace", Descriptor.RegisterSpace));
580
581 if (RSD.Version > 1) {
583 Descriptor.Flags))
584 DeferredErrs =
585 joinErrors(std::move(DeferredErrs),
586 make_error<RootSignatureValidationError<uint32_t>>(
587 "RootDescriptorFlag", Descriptor.Flags));
588 }
589 break;
590 }
591 case dxbc::RootParameterType::DescriptorTable: {
592 const mcdxbc::DescriptorTable &Table =
594 for (const mcdxbc::DescriptorRange &Range : Table) {
595 if (!hlsl::rootsig::verifyRegisterSpace(Range.RegisterSpace))
596 DeferredErrs =
597 joinErrors(std::move(DeferredErrs),
598 make_error<RootSignatureValidationError<uint32_t>>(
599 "RegisterSpace", Range.RegisterSpace));
600
601 if (!hlsl::rootsig::verifyNumDescriptors(Range.NumDescriptors))
602 DeferredErrs =
603 joinErrors(std::move(DeferredErrs),
604 make_error<RootSignatureValidationError<uint32_t>>(
605 "NumDescriptors", Range.NumDescriptors));
606
608 RSD.Version, Range.RangeType,
610 DeferredErrs =
611 joinErrors(std::move(DeferredErrs),
612 make_error<RootSignatureValidationError<uint32_t>>(
613 "DescriptorFlag", Range.Flags));
614 }
615 break;
616 }
617 }
618 }
619
620 for (const mcdxbc::StaticSampler &Sampler : RSD.StaticSamplers) {
621
623 DeferredErrs = joinErrors(std::move(DeferredErrs),
624 make_error<RootSignatureValidationError<float>>(
625 "MipLODBias", Sampler.MipLODBias));
626
628 DeferredErrs =
629 joinErrors(std::move(DeferredErrs),
630 make_error<RootSignatureValidationError<uint32_t>>(
631 "MaxAnisotropy", Sampler.MaxAnisotropy));
632
634 DeferredErrs = joinErrors(std::move(DeferredErrs),
635 make_error<RootSignatureValidationError<float>>(
636 "MinLOD", Sampler.MinLOD));
637
639 DeferredErrs = joinErrors(std::move(DeferredErrs),
640 make_error<RootSignatureValidationError<float>>(
641 "MaxLOD", Sampler.MaxLOD));
642
643 if (!hlsl::rootsig::verifyRegisterValue(Sampler.ShaderRegister))
644 DeferredErrs =
645 joinErrors(std::move(DeferredErrs),
646 make_error<RootSignatureValidationError<uint32_t>>(
647 "ShaderRegister", Sampler.ShaderRegister));
648
650 DeferredErrs =
651 joinErrors(std::move(DeferredErrs),
652 make_error<RootSignatureValidationError<uint32_t>>(
653 "RegisterSpace", Sampler.RegisterSpace));
654 }
655
656 return DeferredErrs;
657}
658
659Expected<mcdxbc::RootSignatureDesc>
661 Error DeferredErrs = Error::success();
663 RSD.Version = Version;
664 for (const auto &Operand : Root->operands()) {
665 MDNode *Element = dyn_cast<MDNode>(Operand);
666 if (Element == nullptr)
667 return joinErrors(std::move(DeferredErrs),
669 "Missing Root Element Metadata Node.", nullptr));
670
671 if (auto Err = parseRootSignatureElement(RSD, Element))
672 DeferredErrs = joinErrors(std::move(DeferredErrs), std::move(Err));
673 }
674
675 if (auto Err = validateRootSignature(RSD))
676 DeferredErrs = joinErrors(std::move(DeferredErrs), std::move(Err));
677
678 if (DeferredErrs)
679 return std::move(DeferredErrs);
680
681 return std::move(RSD);
682}
683} // namespace rootsig
684} // namespace hlsl
685} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Definition CSEInfo.cpp:27
dxil translate DXIL Translate Metadata
#define I(x, y, z)
Definition MD5.cpp:58
mir Rename Register Operands
This file contains the declarations for metadata subclasses.
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:535
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:1441
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1561
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1447
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
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
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:143
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:285
An efficient, type-erasing, non-owning reference to a callable.
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)
bool isValidSamplerFilter(uint32_t V)
bool isValidBorderColor(uint32_t V)
bool isValidComparisonFunc(uint32_t V)
bool isValidAddress(uint32_t V)
LLVM_ABI StringRef getResourceClassName(ResourceClass RC)
Definition DXILABI.cpp:21
static std::optional< uint32_t > extractMdIntValue(MDNode *Node, unsigned int OpId)
LLVM_ABI bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal)
LLVM_ABI bool verifyRegisterSpace(uint32_t RegisterSpace)
LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type, dxbc::DescriptorRangeFlags FlagsVal)
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)
Expected< T > extractEnumValue(MDNode *Node, unsigned int OpId, StringRef ErrText, llvm::function_ref< bool(uint32_t)> VerifyFn)
std::variant< dxbc::RootFlags, RootConstants, RootDescriptor, DescriptorTable, DescriptorTableClause, StaticSampler > RootElement
Models RootElement : RootFlags | RootConstants | RootParam | DescriptorTable | DescriptorTableClause ...
LLVM_ABI bool verifyMipLODBias(float MipLODBias)
LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors)
LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy)
LLVM_ABI bool verifyRegisterValue(uint32_t RegisterValue)
static std::optional< float > extractMdFloatValue(MDNode *Node, unsigned int OpId)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
Definition Metadata.h:694
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:302
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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
SmallVector< 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< StaticSampler > StaticSamplers
mcdxbc::RootParametersContainer ParametersContainer