Skip to content

Commit 2b72841

Browse files
author
joaosaffran
committed
adding metadata extraction
1 parent be3764d commit 2b72841

File tree

11 files changed

+238
-14
lines changed

11 files changed

+238
-14
lines changed

llvm/include/llvm/Analysis/DXILMetadataAnalysis.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
#include "llvm/ADT/SmallVector.h"
1313
#include "llvm/IR/PassManager.h"
14+
#include "llvm/MC/DXContainerRootSignature.h"
1415
#include "llvm/Pass.h"
1516
#include "llvm/Support/VersionTuple.h"
1617
#include "llvm/TargetParser/Triple.h"
18+
#include <optional>
1719

1820
namespace llvm {
1921

@@ -37,6 +39,7 @@ struct ModuleMetadataInfo {
3739
Triple::EnvironmentType ShaderProfile{Triple::UnknownEnvironment};
3840
VersionTuple ValidatorVersion{};
3941
SmallVector<EntryProperties> EntryPropertyVec{};
42+
std::optional<mcdxbc::RootSignatureDesc> RootSignatureDesc;
4043
void print(raw_ostream &OS) const;
4144
};
4245

llvm/include/llvm/BinaryFormat/DXContainer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ struct ShaderHash {
6666
struct RootSignatureDesc {
6767
uint32_t Version;
6868
uint32_t Flags;
69-
void swapBytes() {
69+
void swapBytes() {
7070
sys::swapByteOrder(Version);
71-
sys::swapByteOrder(Flags);
71+
sys::swapByteOrder(Flags);
7272
}
7373
};
7474

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===- DXILRootSignature.h - DXIL 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 helper objects for working with DXIL Root
10+
/// Signatures.
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_DIRECTX_HLSLROOTSIGNATURE_H
15+
#define LLVM_DIRECTX_HLSLROOTSIGNATURE_H
16+
17+
#include "llvm/IR/Metadata.h"
18+
#include <memory>
19+
20+
namespace llvm {
21+
namespace mcdxbc {
22+
23+
enum class RootSignatureElementKind {
24+
None = 0,
25+
RootFlags = 1,
26+
RootConstants = 2,
27+
RootDescriptor = 3,
28+
DescriptorTable = 4,
29+
StaticSampler = 5
30+
};
31+
32+
enum RootSignatureFlags : uint32_t {
33+
None = 0,
34+
AllowInputAssemblerInputLayout = 0x1,
35+
DenyVertexShaderRootAccess = 0x2,
36+
DenyHullShaderRootAccess = 0x4,
37+
DenyDomainShaderRootAccess = 0x8,
38+
DenyGeometryShaderRootAccess = 0x10,
39+
DenyPixelShaderRootAccess = 0x20,
40+
AllowStreamOutput = 0x40,
41+
LocalRootSignature = 0x80,
42+
DenyAmplificationShaderRootAccess = 0x100,
43+
DenyMeshShaderRootAccess = 0x200,
44+
CBVSRVUAVHeapDirectlyIndexed = 0x400,
45+
SamplerHeapDirectlyIndexed = 0x800,
46+
AllowLowTierReservedHwCbLimit = 0x80000000,
47+
ValidFlags = 0x80000fff
48+
};
49+
50+
struct RootSignatureDesc {
51+
uint32_t Version;
52+
RootSignatureFlags Flags;
53+
54+
void swapBytes() {
55+
sys::swapByteOrder(Version);
56+
sys::swapByteOrder(Flags);
57+
}
58+
};
59+
60+
class RootSignatureDescWriter {
61+
private:
62+
RootSignatureDesc *Desc;
63+
64+
public:
65+
RootSignatureDescWriter(RootSignatureDesc *Desc) : Desc(Desc) {}
66+
67+
void write(raw_ostream &OS,
68+
uint32_t Version = std::numeric_limits<uint32_t>::max());
69+
};
70+
71+
} // namespace mcdxbc
72+
} // namespace llvm
73+
74+
#endif // LLVM_DIRECTX_HLSLROOTSIGNATURE_H

llvm/include/llvm/Object/DXContainer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,7 @@ class DXContainer {
384384

385385
std::optional<dxbc::ShaderHash> getShaderHash() const { return Hash; }
386386

387-
std::optional<dxbc::RootSignatureDesc>
388-
getRootSignature() const {
387+
std::optional<dxbc::RootSignatureDesc> getRootSignature() const {
389388
return RootSignature;
390389
}
391390

llvm/include/llvm/ObjectYAML/DXContainerYAML.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ struct ShaderHash {
7272
std::vector<llvm::yaml::Hex8> Digest;
7373
};
7474

75-
7675
#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
7776
struct RootSignatureDesc {
7877
RootSignatureDesc() = default;

llvm/lib/Analysis/DXILMetadataAnalysis.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,99 @@
1515
#include "llvm/IR/Metadata.h"
1616
#include "llvm/IR/Module.h"
1717
#include "llvm/InitializePasses.h"
18+
#include "llvm/MC/DXContainerRootSignature.h"
19+
#include "llvm/Support/Casting.h"
1820
#include "llvm/Support/ErrorHandling.h"
21+
#include <memory>
1922

2023
#define DEBUG_TYPE "dxil-metadata-analysis"
2124

2225
using namespace llvm;
2326
using namespace dxil;
27+
using namespace llvm::mcdxbc;
28+
29+
static bool parseRootFlags(MDNode *RootFlagNode, RootSignatureDesc *Desc) {
30+
31+
assert(RootFlagNode->getNumOperands() == 2 &&
32+
"Invalid format for RootFlag Element");
33+
auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1));
34+
auto Value = (RootSignatureFlags)Flag->getZExtValue();
35+
36+
if ((Value & ~RootSignatureFlags::ValidFlags) != RootSignatureFlags::None)
37+
return true;
38+
39+
Desc->Flags = Value;
40+
return false;
41+
}
42+
43+
static bool parseRootSignatureElement(MDNode *Element,
44+
RootSignatureDesc *Desc) {
45+
MDString *ElementText = cast<MDString>(Element->getOperand(0));
46+
47+
assert(ElementText != nullptr && "First preoperty of element is not ");
48+
49+
RootSignatureElementKind ElementKind =
50+
StringSwitch<RootSignatureElementKind>(ElementText->getString())
51+
.Case("RootFlags", RootSignatureElementKind::RootFlags)
52+
.Case("RootConstants", RootSignatureElementKind::RootConstants)
53+
.Case("RootCBV", RootSignatureElementKind::RootDescriptor)
54+
.Case("RootSRV", RootSignatureElementKind::RootDescriptor)
55+
.Case("RootUAV", RootSignatureElementKind::RootDescriptor)
56+
.Case("Sampler", RootSignatureElementKind::RootDescriptor)
57+
.Case("DescriptorTable", RootSignatureElementKind::DescriptorTable)
58+
.Case("StaticSampler", RootSignatureElementKind::StaticSampler)
59+
.Default(RootSignatureElementKind::None);
60+
61+
switch (ElementKind) {
62+
63+
case RootSignatureElementKind::RootFlags: {
64+
return parseRootFlags(Element, Desc);
65+
break;
66+
}
67+
68+
case RootSignatureElementKind::RootConstants:
69+
case RootSignatureElementKind::RootDescriptor:
70+
case RootSignatureElementKind::DescriptorTable:
71+
case RootSignatureElementKind::StaticSampler:
72+
case RootSignatureElementKind::None:
73+
llvm_unreachable("Not Implemented yet");
74+
break;
75+
}
76+
77+
return true;
78+
}
79+
80+
bool parseRootSignature(RootSignatureDesc *Desc, int32_t Version,
81+
NamedMDNode *Root) {
82+
Desc->Version = Version;
83+
bool HasError = false;
84+
85+
for (unsigned int Sid = 0; Sid < Root->getNumOperands(); Sid++) {
86+
// This should be an if, for error handling
87+
MDNode *Node = cast<MDNode>(Root->getOperand(Sid));
88+
89+
// Not sure what use this for...
90+
Metadata *Func = Node->getOperand(0).get();
91+
92+
// This should be an if, for error handling
93+
MDNode *Elements = cast<MDNode>(Node->getOperand(1).get());
94+
95+
for (unsigned int Eid = 0; Eid < Elements->getNumOperands(); Eid++) {
96+
MDNode *Element = cast<MDNode>(Elements->getOperand(Eid));
97+
98+
HasError = HasError || parseRootSignatureElement(Element, Desc);
99+
}
100+
}
101+
return HasError;
102+
}
24103

25104
static ModuleMetadataInfo collectMetadataInfo(Module &M) {
26105
ModuleMetadataInfo MMDAI;
27106
Triple TT(Triple(M.getTargetTriple()));
28107
MMDAI.DXILVersion = TT.getDXILVersion();
29108
MMDAI.ShaderModelVersion = TT.getOSVersion();
30109
MMDAI.ShaderProfile = TT.getEnvironment();
110+
31111
NamedMDNode *ValidatorVerNode = M.getNamedMetadata("dx.valver");
32112
if (ValidatorVerNode) {
33113
auto *ValVerMD = cast<MDNode>(ValidatorVerNode->getOperand(0));
@@ -37,6 +117,15 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) {
37117
VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue());
38118
}
39119

120+
NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures");
121+
if (RootSignatureNode) {
122+
mcdxbc::RootSignatureDesc Desc;
123+
124+
parseRootSignature(&Desc, 1, RootSignatureNode);
125+
126+
MMDAI.RootSignatureDesc = Desc;
127+
}
128+
40129
// For all HLSL Shader functions
41130
for (auto &F : M.functions()) {
42131
if (!F.hasFnAttribute("hlsl.shader"))

llvm/lib/MC/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_llvm_component_library(LLVMMC
22
ConstantPools.cpp
33
DXContainerPSVInfo.cpp
4+
DXContainerRootSignature.cpp
45
ELFObjectWriter.cpp
56
GOFFObjectWriter.cpp
67
MCAsmBackend.cpp
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===- DXContainerRootSignature.cpp - DXIL Root Signature helper objects
2+
//-----------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
///
10+
/// \file This file contains the parsing logic to extract root signature data
11+
/// from LLVM IR metadata.
12+
///
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "llvm/MC/DXContainerRootSignature.h"
16+
#include "llvm/ADT/StringSwitch.h"
17+
#include "llvm/BinaryFormat/DXContainer.h"
18+
#include "llvm/IR/Constants.h"
19+
#include "llvm/IR/Metadata.h"
20+
#include "llvm/Support/ErrorHandling.h"
21+
#include "llvm/Support/SwapByteOrder.h"
22+
#include <cassert>
23+
#include <cstdint>
24+
25+
using namespace llvm;
26+
using namespace llvm::mcdxbc;
27+
28+
void RootSignatureDescWriter::write(raw_ostream &OS, uint32_t Version) {
29+
dxbc::RootSignatureDesc Out{Desc->Version, Desc->Flags};
30+
31+
if (sys::IsBigEndianHost) {
32+
Out.swapBytes();
33+
}
34+
35+
OS.write(reinterpret_cast<const char *>(&Out), sizeof(RootSignatureDesc));
36+
}

llvm/lib/ObjectYAML/DXContainerEmitter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
267267
uint32_t Flags = P.RootSignature->getEncodedFlags();
268268
if (sys::IsBigEndianHost)
269269
sys::swapByteOrder(Flags);
270-
dxbc::RootSignatureDesc RS = {P.RootSignature->Version, Flags};
270+
dxbc::RootSignatureDesc RS = {P.RootSignature->Version, Flags};
271271
if (sys::IsBigEndianHost)
272272
RS.swapBytes();
273273
OS.write(reinterpret_cast<char *>(&RS), sizeof(dxbc::RootSignatureDesc));

llvm/lib/ObjectYAML/DXContainerYAML.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) {
3030
#include "llvm/BinaryFormat/DXContainerConstants.def"
3131
}
3232

33-
34-
DXContainerYAML::RootSignatureDesc::RootSignatureDesc(const dxbc::RootSignatureDesc &Data): Version(Data.Version) {
35-
#define ROOT_ELEMENT_FLAG(Num, Val) \
33+
DXContainerYAML::RootSignatureDesc::RootSignatureDesc(
34+
const dxbc::RootSignatureDesc &Data)
35+
: Version(Data.Version) {
36+
#define ROOT_ELEMENT_FLAG(Num, Val) \
3637
Val = (Data.Flags & (uint32_t)dxbc::RootElementFlag::Val) > 0;
3738
#include "llvm/BinaryFormat/DXContainerConstants.def"
3839
}
3940

40-
4141
uint32_t DXContainerYAML::RootSignatureDesc::getEncodedFlags() {
4242
uint64_t Flag = 0;
43-
#define ROOT_ELEMENT_FLAG(Num, Val) \
43+
#define ROOT_ELEMENT_FLAG(Num, Val) \
4444
if (Val) \
4545
Flag |= (uint32_t)dxbc::RootElementFlag::Val;
4646
#include "llvm/BinaryFormat/DXContainerConstants.def"
@@ -209,9 +209,8 @@ void MappingTraits<DXContainerYAML::Signature>::mapping(
209209
void MappingTraits<DXContainerYAML::RootSignatureDesc>::mapping(
210210
IO &IO, DXContainerYAML::RootSignatureDesc &S) {
211211
IO.mapRequired("Version", S.Version);
212-
#define ROOT_ELEMENT_FLAG(Num, Val) \
213-
IO.mapRequired(#Val, S.Val);
214-
#include "llvm/BinaryFormat/DXContainerConstants.def"
212+
#define ROOT_ELEMENT_FLAG(Num, Val) IO.mapRequired(#Val, S.Val);
213+
#include "llvm/BinaryFormat/DXContainerConstants.def"
215214
}
216215

217216
void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,

0 commit comments

Comments
 (0)