-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[DirectX] Refactor RootSignature Backend to remove to_underlying
from Root Parameter Header
#154249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
31ec5e5
1690a9c
f6f2e61
6539364
1d29111
8eb82fd
d38c00d
3b25b34
567a3d4
fb248da
dc436d5
8353fe0
3a30581
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -19,14 +19,22 @@ namespace llvm { | |||||
class raw_ostream; | ||||||
namespace mcdxbc { | ||||||
|
||||||
struct RootParameterHeader { | ||||||
dxbc::RootParameterType ParameterType; | ||||||
dxbc::ShaderVisibility ShaderVisibility; | ||||||
uint32_t ParameterOffset; | ||||||
}; | ||||||
|
||||||
|
||||||
struct RootParameterInfo { | ||||||
dxbc::RTS0::v1::RootParameterHeader Header; | ||||||
dxbc::RootParameterType Type; | ||||||
dxbc::ShaderVisibility Visibility; | ||||||
size_t Location; | ||||||
|
||||||
RootParameterInfo() = default; | ||||||
|
||||||
|
||||||
RootParameterInfo(dxbc::RTS0::v1::RootParameterHeader Header, size_t Location) | ||||||
: Header(Header), Location(Location) {} | ||||||
RootParameterInfo(dxbc::RootParameterType Type, | ||||||
dxbc::ShaderVisibility Visibility, size_t Location) | ||||||
: Type(Type), Visibility(Visibility), Location(Location) {} | ||||||
}; | ||||||
|
||||||
struct DescriptorTable { | ||||||
|
@@ -46,41 +54,34 @@ struct RootParametersContainer { | |||||
SmallVector<dxbc::RTS0::v2::RootDescriptor> Descriptors; | ||||||
SmallVector<DescriptorTable> Tables; | ||||||
|
||||||
void addInfo(dxbc::RTS0::v1::RootParameterHeader Header, size_t Location) { | ||||||
ParametersInfo.push_back(RootParameterInfo(Header, Location)); | ||||||
void addInfo(dxbc::RootParameterType Type, dxbc::ShaderVisibility Visibility, | ||||||
size_t Location) { | ||||||
ParametersInfo.push_back(RootParameterInfo(Type, Visibility, Location)); | ||||||
|
ParametersInfo.push_back(RootParameterInfo(Type, Visibility, Location)); | |
ParametersInfo.emplace_back(Type, Visibility, Location); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,17 @@ static std::optional<StringRef> extractMdStringValue(MDNode *Node, | |
return NodeText->getString(); | ||
} | ||
|
||
static Expected<dxbc::ShaderVisibility> | ||
extractShaderVisibility(MDNode *Node, unsigned int OpId) { | ||
if (std::optional<uint32_t> Val = extractMdIntValue(Node, OpId)) { | ||
if (!dxbc::isValidShaderVisibility(*Val)) | ||
return make_error<RootSignatureValidationError<uint32_t>>( | ||
"ShaderVisibility", *Val); | ||
return dxbc::ShaderVisibility(*Val); | ||
} | ||
return make_error<InvalidRSMetadataValue>("ShaderVisibility"); | ||
} | ||
|
||
namespace { | ||
|
||
// We use the OverloadVisit with std::visit to ensure the compiler catches if a | ||
|
@@ -224,15 +235,12 @@ Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD, | |
if (RootConstantNode->getNumOperands() != 5) | ||
return make_error<InvalidRSMetadataFormat>("RootConstants Element"); | ||
|
||
dxbc::RTS0::v1::RootParameterHeader Header; | ||
// The parameter offset doesn't matter here - we recalculate it during | ||
// serialization Header.ParameterOffset = 0; | ||
Header.ParameterType = to_underlying(dxbc::RootParameterType::Constants32Bit); | ||
mcdxbc::RootParameterHeader Header; | ||
|
||
|
||
if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 1)) | ||
Header.ShaderVisibility = *Val; | ||
else | ||
return make_error<InvalidRSMetadataValue>("ShaderVisibility"); | ||
Expected<dxbc::ShaderVisibility> VisibilityOrErr = | ||
extractShaderVisibility(RootConstantNode, 1); | ||
|
||
if (auto E = VisibilityOrErr.takeError()) | ||
return Error(std::move(E)); | ||
|
||
dxbc::RTS0::v1::RootConstants Constants; | ||
if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 2)) | ||
|
@@ -250,7 +258,8 @@ Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD, | |
else | ||
return make_error<InvalidRSMetadataValue>("Num32BitValues"); | ||
|
||
RSD.ParametersContainer.addParameter(Header, Constants); | ||
RSD.ParametersContainer.addParameter(dxbc::RootParameterType::Constants32Bit, | ||
*VisibilityOrErr, Constants); | ||
|
||
return Error::success(); | ||
} | ||
|
@@ -266,26 +275,26 @@ Error MetadataParser::parseRootDescriptors( | |
if (RootDescriptorNode->getNumOperands() != 5) | ||
return make_error<InvalidRSMetadataFormat>("Root Descriptor Element"); | ||
|
||
dxbc::RTS0::v1::RootParameterHeader Header; | ||
dxbc::RootParameterType Type; | ||
switch (ElementKind) { | ||
case RootSignatureElementKind::SRV: | ||
Header.ParameterType = to_underlying(dxbc::RootParameterType::SRV); | ||
Type = dxbc::RootParameterType::SRV; | ||
break; | ||
case RootSignatureElementKind::UAV: | ||
Header.ParameterType = to_underlying(dxbc::RootParameterType::UAV); | ||
Type = dxbc::RootParameterType::UAV; | ||
break; | ||
case RootSignatureElementKind::CBV: | ||
Header.ParameterType = to_underlying(dxbc::RootParameterType::CBV); | ||
Type = dxbc::RootParameterType::CBV; | ||
break; | ||
default: | ||
llvm_unreachable("invalid Root Descriptor kind"); | ||
break; | ||
} | ||
|
||
if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 1)) | ||
Header.ShaderVisibility = *Val; | ||
else | ||
return make_error<InvalidRSMetadataValue>("ShaderVisibility"); | ||
Expected<dxbc::ShaderVisibility> VisibilityOrErr = | ||
extractShaderVisibility(RootDescriptorNode, 1); | ||
if (auto E = VisibilityOrErr.takeError()) | ||
return Error(std::move(E)); | ||
|
||
dxbc::RTS0::v2::RootDescriptor Descriptor; | ||
if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 2)) | ||
|
@@ -299,7 +308,7 @@ Error MetadataParser::parseRootDescriptors( | |
return make_error<InvalidRSMetadataValue>("RegisterSpace"); | ||
|
||
if (RSD.Version == 1) { | ||
RSD.ParametersContainer.addParameter(Header, Descriptor); | ||
RSD.ParametersContainer.addParameter(Type, *VisibilityOrErr, Descriptor); | ||
return Error::success(); | ||
} | ||
assert(RSD.Version > 1); | ||
|
@@ -309,7 +318,7 @@ Error MetadataParser::parseRootDescriptors( | |
else | ||
return make_error<InvalidRSMetadataValue>("Root Descriptor Flags"); | ||
|
||
RSD.ParametersContainer.addParameter(Header, Descriptor); | ||
RSD.ParametersContainer.addParameter(Type, *VisibilityOrErr, Descriptor); | ||
return Error::success(); | ||
} | ||
|
||
|
@@ -375,15 +384,14 @@ Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD, | |
if (NumOperands < 2) | ||
return make_error<InvalidRSMetadataFormat>("Descriptor Table"); | ||
|
||
dxbc::RTS0::v1::RootParameterHeader Header; | ||
if (std::optional<uint32_t> Val = extractMdIntValue(DescriptorTableNode, 1)) | ||
Header.ShaderVisibility = *Val; | ||
else | ||
return make_error<InvalidRSMetadataValue>("ShaderVisibility"); | ||
mcdxbc::RootParameterHeader Header; | ||
|
||
Expected<dxbc::ShaderVisibility> VisibilityOrErr = | ||
extractShaderVisibility(DescriptorTableNode, 1); | ||
if (auto E = VisibilityOrErr.takeError()) | ||
return Error(std::move(E)); | ||
|
||
mcdxbc::DescriptorTable Table; | ||
Header.ParameterType = | ||
to_underlying(dxbc::RootParameterType::DescriptorTable); | ||
|
||
for (unsigned int I = 2; I < NumOperands; I++) { | ||
MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I)); | ||
|
@@ -395,7 +403,8 @@ Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD, | |
return Err; | ||
} | ||
|
||
RSD.ParametersContainer.addParameter(Header, Table); | ||
RSD.ParametersContainer.addParameter(dxbc::RootParameterType::DescriptorTable, | ||
*VisibilityOrErr, Table); | ||
return Error::success(); | ||
} | ||
|
||
|
@@ -531,20 +540,14 @@ Error MetadataParser::validateRootSignature( | |
} | ||
|
||
for (const mcdxbc::RootParameterInfo &Info : RSD.ParametersContainer) { | ||
if (!dxbc::isValidShaderVisibility(Info.Header.ShaderVisibility)) | ||
DeferredErrs = | ||
joinErrors(std::move(DeferredErrs), | ||
make_error<RootSignatureValidationError<uint32_t>>( | ||
"ShaderVisibility", Info.Header.ShaderVisibility)); | ||
|
||
assert(dxbc::isValidParameterType(Info.Header.ParameterType) && | ||
"Invalid value for ParameterType"); | ||
|
||
switch (Info.Header.ParameterType) { | ||
switch (Info.Type) { | ||
case dxbc::RootParameterType::Constants32Bit: | ||
break; | ||
|
||
case to_underlying(dxbc::RootParameterType::CBV): | ||
case to_underlying(dxbc::RootParameterType::UAV): | ||
case to_underlying(dxbc::RootParameterType::SRV): { | ||
case dxbc::RootParameterType::CBV: | ||
case dxbc::RootParameterType::UAV: | ||
case dxbc::RootParameterType::SRV: { | ||
const dxbc::RTS0::v2::RootDescriptor &Descriptor = | ||
RSD.ParametersContainer.getRootDescriptor(Info.Location); | ||
if (!hlsl::rootsig::verifyRegisterValue(Descriptor.ShaderRegister)) | ||
|
@@ -569,7 +572,7 @@ Error MetadataParser::validateRootSignature( | |
} | ||
break; | ||
} | ||
case to_underlying(dxbc::RootParameterType::DescriptorTable): { | ||
case dxbc::RootParameterType::DescriptorTable: { | ||
const mcdxbc::DescriptorTable &Table = | ||
RSD.ParametersContainer.getDescriptorTable(Info.Location); | ||
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table) { | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -9,6 +9,7 @@ | |||||
#include "llvm/MC/DXContainerRootSignature.h" | ||||||
#include "llvm/ADT/SmallString.h" | ||||||
#include "llvm/Support/EndianStream.h" | ||||||
#include <cstdint> | ||||||
|
||||||
|
||||||
using namespace llvm; | ||||||
using namespace llvm::mcdxbc; | ||||||
|
@@ -35,20 +36,20 @@ size_t RootSignatureDesc::getSize() const { | |||||
StaticSamplers.size() * sizeof(dxbc::RTS0::v1::StaticSampler); | ||||||
|
||||||
for (const RootParameterInfo &I : ParametersContainer) { | ||||||
switch (I.Header.ParameterType) { | ||||||
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): | ||||||
switch (I.Type) { | ||||||
case dxbc::RootParameterType::Constants32Bit: | ||||||
Size += sizeof(dxbc::RTS0::v1::RootConstants); | ||||||
break; | ||||||
case llvm::to_underlying(dxbc::RootParameterType::CBV): | ||||||
case llvm::to_underlying(dxbc::RootParameterType::SRV): | ||||||
case llvm::to_underlying(dxbc::RootParameterType::UAV): | ||||||
case dxbc::RootParameterType::CBV: | ||||||
case dxbc::RootParameterType::SRV: | ||||||
case dxbc::RootParameterType::UAV: | ||||||
if (Version == 1) | ||||||
Size += sizeof(dxbc::RTS0::v1::RootDescriptor); | ||||||
else | ||||||
Size += sizeof(dxbc::RTS0::v2::RootDescriptor); | ||||||
|
||||||
break; | ||||||
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): | ||||||
case dxbc::RootParameterType::DescriptorTable: | ||||||
const DescriptorTable &Table = | ||||||
ParametersContainer.getDescriptorTable(I.Location); | ||||||
|
||||||
|
@@ -84,21 +85,20 @@ void RootSignatureDesc::write(raw_ostream &OS) const { | |||||
support::endian::write(BOS, Flags, llvm::endianness::little); | ||||||
|
||||||
SmallVector<uint32_t> ParamsOffsets; | ||||||
for (const RootParameterInfo &P : ParametersContainer) { | ||||||
support::endian::write(BOS, P.Header.ParameterType, | ||||||
llvm::endianness::little); | ||||||
support::endian::write(BOS, P.Header.ShaderVisibility, | ||||||
llvm::endianness::little); | ||||||
for (const RootParameterInfo &I : ParametersContainer) { | ||||||
support::endian::write(BOS, I.Type, llvm::endianness::little); | ||||||
support::endian::write(BOS, I.Visibility, llvm::endianness::little); | ||||||
|
||||||
ParamsOffsets.push_back(writePlaceholder(BOS)); | ||||||
} | ||||||
|
||||||
assert(NumParameters == ParamsOffsets.size()); | ||||||
for (size_t I = 0; I < NumParameters; ++I) { | ||||||
rewriteOffsetToCurrentByte(BOS, ParamsOffsets[I]); | ||||||
const auto &[Type, Loc] = ParametersContainer.getTypeAndLocForParameter(I); | ||||||
switch (Type) { | ||||||
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): { | ||||||
const auto Info = ParametersContainer.getInfo(I); | ||||||
|
const auto Info = ParametersContainer.getInfo(I); | |
const RootParameterInfo &Info = ParametersContainer.getInfo(I); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const uint32_t &
is a weird type, this could just be uint32_t
. I'd probably just update the users of Loc
to use Info.Location
directly though - I think it's clearer with one less variable here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, this pr is meant to remove any dependency from
MC
ontoObject/DXContainer.h
?Shouldn't that mean that some include is removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It not from
Object/DXContainer.h
, it is from some values defined insideBinaryFormat/DXContainer.h
mainly theRTS0
namespace