================ @@ -0,0 +1,159 @@ +//===- DXILRootSignature.cpp - DXIL Root Signature helper objects ----===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file This file contains helper objects and APIs for working with DXIL +/// Root Signatures. +/// +//===----------------------------------------------------------------------===// +#include "DXILRootSignature.h" +#include "DirectX.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Twine.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Module.h" +#include <cstdint> + +using namespace llvm; +using namespace llvm::dxil; + +static bool reportError(Twine Message) { + report_fatal_error(Message, false); + return true; +} + +static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) { + + if (RootFlagNode->getNumOperands() != 2) + return reportError("Invalid format for RootFlag Element"); + + auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1)); + uint32_t Value = Flag->getZExtValue(); + + // Root Element validation, as specified: + // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation + if ((Value & ~0x80000fff) != 0) + return reportError("Invalid flag value for RootFlag"); + + MRS->Flags = Value; + return false; +} + +static bool parseRootSignatureElement(ModuleRootSignature *MRS, + MDNode *Element) { + MDString *ElementText = cast<MDString>(Element->getOperand(0)); + if (ElementText == nullptr) + return reportError("Invalid format for Root Element"); + + RootSignatureElementKind ElementKind = + StringSwitch<RootSignatureElementKind>(ElementText->getString()) + .Case("RootFlags", RootSignatureElementKind::RootFlags) + .Case("RootConstants", RootSignatureElementKind::RootConstants) + .Case("RootCBV", RootSignatureElementKind::RootDescriptor) + .Case("RootSRV", RootSignatureElementKind::RootDescriptor) + .Case("RootUAV", RootSignatureElementKind::RootDescriptor) + .Case("Sampler", RootSignatureElementKind::RootDescriptor) + .Case("DescriptorTable", RootSignatureElementKind::DescriptorTable) + .Case("StaticSampler", RootSignatureElementKind::StaticSampler) + .Default(RootSignatureElementKind::None); + + switch (ElementKind) { + + case RootSignatureElementKind::RootFlags: { + return parseRootFlags(MRS, Element); + break; + } + + case RootSignatureElementKind::RootConstants: + case RootSignatureElementKind::RootDescriptor: + case RootSignatureElementKind::DescriptorTable: + case RootSignatureElementKind::StaticSampler: + case RootSignatureElementKind::None: + return reportError("Invalid Root Element: " + ElementText->getString()); + break; + } + + return true; +} + +bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) { + this->Version = Version; + bool HasError = false; + + /** Root Signature are specified as following in the metadata: + + !dx.rootsignatures = !{!2} ; list of function/root signature pairs + !2 = !{ ptr @main, !3 } ; function, root signature + !3 = !{ !4, !5, !6, !7 } ; list of root signature elements + + So for each MDNode inside dx.rootsignatures NamedMDNode + (the Root parameter of this function), the parsing process needs + to loop through each of it's operand and process the pairs function + signature pair. + */ + + for (unsigned int Sid = 0; Sid < Root->getNumOperands(); Sid++) { + MDNode *Node = dyn_cast<MDNode>(Root->getOperand(Sid)); + + if (Node == nullptr || Node->getNumOperands() != 2) ---------------- damyanp wrote:
``` if (Node == nullptr || Node->getNumOperands() != 2) ``` Can `Node` really ever be nullptr? I'm not sure it can. https://github.com/llvm/llvm-project/pull/123147 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits