Skip to content

Commit 6714066

Browse files
joaosaffranjoaosaffran
authored andcommitted
[DXIL] Adding support to RootSignatureFlags in obj2yaml (llvm#122396)
This PR adds: - `RootSignatureFlags` extraction from DXContainer using `obj2yaml` This PR is part of: llvm#121493 --------- Co-authored-by: joaosaffran <[email protected]>
1 parent 647682f commit 6714066

File tree

14 files changed

+404
-0
lines changed

14 files changed

+404
-0
lines changed

llvm/include/llvm/BinaryFormat/DXContainer.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#define LLVM_BINARYFORMAT_DXCONTAINER_H
1515

1616
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/Support/BinaryStreamError.h"
18+
#include "llvm/Support/Error.h"
1719
#include "llvm/Support/SwapByteOrder.h"
1820
#include "llvm/TargetParser/Triple.h"
1921

@@ -152,6 +154,11 @@ enum class FeatureFlags : uint64_t {
152154
static_assert((uint64_t)FeatureFlags::NextUnusedBit <= 1ull << 63,
153155
"Shader flag bits exceed enum size.");
154156

157+
#define ROOT_ELEMENT_FLAG(Num, Val) Val = 1ull << Num,
158+
enum class RootElementFlag : uint32_t {
159+
#include "DXContainerConstants.def"
160+
};
161+
155162
PartType parsePartType(StringRef S);
156163

157164
struct VertexPSVInfo {
@@ -541,6 +548,23 @@ struct ProgramSignatureElement {
541548
static_assert(sizeof(ProgramSignatureElement) == 32,
542549
"ProgramSignatureElement is misaligned");
543550

551+
struct RootSignatureValidations {
552+
553+
static Expected<uint32_t> validateRootFlag(uint32_t Flags) {
554+
if ((Flags & ~0x80000fff) != 0)
555+
return llvm::make_error<BinaryStreamError>("Invalid Root Signature flag");
556+
return Flags;
557+
}
558+
559+
static Expected<uint32_t> validateVersion(uint32_t Version) {
560+
if (Version == 1 || Version == 2)
561+
return Version;
562+
563+
return llvm::make_error<BinaryStreamError>(
564+
"Invalid Root Signature Version");
565+
}
566+
};
567+
544568
} // namespace dxbc
545569
} // namespace llvm
546570

llvm/include/llvm/BinaryFormat/DXContainerConstants.def

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CONTAINER_PART(DXIL)
44
CONTAINER_PART(SFI0)
55
CONTAINER_PART(HASH)
66
CONTAINER_PART(PSV0)
7+
CONTAINER_PART(RTS0)
78
CONTAINER_PART(ISG1)
89
CONTAINER_PART(OSG1)
910
CONTAINER_PART(PSG1)
@@ -52,6 +53,26 @@ SHADER_FEATURE_FLAG(31, 36, NextUnusedBit, "Next reserved shader flag bit (not a
5253
#undef SHADER_FEATURE_FLAG
5354
#endif // SHADER_FEATURE_FLAG
5455

56+
57+
// ROOT_ELEMENT_FLAG(bit offset for the flag, name).
58+
#ifdef ROOT_ELEMENT_FLAG
59+
60+
ROOT_ELEMENT_FLAG(0, AllowInputAssemblerInputLayout)
61+
ROOT_ELEMENT_FLAG(1, DenyVertexShaderRootAccess)
62+
ROOT_ELEMENT_FLAG(2, DenyHullShaderRootAccess)
63+
ROOT_ELEMENT_FLAG(3, DenyDomainShaderRootAccess)
64+
ROOT_ELEMENT_FLAG(4, DenyGeometryShaderRootAccess)
65+
ROOT_ELEMENT_FLAG(5, DenyPixelShaderRootAccess)
66+
ROOT_ELEMENT_FLAG(6, AllowStreamOutput)
67+
ROOT_ELEMENT_FLAG(7, LocalRootSignature)
68+
ROOT_ELEMENT_FLAG(8, DenyAmplificationShaderRootAccess)
69+
ROOT_ELEMENT_FLAG(9, DenyMeshShaderRootAccess)
70+
ROOT_ELEMENT_FLAG(10, CBVSRVUAVHeapDirectlyIndexed)
71+
ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed)
72+
#undef ROOT_ELEMENT_FLAG
73+
#endif // ROOT_ELEMENT_FLAG
74+
75+
5576
#ifdef DXIL_MODULE_FLAG
5677

5778
// Only save DXIL module flags which not map to feature flags here.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===- llvm/MC/DXContainerRootSignature.h - RootSignature -*- C++ -*- ========//
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+
#include <cstdint>
10+
#include <limits>
11+
12+
namespace llvm {
13+
14+
class raw_ostream;
15+
16+
namespace mcdxbc {
17+
struct RootSignatureHeader {
18+
uint32_t Version = 2;
19+
uint32_t NumParameters = 0;
20+
uint32_t RootParametersOffset = 0;
21+
uint32_t NumStaticSamplers = 0;
22+
uint32_t StaticSamplersOffset = 0;
23+
uint32_t Flags = 0;
24+
25+
void write(raw_ostream &OS);
26+
};
27+
} // namespace mcdxbc
28+
} // namespace llvm

llvm/include/llvm/Object/DXContainer.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,28 @@ template <typename T> struct ViewArray {
116116
};
117117

118118
namespace DirectX {
119+
120+
class RootSignature {
121+
private:
122+
uint32_t Version;
123+
uint32_t NumParameters;
124+
uint32_t RootParametersOffset;
125+
uint32_t NumStaticSamplers;
126+
uint32_t StaticSamplersOffset;
127+
uint32_t Flags;
128+
129+
public:
130+
RootSignature() {}
131+
132+
Error parse(StringRef Data);
133+
uint32_t getVersion() const { return Version; }
134+
uint32_t getNumParameters() const { return NumParameters; }
135+
uint32_t getRootParametersOffset() const { return RootParametersOffset; }
136+
uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
137+
uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
138+
uint32_t getFlags() const { return Flags; }
139+
};
140+
119141
class PSVRuntimeInfo {
120142

121143
using ResourceArray = ViewArray<dxbc::PSV::v2::ResourceBindInfo>;
@@ -287,6 +309,7 @@ class DXContainer {
287309
std::optional<uint64_t> ShaderFeatureFlags;
288310
std::optional<dxbc::ShaderHash> Hash;
289311
std::optional<DirectX::PSVRuntimeInfo> PSVInfo;
312+
std::optional<DirectX::RootSignature> RootSignature;
290313
DirectX::Signature InputSignature;
291314
DirectX::Signature OutputSignature;
292315
DirectX::Signature PatchConstantSignature;
@@ -296,6 +319,7 @@ class DXContainer {
296319
Error parseDXILHeader(StringRef Part);
297320
Error parseShaderFeatureFlags(StringRef Part);
298321
Error parseHash(StringRef Part);
322+
Error parseRootSignature(StringRef Part);
299323
Error parsePSVInfo(StringRef Part);
300324
Error parseSignature(StringRef Part, DirectX::Signature &Array);
301325
friend class PartIterator;
@@ -382,6 +406,10 @@ class DXContainer {
382406

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

409+
std::optional<DirectX::RootSignature> getRootSignature() const {
410+
return RootSignature;
411+
}
412+
385413
const std::optional<DirectX::PSVRuntimeInfo> &getPSVInfo() const {
386414
return PSVInfo;
387415
};

llvm/include/llvm/ObjectYAML/DXContainerYAML.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "llvm/ADT/StringRef.h"
1919
#include "llvm/BinaryFormat/DXContainer.h"
20+
#include "llvm/Object/DXContainer.h"
2021
#include "llvm/ObjectYAML/YAML.h"
2122
#include "llvm/Support/YAMLTraits.h"
2223
#include <array>
@@ -72,6 +73,22 @@ struct ShaderHash {
7273
std::vector<llvm::yaml::Hex8> Digest;
7374
};
7475

76+
#define ROOT_ELEMENT_FLAG(Num, Val) bool Val = false;
77+
struct RootSignatureDesc {
78+
RootSignatureDesc() = default;
79+
RootSignatureDesc(const object::DirectX::RootSignature &Data);
80+
81+
uint32_t Version;
82+
uint32_t NumParameters;
83+
uint32_t RootParametersOffset;
84+
uint32_t NumStaticSamplers;
85+
uint32_t StaticSamplersOffset;
86+
87+
uint32_t getEncodedFlags();
88+
89+
#include "llvm/BinaryFormat/DXContainerConstants.def"
90+
};
91+
7592
using ResourceFlags = dxbc::PSV::ResourceFlags;
7693
using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo;
7794

@@ -159,6 +176,7 @@ struct Part {
159176
std::optional<ShaderHash> Hash;
160177
std::optional<PSVInfo> Info;
161178
std::optional<DXContainerYAML::Signature> Signature;
179+
std::optional<DXContainerYAML::RootSignatureDesc> RootSignature;
162180
};
163181

164182
struct Object {
@@ -241,6 +259,11 @@ template <> struct MappingTraits<DXContainerYAML::Signature> {
241259
static void mapping(IO &IO, llvm::DXContainerYAML::Signature &El);
242260
};
243261

262+
template <> struct MappingTraits<DXContainerYAML::RootSignatureDesc> {
263+
static void mapping(IO &IO,
264+
DXContainerYAML::RootSignatureDesc &RootSignature);
265+
};
266+
244267
} // namespace yaml
245268

246269
} // namespace llvm

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: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===- llvm/MC/DXContainerRootSignature.cpp - RootSignature -*- C++ -*-=======//
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+
#include "llvm/MC/DXContainerRootSignature.h"
10+
#include "llvm/Support/EndianStream.h"
11+
12+
using namespace llvm;
13+
using namespace llvm::mcdxbc;
14+
15+
void RootSignatureHeader::write(raw_ostream &OS) {
16+
17+
support::endian::write(OS, Version, llvm::endianness::little);
18+
support::endian::write(OS, NumParameters, llvm::endianness::little);
19+
support::endian::write(OS, RootParametersOffset, llvm::endianness::little);
20+
support::endian::write(OS, NumStaticSamplers, llvm::endianness::little);
21+
support::endian::write(OS, StaticSamplersOffset, llvm::endianness::little);
22+
support::endian::write(OS, Flags, llvm::endianness::little);
23+
}

llvm/lib/Object/DXContainer.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "llvm/BinaryFormat/DXContainer.h"
1111
#include "llvm/Object/Error.h"
1212
#include "llvm/Support/Alignment.h"
13+
#include "llvm/Support/Endian.h"
1314
#include "llvm/Support/FormatVariadic.h"
1415

1516
using namespace llvm;
@@ -92,6 +93,15 @@ Error DXContainer::parseHash(StringRef Part) {
9293
return Error::success();
9394
}
9495

96+
Error DXContainer::parseRootSignature(StringRef Part) {
97+
if (RootSignature)
98+
return parseFailed("More than one RTS0 part is present in the file");
99+
RootSignature = DirectX::RootSignature();
100+
if (Error Err = RootSignature->parse(Part))
101+
return Err;
102+
return Error::success();
103+
}
104+
95105
Error DXContainer::parsePSVInfo(StringRef Part) {
96106
if (PSVInfo)
97107
return parseFailed("More than one PSV0 part is present in the file");
@@ -193,6 +203,10 @@ Error DXContainer::parsePartOffsets() {
193203
break;
194204
case dxbc::PartType::Unknown:
195205
break;
206+
case dxbc::PartType::RTS0:
207+
if (Error Err = parseRootSignature(PartData))
208+
return Err;
209+
break;
196210
}
197211
}
198212

@@ -228,6 +242,53 @@ void DXContainer::PartIterator::updateIteratorImpl(const uint32_t Offset) {
228242
IteratorState.Offset = Offset;
229243
}
230244

245+
Error DirectX::RootSignature::parse(StringRef Data) {
246+
const char *Current = Data.begin();
247+
248+
// Root Signature headers expects 6 integers to be present.
249+
if (Data.size() < 6 * sizeof(uint32_t))
250+
return parseFailed(
251+
"Invalid root signature, insufficient space for header.");
252+
253+
uint32_t VValue =
254+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
255+
Current += sizeof(uint32_t);
256+
257+
Expected<uint32_t> MaybeVersion =
258+
dxbc::RootSignatureValidations::validateVersion(VValue);
259+
if (Error E = MaybeVersion.takeError())
260+
return E;
261+
Version = MaybeVersion.get();
262+
263+
NumParameters =
264+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
265+
Current += sizeof(uint32_t);
266+
267+
RootParametersOffset =
268+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
269+
Current += sizeof(uint32_t);
270+
271+
NumStaticSamplers =
272+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
273+
Current += sizeof(uint32_t);
274+
275+
StaticSamplersOffset =
276+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
277+
Current += sizeof(uint32_t);
278+
279+
uint32_t FValue =
280+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
281+
Current += sizeof(uint32_t);
282+
283+
Expected<uint32_t> MaybeFlag =
284+
dxbc::RootSignatureValidations::validateRootFlag(FValue);
285+
if (Error E = MaybeFlag.takeError())
286+
return E;
287+
Flags = MaybeFlag.get();
288+
289+
return Error::success();
290+
}
291+
231292
Error DirectX::PSVRuntimeInfo::parse(uint16_t ShaderKind) {
232293
Triple::EnvironmentType ShaderStage = dxbc::getShaderStage(ShaderKind);
233294

llvm/lib/ObjectYAML/DXContainerEmitter.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "llvm/BinaryFormat/DXContainer.h"
1515
#include "llvm/MC/DXContainerPSVInfo.h"
16+
#include "llvm/MC/DXContainerRootSignature.h"
1617
#include "llvm/ObjectYAML/ObjectYAML.h"
1718
#include "llvm/ObjectYAML/yaml2obj.h"
1819
#include "llvm/Support/Errc.h"
@@ -261,6 +262,20 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
261262
}
262263
case dxbc::PartType::Unknown:
263264
break; // Skip any handling for unrecognized parts.
265+
case dxbc::PartType::RTS0:
266+
if (!P.RootSignature.has_value())
267+
continue;
268+
269+
mcdxbc::RootSignatureHeader Header;
270+
Header.Flags = P.RootSignature->getEncodedFlags();
271+
Header.Version = P.RootSignature->Version;
272+
Header.NumParameters = P.RootSignature->NumParameters;
273+
Header.RootParametersOffset = P.RootSignature->RootParametersOffset;
274+
Header.NumStaticSamplers = P.RootSignature->NumStaticSamplers;
275+
Header.StaticSamplersOffset = P.RootSignature->StaticSamplersOffset;
276+
277+
Header.write(OS);
278+
break;
264279
}
265280
uint64_t BytesWritten = OS.tell() - DataStart;
266281
RollingOffset += BytesWritten;

0 commit comments

Comments
 (0)