Compare commits

...

15 Commits

Author SHA1 Message Date
Joao Saffran
e57236c70a removing binaryformat dependency on mc 2025-08-20 14:41:14 -07:00
Joao Saffran
8c143ba0ce removing binary format descriptor range dependency 2025-08-20 11:55:38 -07:00
Joao Saffran
f3ecd8ae8c removing dependency of Object 2025-08-20 10:15:37 -07:00
Joao Saffran
8353fe0d0a remove Loc 2025-08-19 16:38:47 -07:00
Joao Saffran
dc436d553b remove cstdint 2025-08-19 16:37:45 -07:00
Joao Saffran
fb248daeef rename visibility 2025-08-19 16:36:56 -07:00
Joao Saffran
567a3d4efe remove default constructor 2025-08-19 16:35:55 -07:00
Joao Saffran
3b25b34cd9 save a copy 2025-08-19 16:35:05 -07:00
Joao Saffran
d38c00d09a remove unused 2025-08-19 16:33:07 -07:00
Joao Saffran
8eb82fdac3 adding missing import 2025-08-19 10:56:17 -07:00
Joao Saffran
1d29111c4f fix whitespace in test 2025-08-19 10:47:15 -07:00
Joao Saffran
6539364fa7 clean up 2025-08-19 10:45:49 -07:00
Joao Saffran
f6f2e61d5d removing root parameter header from MC 2025-08-19 10:34:02 -07:00
Joao Saffran
1690a9c04d clean up 2025-08-18 18:52:48 -07:00
Joao Saffran
31ec5e50ff making parameter type and shader visibility use enums 2025-08-18 18:49:45 -07:00
17 changed files with 362 additions and 396 deletions

View File

@ -1268,11 +1268,34 @@ bool SemaHLSL::handleRootSignatureElements(
// value // value
ReportError(Loc, 1, 0xfffffffe); ReportError(Loc, 1, 0xfffffffe);
} }
switch (Clause->Type) {
if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag( case llvm::dxil::ResourceClass::SRV:
Version, llvm::to_underlying(Clause->Type), if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(
llvm::to_underlying(Clause->Flags))) Version, llvm::dxbc::DescriptorRangeType::SRV,
ReportFlagError(Loc); llvm::to_underlying(Clause->Flags)))
ReportFlagError(Loc);
break;
case llvm::dxil::ResourceClass::UAV:
if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(
Version, llvm::dxbc::DescriptorRangeType::UAV,
llvm::to_underlying(Clause->Flags)))
ReportFlagError(Loc);
break;
case llvm::dxil::ResourceClass::CBuffer:
if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(
Version, llvm::dxbc::DescriptorRangeType::CBV,
llvm::to_underlying(Clause->Flags)))
ReportFlagError(Loc);
break;
case llvm::dxil::ResourceClass::Sampler:
if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(
Version, llvm::dxbc::DescriptorRangeType::Sampler,
llvm::to_underlying(Clause->Flags)))
ReportFlagError(Loc);
break;
break;
}
} }
} }

View File

@ -209,6 +209,16 @@ inline bool isValidParameterType(uint32_t V) {
return false; return false;
} }
#define DESCRIPTOR_RANGE(Val, Enum) \
case Val: \
return true;
inline bool isValidRangeType(uint32_t V) {
switch (V) {
#include "DXContainerConstants.def"
}
return false;
}
#define SHADER_VISIBILITY(Val, Enum) Enum = Val, #define SHADER_VISIBILITY(Val, Enum) Enum = Val,
enum class ShaderVisibility : uint32_t { enum class ShaderVisibility : uint32_t {
#include "DXContainerConstants.def" #include "DXContainerConstants.def"
@ -231,6 +241,16 @@ enum class SamplerFilter : uint32_t {
#include "DXContainerConstants.def" #include "DXContainerConstants.def"
}; };
#define FILTER(Val, Enum) \
case Val: \
return true;
inline bool isValidSamplerFilter(uint32_t V) {
switch (V) {
#include "DXContainerConstants.def"
}
return false;
}
LLVM_ABI ArrayRef<EnumEntry<SamplerFilter>> getSamplerFilters(); LLVM_ABI ArrayRef<EnumEntry<SamplerFilter>> getSamplerFilters();
#define TEXTURE_ADDRESS_MODE(Val, Enum) Enum = Val, #define TEXTURE_ADDRESS_MODE(Val, Enum) Enum = Val,
@ -240,6 +260,16 @@ enum class TextureAddressMode : uint32_t {
LLVM_ABI ArrayRef<EnumEntry<TextureAddressMode>> getTextureAddressModes(); LLVM_ABI ArrayRef<EnumEntry<TextureAddressMode>> getTextureAddressModes();
#define TEXTURE_ADDRESS_MODE(Val, Enum) \
case Val: \
return true;
inline bool isValidAddress(uint32_t V) {
switch (V) {
#include "DXContainerConstants.def"
}
return false;
}
#define COMPARISON_FUNC(Val, Enum) Enum = Val, #define COMPARISON_FUNC(Val, Enum) Enum = Val,
enum class ComparisonFunc : uint32_t { enum class ComparisonFunc : uint32_t {
#include "DXContainerConstants.def" #include "DXContainerConstants.def"
@ -247,11 +277,31 @@ enum class ComparisonFunc : uint32_t {
LLVM_ABI ArrayRef<EnumEntry<ComparisonFunc>> getComparisonFuncs(); LLVM_ABI ArrayRef<EnumEntry<ComparisonFunc>> getComparisonFuncs();
#define COMPARISON_FUNC(Val, Enum) \
case Val: \
return true;
inline bool isValidComparisonFunc(uint32_t V) {
switch (V) {
#include "DXContainerConstants.def"
}
return false;
}
#define STATIC_BORDER_COLOR(Val, Enum) Enum = Val, #define STATIC_BORDER_COLOR(Val, Enum) Enum = Val,
enum class StaticBorderColor : uint32_t { enum class StaticBorderColor : uint32_t {
#include "DXContainerConstants.def" #include "DXContainerConstants.def"
}; };
#define STATIC_BORDER_COLOR(Val, Enum) \
case Val: \
return true;
inline bool isValidBorderColor(uint32_t V) {
switch (V) {
#include "DXContainerConstants.def"
}
return false;
}
LLVM_ABI ArrayRef<EnumEntry<StaticBorderColor>> getStaticBorderColors(); LLVM_ABI ArrayRef<EnumEntry<StaticBorderColor>> getStaticBorderColors();
LLVM_ABI PartType parsePartType(StringRef S); LLVM_ABI PartType parsePartType(StringRef S);

View File

@ -30,15 +30,12 @@ LLVM_ABI bool verifyRegisterValue(uint32_t RegisterValue);
LLVM_ABI bool verifyRegisterSpace(uint32_t RegisterSpace); LLVM_ABI bool verifyRegisterSpace(uint32_t RegisterSpace);
LLVM_ABI bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal); LLVM_ABI bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal);
LLVM_ABI bool verifyRangeType(uint32_t Type); LLVM_ABI bool verifyRangeType(uint32_t Type);
LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type, LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version,
dxbc::DescriptorRangeType Type,
uint32_t FlagsVal); uint32_t FlagsVal);
LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors); LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors);
LLVM_ABI bool verifySamplerFilter(uint32_t Value);
LLVM_ABI bool verifyAddress(uint32_t Address);
LLVM_ABI bool verifyMipLODBias(float MipLODBias); LLVM_ABI bool verifyMipLODBias(float MipLODBias);
LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy); LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy);
LLVM_ABI bool verifyComparisonFunc(uint32_t ComparisonFunc);
LLVM_ABI bool verifyBorderColor(uint32_t BorderColor);
LLVM_ABI bool verifyLOD(float LOD); LLVM_ABI bool verifyLOD(float LOD);
} // namespace rootsig } // namespace rootsig

View File

@ -19,75 +19,104 @@ namespace llvm {
class raw_ostream; class raw_ostream;
namespace mcdxbc { namespace mcdxbc {
struct RootConstants {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
uint32_t Num32BitValues;
};
struct RootDescriptor {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
uint32_t Flags;
};
struct DescriptorRange {
dxbc::DescriptorRangeType RangeType;
uint32_t NumDescriptors;
uint32_t BaseShaderRegister;
uint32_t RegisterSpace;
uint32_t Flags;
uint32_t OffsetInDescriptorsFromTableStart;
};
struct RootParameterInfo { struct RootParameterInfo {
dxbc::RTS0::v1::RootParameterHeader Header; dxbc::RootParameterType Type;
dxbc::ShaderVisibility Visibility;
size_t Location; size_t Location;
RootParameterInfo() = default; RootParameterInfo(dxbc::RootParameterType Type,
dxbc::ShaderVisibility Visibility, size_t Location)
RootParameterInfo(dxbc::RTS0::v1::RootParameterHeader Header, size_t Location) : Type(Type), Visibility(Visibility), Location(Location) {}
: Header(Header), Location(Location) {}
}; };
struct DescriptorTable { struct DescriptorTable {
SmallVector<dxbc::RTS0::v2::DescriptorRange> Ranges; SmallVector<DescriptorRange> Ranges;
SmallVector<dxbc::RTS0::v2::DescriptorRange>::const_iterator begin() const { SmallVector<DescriptorRange>::const_iterator begin() const {
return Ranges.begin(); return Ranges.begin();
} }
SmallVector<dxbc::RTS0::v2::DescriptorRange>::const_iterator end() const { SmallVector<DescriptorRange>::const_iterator end() const {
return Ranges.end(); return Ranges.end();
} }
}; };
struct StaticSampler {
dxbc::SamplerFilter Filter;
dxbc::TextureAddressMode AddressU;
dxbc::TextureAddressMode AddressV;
dxbc::TextureAddressMode AddressW;
float MipLODBias;
uint32_t MaxAnisotropy;
dxbc::ComparisonFunc ComparisonFunc;
dxbc::StaticBorderColor BorderColor;
float MinLOD;
float MaxLOD;
uint32_t ShaderRegister;
uint32_t RegisterSpace;
dxbc::ShaderVisibility ShaderVisibility;
};
struct RootParametersContainer { struct RootParametersContainer {
SmallVector<RootParameterInfo> ParametersInfo; SmallVector<RootParameterInfo> ParametersInfo;
SmallVector<dxbc::RTS0::v1::RootConstants> Constants; SmallVector<RootConstants> Constants;
SmallVector<dxbc::RTS0::v2::RootDescriptor> Descriptors; SmallVector<RootDescriptor> Descriptors;
SmallVector<DescriptorTable> Tables; SmallVector<DescriptorTable> Tables;
void addInfo(dxbc::RTS0::v1::RootParameterHeader Header, size_t Location) { void addInfo(dxbc::RootParameterType Type, dxbc::ShaderVisibility Visibility,
ParametersInfo.push_back(RootParameterInfo(Header, Location)); size_t Location) {
ParametersInfo.emplace_back(Type, Visibility, Location);
} }
void addParameter(dxbc::RTS0::v1::RootParameterHeader Header, void addParameter(dxbc::RootParameterType Type,
dxbc::RTS0::v1::RootConstants Constant) { dxbc::ShaderVisibility Visibility, RootConstants Constant) {
addInfo(Header, Constants.size()); addInfo(Type, Visibility, Constants.size());
Constants.push_back(Constant); Constants.push_back(Constant);
} }
void addInvalidParameter(dxbc::RTS0::v1::RootParameterHeader Header) { void addParameter(dxbc::RootParameterType Type,
addInfo(Header, -1); dxbc::ShaderVisibility Visibility,
} RootDescriptor Descriptor) {
addInfo(Type, Visibility, Descriptors.size());
void addParameter(dxbc::RTS0::v1::RootParameterHeader Header,
dxbc::RTS0::v2::RootDescriptor Descriptor) {
addInfo(Header, Descriptors.size());
Descriptors.push_back(Descriptor); Descriptors.push_back(Descriptor);
} }
void addParameter(dxbc::RTS0::v1::RootParameterHeader Header, void addParameter(dxbc::RootParameterType Type,
DescriptorTable Table) { dxbc::ShaderVisibility Visibility, DescriptorTable Table) {
addInfo(Header, Tables.size()); addInfo(Type, Visibility, Tables.size());
Tables.push_back(Table); Tables.push_back(Table);
} }
std::pair<uint32_t, uint32_t> const RootParameterInfo &getInfo(uint32_t Location) const {
getTypeAndLocForParameter(uint32_t Location) const {
const RootParameterInfo &Info = ParametersInfo[Location]; const RootParameterInfo &Info = ParametersInfo[Location];
return {Info.Header.ParameterType, Info.Location}; return Info;
} }
const dxbc::RTS0::v1::RootParameterHeader &getHeader(size_t Location) const { const RootConstants &getConstant(size_t Index) const {
const RootParameterInfo &Info = ParametersInfo[Location];
return Info.Header;
}
const dxbc::RTS0::v1::RootConstants &getConstant(size_t Index) const {
return Constants[Index]; return Constants[Index];
} }
const dxbc::RTS0::v2::RootDescriptor &getRootDescriptor(size_t Index) const { const RootDescriptor &getRootDescriptor(size_t Index) const {
return Descriptors[Index]; return Descriptors[Index];
} }
@ -112,7 +141,7 @@ struct RootSignatureDesc {
uint32_t StaticSamplersOffset = 0u; uint32_t StaticSamplersOffset = 0u;
uint32_t NumStaticSamplers = 0u; uint32_t NumStaticSamplers = 0u;
mcdxbc::RootParametersContainer ParametersContainer; mcdxbc::RootParametersContainer ParametersContainer;
SmallVector<dxbc::RTS0::v1::StaticSampler> StaticSamplers; SmallVector<StaticSampler> StaticSamplers;
LLVM_ABI void write(raw_ostream &OS) const; LLVM_ABI void write(raw_ostream &OS) const;

View File

@ -149,6 +149,16 @@ ArrayRef<EnumEntry<RootParameterType>> dxbc::getRootParameterTypes() {
return ArrayRef(RootParameterTypes); return ArrayRef(RootParameterTypes);
} }
#define DESCRIPTOR_RANGE(Val, Enum) {#Enum, DescriptorRangeType::Enum},
static const EnumEntry<DescriptorRangeType> DescriptorRangeTypes[] = {
#include "llvm/BinaryFormat/DXContainerConstants.def"
};
ArrayRef<EnumEntry<DescriptorRangeType>> dxbc::getDescriptorRangeTypes() {
return ArrayRef(DescriptorRangeTypes);
}
#define SEMANTIC_KIND(Val, Enum) {#Enum, PSV::SemanticKind::Enum}, #define SEMANTIC_KIND(Val, Enum) {#Enum, PSV::SemanticKind::Enum},
static const EnumEntry<PSV::SemanticKind> SemanticKindNames[] = { static const EnumEntry<PSV::SemanticKind> SemanticKindNames[] = {

View File

@ -51,6 +51,17 @@ static std::optional<StringRef> extractMdStringValue(MDNode *Node,
return NodeText->getString(); return NodeText->getString();
} }
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
Expected<T> extractEnumValue(MDNode *Node, unsigned int OpId, StringRef ErrText,
llvm::function_ref<bool(uint32_t)> VerifyFn) {
if (std::optional<uint32_t> Val = extractMdIntValue(Node, OpId)) {
if (!VerifyFn(*Val))
return make_error<RootSignatureValidationError<uint32_t>>(ErrText, *Val);
return static_cast<T>(*Val);
}
return make_error<InvalidRSMetadataValue>("ShaderVisibility");
}
namespace { namespace {
// We use the OverloadVisit with std::visit to ensure the compiler catches if a // We use the OverloadVisit with std::visit to ensure the compiler catches if a
@ -224,17 +235,14 @@ Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD,
if (RootConstantNode->getNumOperands() != 5) if (RootConstantNode->getNumOperands() != 5)
return make_error<InvalidRSMetadataFormat>("RootConstants Element"); return make_error<InvalidRSMetadataFormat>("RootConstants Element");
dxbc::RTS0::v1::RootParameterHeader Header; Expected<dxbc::ShaderVisibility> Visibility =
// The parameter offset doesn't matter here - we recalculate it during extractEnumValue<dxbc::ShaderVisibility>(RootConstantNode, 1,
// serialization Header.ParameterOffset = 0; "ShaderVisibility",
Header.ParameterType = to_underlying(dxbc::RootParameterType::Constants32Bit); dxbc::isValidShaderVisibility);
if (auto E = Visibility.takeError())
return Error(std::move(E));
if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 1)) mcdxbc::RootConstants Constants;
Header.ShaderVisibility = *Val;
else
return make_error<InvalidRSMetadataValue>("ShaderVisibility");
dxbc::RTS0::v1::RootConstants Constants;
if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 2)) if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 2))
Constants.ShaderRegister = *Val; Constants.ShaderRegister = *Val;
else else
@ -250,7 +258,8 @@ Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD,
else else
return make_error<InvalidRSMetadataValue>("Num32BitValues"); return make_error<InvalidRSMetadataValue>("Num32BitValues");
RSD.ParametersContainer.addParameter(Header, Constants); RSD.ParametersContainer.addParameter(dxbc::RootParameterType::Constants32Bit,
*Visibility, Constants);
return Error::success(); return Error::success();
} }
@ -266,28 +275,30 @@ Error MetadataParser::parseRootDescriptors(
if (RootDescriptorNode->getNumOperands() != 5) if (RootDescriptorNode->getNumOperands() != 5)
return make_error<InvalidRSMetadataFormat>("Root Descriptor Element"); return make_error<InvalidRSMetadataFormat>("Root Descriptor Element");
dxbc::RTS0::v1::RootParameterHeader Header; dxbc::RootParameterType Type;
switch (ElementKind) { switch (ElementKind) {
case RootSignatureElementKind::SRV: case RootSignatureElementKind::SRV:
Header.ParameterType = to_underlying(dxbc::RootParameterType::SRV); Type = dxbc::RootParameterType::SRV;
break; break;
case RootSignatureElementKind::UAV: case RootSignatureElementKind::UAV:
Header.ParameterType = to_underlying(dxbc::RootParameterType::UAV); Type = dxbc::RootParameterType::UAV;
break; break;
case RootSignatureElementKind::CBV: case RootSignatureElementKind::CBV:
Header.ParameterType = to_underlying(dxbc::RootParameterType::CBV); Type = dxbc::RootParameterType::CBV;
break; break;
default: default:
llvm_unreachable("invalid Root Descriptor kind"); llvm_unreachable("invalid Root Descriptor kind");
break; break;
} }
if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 1)) Expected<dxbc::ShaderVisibility> Visibility =
Header.ShaderVisibility = *Val; extractEnumValue<dxbc::ShaderVisibility>(RootDescriptorNode, 1,
else "ShaderVisibility",
return make_error<InvalidRSMetadataValue>("ShaderVisibility"); dxbc::isValidShaderVisibility);
if (auto E = Visibility.takeError())
return Error(std::move(E));
dxbc::RTS0::v2::RootDescriptor Descriptor; mcdxbc::RootDescriptor Descriptor;
if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 2)) if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 2))
Descriptor.ShaderRegister = *Val; Descriptor.ShaderRegister = *Val;
else else
@ -299,7 +310,7 @@ Error MetadataParser::parseRootDescriptors(
return make_error<InvalidRSMetadataValue>("RegisterSpace"); return make_error<InvalidRSMetadataValue>("RegisterSpace");
if (RSD.Version == 1) { if (RSD.Version == 1) {
RSD.ParametersContainer.addParameter(Header, Descriptor); RSD.ParametersContainer.addParameter(Type, *Visibility, Descriptor);
return Error::success(); return Error::success();
} }
assert(RSD.Version > 1); assert(RSD.Version > 1);
@ -309,7 +320,7 @@ Error MetadataParser::parseRootDescriptors(
else else
return make_error<InvalidRSMetadataValue>("Root Descriptor Flags"); return make_error<InvalidRSMetadataValue>("Root Descriptor Flags");
RSD.ParametersContainer.addParameter(Header, Descriptor); RSD.ParametersContainer.addParameter(Type, *Visibility, Descriptor);
return Error::success(); return Error::success();
} }
@ -318,7 +329,7 @@ Error MetadataParser::parseDescriptorRange(mcdxbc::DescriptorTable &Table,
if (RangeDescriptorNode->getNumOperands() != 6) if (RangeDescriptorNode->getNumOperands() != 6)
return make_error<InvalidRSMetadataFormat>("Descriptor Range"); return make_error<InvalidRSMetadataFormat>("Descriptor Range");
dxbc::RTS0::v2::DescriptorRange Range; mcdxbc::DescriptorRange Range;
std::optional<StringRef> ElementText = std::optional<StringRef> ElementText =
extractMdStringValue(RangeDescriptorNode, 0); extractMdStringValue(RangeDescriptorNode, 0);
@ -326,17 +337,11 @@ Error MetadataParser::parseDescriptorRange(mcdxbc::DescriptorTable &Table,
if (!ElementText.has_value()) if (!ElementText.has_value())
return make_error<InvalidRSMetadataFormat>("Descriptor Range"); return make_error<InvalidRSMetadataFormat>("Descriptor Range");
Range.RangeType = Range.RangeType = StringSwitch<dxbc::DescriptorRangeType>(*ElementText)
StringSwitch<uint32_t>(*ElementText) .Case("CBV", dxbc::DescriptorRangeType::CBV)
.Case("CBV", to_underlying(dxbc::DescriptorRangeType::CBV)) .Case("SRV", dxbc::DescriptorRangeType::SRV)
.Case("SRV", to_underlying(dxbc::DescriptorRangeType::SRV)) .Case("UAV", dxbc::DescriptorRangeType::UAV)
.Case("UAV", to_underlying(dxbc::DescriptorRangeType::UAV)) .Case("Sampler", dxbc::DescriptorRangeType::Sampler);
.Case("Sampler", to_underlying(dxbc::DescriptorRangeType::Sampler))
.Default(~0U);
if (Range.RangeType == ~0U)
return make_error<GenericRSMetadataError>("Invalid Descriptor Range type.",
RangeDescriptorNode);
if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 1)) if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 1))
Range.NumDescriptors = *Val; Range.NumDescriptors = *Val;
@ -375,15 +380,14 @@ Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
if (NumOperands < 2) if (NumOperands < 2)
return make_error<InvalidRSMetadataFormat>("Descriptor Table"); return make_error<InvalidRSMetadataFormat>("Descriptor Table");
dxbc::RTS0::v1::RootParameterHeader Header; Expected<dxbc::ShaderVisibility> Visibility =
if (std::optional<uint32_t> Val = extractMdIntValue(DescriptorTableNode, 1)) extractEnumValue<dxbc::ShaderVisibility>(DescriptorTableNode, 1,
Header.ShaderVisibility = *Val; "ShaderVisibility",
else dxbc::isValidShaderVisibility);
return make_error<InvalidRSMetadataValue>("ShaderVisibility"); if (auto E = Visibility.takeError())
return Error(std::move(E));
mcdxbc::DescriptorTable Table; mcdxbc::DescriptorTable Table;
Header.ParameterType =
to_underlying(dxbc::RootParameterType::DescriptorTable);
for (unsigned int I = 2; I < NumOperands; I++) { for (unsigned int I = 2; I < NumOperands; I++) {
MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I)); MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I));
@ -395,7 +399,8 @@ Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
return Err; return Err;
} }
RSD.ParametersContainer.addParameter(Header, Table); RSD.ParametersContainer.addParameter(dxbc::RootParameterType::DescriptorTable,
*Visibility, Table);
return Error::success(); return Error::success();
} }
@ -404,26 +409,34 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
if (StaticSamplerNode->getNumOperands() != 14) if (StaticSamplerNode->getNumOperands() != 14)
return make_error<InvalidRSMetadataFormat>("Static Sampler"); return make_error<InvalidRSMetadataFormat>("Static Sampler");
dxbc::RTS0::v1::StaticSampler Sampler; mcdxbc::StaticSampler Sampler;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 1))
Sampler.Filter = *Val;
else
return make_error<InvalidRSMetadataValue>("Filter");
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 2)) Expected<dxbc::SamplerFilter> Filter = extractEnumValue<dxbc::SamplerFilter>(
Sampler.AddressU = *Val; StaticSamplerNode, 1, "Filter", dxbc::isValidSamplerFilter);
else if (auto E = Filter.takeError())
return make_error<InvalidRSMetadataValue>("AddressU"); return Error(std::move(E));
Sampler.Filter = *Filter;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 3)) Expected<dxbc::TextureAddressMode> AddressU =
Sampler.AddressV = *Val; extractEnumValue<dxbc::TextureAddressMode>(
else StaticSamplerNode, 2, "AddressU", dxbc::isValidAddress);
return make_error<InvalidRSMetadataValue>("AddressV"); if (auto E = AddressU.takeError())
return Error(std::move(E));
Sampler.AddressU = *AddressU;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 4)) Expected<dxbc::TextureAddressMode> AddressV =
Sampler.AddressW = *Val; extractEnumValue<dxbc::TextureAddressMode>(
else StaticSamplerNode, 3, "AddressV", dxbc::isValidAddress);
return make_error<InvalidRSMetadataValue>("AddressW"); if (auto E = AddressV.takeError())
return Error(std::move(E));
Sampler.AddressV = *AddressV;
Expected<dxbc::TextureAddressMode> AddressW =
extractEnumValue<dxbc::TextureAddressMode>(
StaticSamplerNode, 4, "AddressW", dxbc::isValidAddress);
if (auto E = AddressW.takeError())
return Error(std::move(E));
Sampler.AddressW = *AddressW;
if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 5)) if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 5))
Sampler.MipLODBias = *Val; Sampler.MipLODBias = *Val;
@ -435,15 +448,19 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
else else
return make_error<InvalidRSMetadataValue>("MaxAnisotropy"); return make_error<InvalidRSMetadataValue>("MaxAnisotropy");
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 7)) Expected<dxbc::ComparisonFunc> ComparisonFunc =
Sampler.ComparisonFunc = *Val; extractEnumValue<dxbc::ComparisonFunc>(
else StaticSamplerNode, 7, "ComparisonFunc", dxbc::isValidComparisonFunc);
return make_error<InvalidRSMetadataValue>("ComparisonFunc"); if (auto E = ComparisonFunc.takeError())
return Error(std::move(E));
Sampler.ComparisonFunc = *ComparisonFunc;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 8)) Expected<dxbc::StaticBorderColor> BorderColor =
Sampler.BorderColor = *Val; extractEnumValue<dxbc::StaticBorderColor>(
else StaticSamplerNode, 8, "BorderColor", dxbc::isValidBorderColor);
return make_error<InvalidRSMetadataValue>("ComparisonFunc"); if (auto E = BorderColor.takeError())
return Error(std::move(E));
Sampler.BorderColor = *BorderColor;
if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 9)) if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 9))
Sampler.MinLOD = *Val; Sampler.MinLOD = *Val;
@ -465,10 +482,13 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
else else
return make_error<InvalidRSMetadataValue>("RegisterSpace"); return make_error<InvalidRSMetadataValue>("RegisterSpace");
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 13)) Expected<dxbc::ShaderVisibility> Visibility =
Sampler.ShaderVisibility = *Val; extractEnumValue<dxbc::ShaderVisibility>(StaticSamplerNode, 13,
else "ShaderVisibility",
return make_error<InvalidRSMetadataValue>("ShaderVisibility"); dxbc::isValidShaderVisibility);
if (auto E = Visibility.takeError())
return Error(std::move(E));
Sampler.ShaderVisibility = *Visibility;
RSD.StaticSamplers.push_back(Sampler); RSD.StaticSamplers.push_back(Sampler);
return Error::success(); return Error::success();
@ -531,21 +551,15 @@ Error MetadataParser::validateRootSignature(
} }
for (const mcdxbc::RootParameterInfo &Info : RSD.ParametersContainer) { 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) && switch (Info.Type) {
"Invalid value for ParameterType"); case dxbc::RootParameterType::Constants32Bit:
break;
switch (Info.Header.ParameterType) { case dxbc::RootParameterType::CBV:
case dxbc::RootParameterType::UAV:
case to_underlying(dxbc::RootParameterType::CBV): case dxbc::RootParameterType::SRV: {
case to_underlying(dxbc::RootParameterType::UAV): const mcdxbc::RootDescriptor &Descriptor =
case to_underlying(dxbc::RootParameterType::SRV): {
const dxbc::RTS0::v2::RootDescriptor &Descriptor =
RSD.ParametersContainer.getRootDescriptor(Info.Location); RSD.ParametersContainer.getRootDescriptor(Info.Location);
if (!hlsl::rootsig::verifyRegisterValue(Descriptor.ShaderRegister)) if (!hlsl::rootsig::verifyRegisterValue(Descriptor.ShaderRegister))
DeferredErrs = DeferredErrs =
@ -569,15 +583,10 @@ Error MetadataParser::validateRootSignature(
} }
break; break;
} }
case to_underlying(dxbc::RootParameterType::DescriptorTable): { case dxbc::RootParameterType::DescriptorTable: {
const mcdxbc::DescriptorTable &Table = const mcdxbc::DescriptorTable &Table =
RSD.ParametersContainer.getDescriptorTable(Info.Location); RSD.ParametersContainer.getDescriptorTable(Info.Location);
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table) { for (const mcdxbc::DescriptorRange &Range : Table) {
if (!hlsl::rootsig::verifyRangeType(Range.RangeType))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"RangeType", Range.RangeType));
if (!hlsl::rootsig::verifyRegisterSpace(Range.RegisterSpace)) if (!hlsl::rootsig::verifyRegisterSpace(Range.RegisterSpace))
DeferredErrs = DeferredErrs =
@ -603,30 +612,7 @@ Error MetadataParser::validateRootSignature(
} }
} }
for (const dxbc::RTS0::v1::StaticSampler &Sampler : RSD.StaticSamplers) { for (const mcdxbc::StaticSampler &Sampler : RSD.StaticSamplers) {
if (!hlsl::rootsig::verifySamplerFilter(Sampler.Filter))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"Filter", Sampler.Filter));
if (!hlsl::rootsig::verifyAddress(Sampler.AddressU))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"AddressU", Sampler.AddressU));
if (!hlsl::rootsig::verifyAddress(Sampler.AddressV))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"AddressV", Sampler.AddressV));
if (!hlsl::rootsig::verifyAddress(Sampler.AddressW))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"AddressW", Sampler.AddressW));
if (!hlsl::rootsig::verifyMipLODBias(Sampler.MipLODBias)) if (!hlsl::rootsig::verifyMipLODBias(Sampler.MipLODBias))
DeferredErrs = joinErrors(std::move(DeferredErrs), DeferredErrs = joinErrors(std::move(DeferredErrs),
@ -639,18 +625,6 @@ Error MetadataParser::validateRootSignature(
make_error<RootSignatureValidationError<uint32_t>>( make_error<RootSignatureValidationError<uint32_t>>(
"MaxAnisotropy", Sampler.MaxAnisotropy)); "MaxAnisotropy", Sampler.MaxAnisotropy));
if (!hlsl::rootsig::verifyComparisonFunc(Sampler.ComparisonFunc))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"ComparisonFunc", Sampler.ComparisonFunc));
if (!hlsl::rootsig::verifyBorderColor(Sampler.BorderColor))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"BorderColor", Sampler.BorderColor));
if (!hlsl::rootsig::verifyLOD(Sampler.MinLOD)) if (!hlsl::rootsig::verifyLOD(Sampler.MinLOD))
DeferredErrs = joinErrors(std::move(DeferredErrs), DeferredErrs = joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<float>>( make_error<RootSignatureValidationError<float>>(
@ -672,12 +646,6 @@ Error MetadataParser::validateRootSignature(
joinErrors(std::move(DeferredErrs), joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>( make_error<RootSignatureValidationError<uint32_t>>(
"RegisterSpace", Sampler.RegisterSpace)); "RegisterSpace", Sampler.RegisterSpace));
if (!dxbc::isValidShaderVisibility(Sampler.ShaderVisibility))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"ShaderVisibility", Sampler.ShaderVisibility));
} }
return DeferredErrs; return DeferredErrs;

View File

@ -63,13 +63,12 @@ bool verifyRangeType(uint32_t Type) {
return false; return false;
} }
bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type, bool verifyDescriptorRangeFlag(uint32_t Version, dxbc::DescriptorRangeType Type,
uint32_t FlagsVal) { uint32_t FlagsVal) {
using FlagT = dxbc::DescriptorRangeFlags; using FlagT = dxbc::DescriptorRangeFlags;
FlagT Flags = FlagT(FlagsVal); FlagT Flags = FlagT(FlagsVal);
const bool IsSampler = const bool IsSampler = (Type == dxbc::DescriptorRangeType::Sampler);
(Type == llvm::to_underlying(dxbc::DescriptorRangeType::Sampler));
if (Version == 1) { if (Version == 1) {
// Since the metadata is unversioned, we expect to explicitly see the values // Since the metadata is unversioned, we expect to explicitly see the values
@ -129,27 +128,6 @@ bool verifyNumDescriptors(uint32_t NumDescriptors) {
return NumDescriptors > 0; return NumDescriptors > 0;
} }
bool verifySamplerFilter(uint32_t Value) {
switch (Value) {
#define FILTER(Num, Val) case llvm::to_underlying(dxbc::SamplerFilter::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}
// Values allowed here:
// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_texture_address_mode#syntax
bool verifyAddress(uint32_t Address) {
switch (Address) {
#define TEXTURE_ADDRESS_MODE(Num, Val) \
case llvm::to_underlying(dxbc::TextureAddressMode::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}
bool verifyMipLODBias(float MipLODBias) { bool verifyMipLODBias(float MipLODBias) {
return MipLODBias >= -16.f && MipLODBias <= 15.99f; return MipLODBias >= -16.f && MipLODBias <= 15.99f;
} }
@ -158,26 +136,6 @@ bool verifyMaxAnisotropy(uint32_t MaxAnisotropy) {
return MaxAnisotropy <= 16u; return MaxAnisotropy <= 16u;
} }
bool verifyComparisonFunc(uint32_t ComparisonFunc) {
switch (ComparisonFunc) {
#define COMPARISON_FUNC(Num, Val) \
case llvm::to_underlying(dxbc::ComparisonFunc::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}
bool verifyBorderColor(uint32_t BorderColor) {
switch (BorderColor) {
#define STATIC_BORDER_COLOR(Num, Val) \
case llvm::to_underlying(dxbc::StaticBorderColor::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}
bool verifyLOD(float LOD) { return !std::isnan(LOD); } bool verifyLOD(float LOD) { return !std::isnan(LOD); }
} // namespace rootsig } // namespace rootsig

View File

@ -35,20 +35,20 @@ size_t RootSignatureDesc::getSize() const {
StaticSamplers.size() * sizeof(dxbc::RTS0::v1::StaticSampler); StaticSamplers.size() * sizeof(dxbc::RTS0::v1::StaticSampler);
for (const RootParameterInfo &I : ParametersContainer) { for (const RootParameterInfo &I : ParametersContainer) {
switch (I.Header.ParameterType) { switch (I.Type) {
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): case dxbc::RootParameterType::Constants32Bit:
Size += sizeof(dxbc::RTS0::v1::RootConstants); Size += sizeof(dxbc::RTS0::v1::RootConstants);
break; break;
case llvm::to_underlying(dxbc::RootParameterType::CBV): case dxbc::RootParameterType::CBV:
case llvm::to_underlying(dxbc::RootParameterType::SRV): case dxbc::RootParameterType::SRV:
case llvm::to_underlying(dxbc::RootParameterType::UAV): case dxbc::RootParameterType::UAV:
if (Version == 1) if (Version == 1)
Size += sizeof(dxbc::RTS0::v1::RootDescriptor); Size += sizeof(dxbc::RTS0::v1::RootDescriptor);
else else
Size += sizeof(dxbc::RTS0::v2::RootDescriptor); Size += sizeof(dxbc::RTS0::v2::RootDescriptor);
break; break;
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): case dxbc::RootParameterType::DescriptorTable:
const DescriptorTable &Table = const DescriptorTable &Table =
ParametersContainer.getDescriptorTable(I.Location); ParametersContainer.getDescriptorTable(I.Location);
@ -84,11 +84,9 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
support::endian::write(BOS, Flags, llvm::endianness::little); support::endian::write(BOS, Flags, llvm::endianness::little);
SmallVector<uint32_t> ParamsOffsets; SmallVector<uint32_t> ParamsOffsets;
for (const RootParameterInfo &P : ParametersContainer) { for (const RootParameterInfo &I : ParametersContainer) {
support::endian::write(BOS, P.Header.ParameterType, support::endian::write(BOS, I.Type, llvm::endianness::little);
llvm::endianness::little); support::endian::write(BOS, I.Visibility, llvm::endianness::little);
support::endian::write(BOS, P.Header.ShaderVisibility,
llvm::endianness::little);
ParamsOffsets.push_back(writePlaceholder(BOS)); ParamsOffsets.push_back(writePlaceholder(BOS));
} }
@ -96,11 +94,11 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
assert(NumParameters == ParamsOffsets.size()); assert(NumParameters == ParamsOffsets.size());
for (size_t I = 0; I < NumParameters; ++I) { for (size_t I = 0; I < NumParameters; ++I) {
rewriteOffsetToCurrentByte(BOS, ParamsOffsets[I]); rewriteOffsetToCurrentByte(BOS, ParamsOffsets[I]);
const auto &[Type, Loc] = ParametersContainer.getTypeAndLocForParameter(I); const auto Info = ParametersContainer.getInfo(I);
switch (Type) { switch (Info.Type) {
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): { case dxbc::RootParameterType::Constants32Bit: {
const dxbc::RTS0::v1::RootConstants &Constants = const mcdxbc::RootConstants &Constants =
ParametersContainer.getConstant(Loc); ParametersContainer.getConstant(Info.Location);
support::endian::write(BOS, Constants.ShaderRegister, support::endian::write(BOS, Constants.ShaderRegister,
llvm::endianness::little); llvm::endianness::little);
support::endian::write(BOS, Constants.RegisterSpace, support::endian::write(BOS, Constants.RegisterSpace,
@ -109,11 +107,11 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
llvm::endianness::little); llvm::endianness::little);
break; break;
} }
case llvm::to_underlying(dxbc::RootParameterType::CBV): case dxbc::RootParameterType::CBV:
case llvm::to_underlying(dxbc::RootParameterType::SRV): case dxbc::RootParameterType::SRV:
case llvm::to_underlying(dxbc::RootParameterType::UAV): { case dxbc::RootParameterType::UAV: {
const dxbc::RTS0::v2::RootDescriptor &Descriptor = const mcdxbc::RootDescriptor &Descriptor =
ParametersContainer.getRootDescriptor(Loc); ParametersContainer.getRootDescriptor(Info.Location);
support::endian::write(BOS, Descriptor.ShaderRegister, support::endian::write(BOS, Descriptor.ShaderRegister,
llvm::endianness::little); llvm::endianness::little);
@ -123,9 +121,9 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little); support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little);
break; break;
} }
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): { case dxbc::RootParameterType::DescriptorTable: {
const DescriptorTable &Table = const DescriptorTable &Table =
ParametersContainer.getDescriptorTable(Loc); ParametersContainer.getDescriptorTable(Info.Location);
support::endian::write(BOS, (uint32_t)Table.Ranges.size(), support::endian::write(BOS, (uint32_t)Table.Ranges.size(),
llvm::endianness::little); llvm::endianness::little);
rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS)); rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS));

View File

@ -275,42 +275,50 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
for (DXContainerYAML::RootParameterLocationYaml &L : for (DXContainerYAML::RootParameterLocationYaml &L :
P.RootSignature->Parameters.Locations) { P.RootSignature->Parameters.Locations) {
dxbc::RTS0::v1::RootParameterHeader Header{L.Header.Type, L.Header.Visibility,
L.Header.Offset};
switch (L.Header.Type) { assert(dxbc::isValidParameterType(L.Header.Type) &&
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): { "invalid DXContainer YAML");
assert(dxbc::isValidShaderVisibility(L.Header.Visibility) &&
"invalid DXContainer YAML");
dxbc::RootParameterType Type = dxbc::RootParameterType(L.Header.Type);
dxbc::ShaderVisibility Visibility =
dxbc::ShaderVisibility(L.Header.Visibility);
switch (Type) {
case dxbc::RootParameterType::Constants32Bit: {
const DXContainerYAML::RootConstantsYaml &ConstantYaml = const DXContainerYAML::RootConstantsYaml &ConstantYaml =
P.RootSignature->Parameters.getOrInsertConstants(L); P.RootSignature->Parameters.getOrInsertConstants(L);
dxbc::RTS0::v1::RootConstants Constants; mcdxbc::RootConstants Constants;
Constants.Num32BitValues = ConstantYaml.Num32BitValues; Constants.Num32BitValues = ConstantYaml.Num32BitValues;
Constants.RegisterSpace = ConstantYaml.RegisterSpace; Constants.RegisterSpace = ConstantYaml.RegisterSpace;
Constants.ShaderRegister = ConstantYaml.ShaderRegister; Constants.ShaderRegister = ConstantYaml.ShaderRegister;
RS.ParametersContainer.addParameter(Header, Constants); RS.ParametersContainer.addParameter(Type, Visibility, Constants);
break; break;
} }
case llvm::to_underlying(dxbc::RootParameterType::CBV): case dxbc::RootParameterType::CBV:
case llvm::to_underlying(dxbc::RootParameterType::SRV): case dxbc::RootParameterType::SRV:
case llvm::to_underlying(dxbc::RootParameterType::UAV): { case dxbc::RootParameterType::UAV: {
const DXContainerYAML::RootDescriptorYaml &DescriptorYaml = const DXContainerYAML::RootDescriptorYaml &DescriptorYaml =
P.RootSignature->Parameters.getOrInsertDescriptor(L); P.RootSignature->Parameters.getOrInsertDescriptor(L);
dxbc::RTS0::v2::RootDescriptor Descriptor; mcdxbc::RootDescriptor Descriptor;
Descriptor.RegisterSpace = DescriptorYaml.RegisterSpace; Descriptor.RegisterSpace = DescriptorYaml.RegisterSpace;
Descriptor.ShaderRegister = DescriptorYaml.ShaderRegister; Descriptor.ShaderRegister = DescriptorYaml.ShaderRegister;
if (RS.Version > 1) if (RS.Version > 1)
Descriptor.Flags = DescriptorYaml.getEncodedFlags(); Descriptor.Flags = DescriptorYaml.getEncodedFlags();
RS.ParametersContainer.addParameter(Header, Descriptor); RS.ParametersContainer.addParameter(Type, Visibility, Descriptor);
break; break;
} }
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): { case dxbc::RootParameterType::DescriptorTable: {
const DXContainerYAML::DescriptorTableYaml &TableYaml = const DXContainerYAML::DescriptorTableYaml &TableYaml =
P.RootSignature->Parameters.getOrInsertTable(L); P.RootSignature->Parameters.getOrInsertTable(L);
mcdxbc::DescriptorTable Table; mcdxbc::DescriptorTable Table;
for (const auto &R : TableYaml.Ranges) { for (const auto &R : TableYaml.Ranges) {
assert(dxbc::isValidRangeType(R.RangeType) &&
dxbc::RTS0::v2::DescriptorRange Range; "Invalid Descriptor Range Type");
Range.RangeType = R.RangeType; mcdxbc::DescriptorRange Range;
Range.RangeType = dxbc::DescriptorRangeType(R.RangeType);
Range.NumDescriptors = R.NumDescriptors; Range.NumDescriptors = R.NumDescriptors;
Range.BaseShaderRegister = R.BaseShaderRegister; Range.BaseShaderRegister = R.BaseShaderRegister;
Range.RegisterSpace = R.RegisterSpace; Range.RegisterSpace = R.RegisterSpace;
@ -320,32 +328,37 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
Range.Flags = R.getEncodedFlags(); Range.Flags = R.getEncodedFlags();
Table.Ranges.push_back(Range); Table.Ranges.push_back(Range);
} }
RS.ParametersContainer.addParameter(Header, Table); RS.ParametersContainer.addParameter(Type, Visibility, Table);
break; break;
} }
default:
// Handling invalid parameter type edge case. We intentionally let
// obj2yaml/yaml2obj parse and emit invalid dxcontainer data, in order
// for that to be used as a testing tool more effectively.
RS.ParametersContainer.addInvalidParameter(Header);
} }
} }
for (const auto &Param : P.RootSignature->samplers()) { for (const auto &Param : P.RootSignature->samplers()) {
dxbc::RTS0::v1::StaticSampler NewSampler; assert(dxbc::isValidSamplerFilter(Param.Filter) &&
NewSampler.Filter = Param.Filter; dxbc::isValidAddress(Param.AddressU) &&
NewSampler.AddressU = Param.AddressU; dxbc::isValidAddress(Param.AddressV) &&
NewSampler.AddressV = Param.AddressV; dxbc::isValidAddress(Param.AddressW) &&
NewSampler.AddressW = Param.AddressW; dxbc::isValidComparisonFunc(Param.ComparisonFunc) &&
dxbc::isValidBorderColor(Param.BorderColor) &&
dxbc::isValidShaderVisibility(Param.ShaderVisibility) &&
"Invalid enum value in static sampler");
mcdxbc::StaticSampler NewSampler;
NewSampler.Filter = dxbc::SamplerFilter(Param.Filter);
NewSampler.AddressU = dxbc::TextureAddressMode(Param.AddressU);
NewSampler.AddressV = dxbc::TextureAddressMode(Param.AddressV);
NewSampler.AddressW = dxbc::TextureAddressMode(Param.AddressW);
NewSampler.MipLODBias = Param.MipLODBias; NewSampler.MipLODBias = Param.MipLODBias;
NewSampler.MaxAnisotropy = Param.MaxAnisotropy; NewSampler.MaxAnisotropy = Param.MaxAnisotropy;
NewSampler.ComparisonFunc = Param.ComparisonFunc; NewSampler.ComparisonFunc = dxbc::ComparisonFunc(Param.ComparisonFunc);
NewSampler.BorderColor = Param.BorderColor; NewSampler.BorderColor = dxbc::StaticBorderColor(Param.BorderColor);
NewSampler.MinLOD = Param.MinLOD; NewSampler.MinLOD = Param.MinLOD;
NewSampler.MaxLOD = Param.MaxLOD; NewSampler.MaxLOD = Param.MaxLOD;
NewSampler.ShaderRegister = Param.ShaderRegister; NewSampler.ShaderRegister = Param.ShaderRegister;
NewSampler.RegisterSpace = Param.RegisterSpace; NewSampler.RegisterSpace = Param.RegisterSpace;
NewSampler.ShaderVisibility = Param.ShaderVisibility; NewSampler.ShaderVisibility =
dxbc::ShaderVisibility(Param.ShaderVisibility);
RS.StaticSamplers.push_back(NewSampler); RS.StaticSamplers.push_back(NewSampler);
} }

View File

@ -164,15 +164,14 @@ static void validateRootSignature(Module &M,
for (const mcdxbc::RootParameterInfo &ParamInfo : RSD.ParametersContainer) { for (const mcdxbc::RootParameterInfo &ParamInfo : RSD.ParametersContainer) {
dxbc::ShaderVisibility ParamVisibility = dxbc::ShaderVisibility ParamVisibility =
static_cast<dxbc::ShaderVisibility>(ParamInfo.Header.ShaderVisibility); dxbc::ShaderVisibility(ParamInfo.Visibility);
if (ParamVisibility != dxbc::ShaderVisibility::All && if (ParamVisibility != dxbc::ShaderVisibility::All &&
ParamVisibility != Visibility) ParamVisibility != Visibility)
continue; continue;
dxbc::RootParameterType ParamType = dxbc::RootParameterType ParamType = dxbc::RootParameterType(ParamInfo.Type);
static_cast<dxbc::RootParameterType>(ParamInfo.Header.ParameterType);
switch (ParamType) { switch (ParamType) {
case dxbc::RootParameterType::Constants32Bit: { case dxbc::RootParameterType::Constants32Bit: {
dxbc::RTS0::v1::RootConstants Const = mcdxbc::RootConstants Const =
RSD.ParametersContainer.getConstant(ParamInfo.Location); RSD.ParametersContainer.getConstant(ParamInfo.Location);
Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace, Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
Const.ShaderRegister, Const.ShaderRegister, Const.ShaderRegister, Const.ShaderRegister,
@ -183,12 +182,11 @@ static void validateRootSignature(Module &M,
case dxbc::RootParameterType::SRV: case dxbc::RootParameterType::SRV:
case dxbc::RootParameterType::UAV: case dxbc::RootParameterType::UAV:
case dxbc::RootParameterType::CBV: { case dxbc::RootParameterType::CBV: {
dxbc::RTS0::v2::RootDescriptor Desc = mcdxbc::RootDescriptor Desc =
RSD.ParametersContainer.getRootDescriptor(ParamInfo.Location); RSD.ParametersContainer.getRootDescriptor(ParamInfo.Location);
Builder.trackBinding(toResourceClass(static_cast<dxbc::RootParameterType>( Builder.trackBinding(toResourceClass(ParamInfo.Type), Desc.RegisterSpace,
ParamInfo.Header.ParameterType)), Desc.ShaderRegister, Desc.ShaderRegister,
Desc.RegisterSpace, Desc.ShaderRegister, &ParamInfo);
Desc.ShaderRegister, &ParamInfo);
break; break;
} }
@ -196,7 +194,7 @@ static void validateRootSignature(Module &M,
const mcdxbc::DescriptorTable &Table = const mcdxbc::DescriptorTable &Table =
RSD.ParametersContainer.getDescriptorTable(ParamInfo.Location); RSD.ParametersContainer.getDescriptorTable(ParamInfo.Location);
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) { for (const mcdxbc::DescriptorRange &Range : Table.Ranges) {
uint32_t UpperBound = uint32_t UpperBound =
Range.NumDescriptors == ~0U Range.NumDescriptors == ~0U
? Range.BaseShaderRegister ? Range.BaseShaderRegister
@ -212,7 +210,7 @@ static void validateRootSignature(Module &M,
} }
} }
for (const dxbc::RTS0::v1::StaticSampler &S : RSD.StaticSamplers) for (const mcdxbc::StaticSampler &S : RSD.StaticSamplers)
Builder.trackBinding(dxil::ResourceClass::Sampler, S.RegisterSpace, Builder.trackBinding(dxil::ResourceClass::Sampler, S.RegisterSpace,
S.ShaderRegister, S.ShaderRegister, &S); S.ShaderRegister, S.ShaderRegister, &S);

View File

@ -27,6 +27,7 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <cstdint> #include <cstdint>
@ -171,27 +172,27 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
<< "RootParametersOffset: " << RS.RootParameterOffset << "\n" << "RootParametersOffset: " << RS.RootParameterOffset << "\n"
<< "NumParameters: " << RS.ParametersContainer.size() << "\n"; << "NumParameters: " << RS.ParametersContainer.size() << "\n";
for (size_t I = 0; I < RS.ParametersContainer.size(); I++) { for (size_t I = 0; I < RS.ParametersContainer.size(); I++) {
const auto &[Type, Loc] = const auto &Info = RS.ParametersContainer.getInfo(I);
RS.ParametersContainer.getTypeAndLocForParameter(I);
const dxbc::RTS0::v1::RootParameterHeader Header =
RS.ParametersContainer.getHeader(I);
OS << "- Parameter Type: " << Type << "\n" OS << "- Parameter Type: "
<< " Shader Visibility: " << Header.ShaderVisibility << "\n"; << enumToStringRef(Info.Type, dxbc::getRootParameterTypes()) << "\n"
<< " Shader Visibility: "
switch (Type) { << enumToStringRef(Info.Visibility, dxbc::getShaderVisibility())
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): { << "\n";
const dxbc::RTS0::v1::RootConstants &Constants = const uint32_t &Loc = Info.Location;
switch (Info.Type) {
case dxbc::RootParameterType::Constants32Bit: {
const mcdxbc::RootConstants &Constants =
RS.ParametersContainer.getConstant(Loc); RS.ParametersContainer.getConstant(Loc);
OS << " Register Space: " << Constants.RegisterSpace << "\n" OS << " Register Space: " << Constants.RegisterSpace << "\n"
<< " Shader Register: " << Constants.ShaderRegister << "\n" << " Shader Register: " << Constants.ShaderRegister << "\n"
<< " Num 32 Bit Values: " << Constants.Num32BitValues << "\n"; << " Num 32 Bit Values: " << Constants.Num32BitValues << "\n";
break; break;
} }
case llvm::to_underlying(dxbc::RootParameterType::CBV): case dxbc::RootParameterType::CBV:
case llvm::to_underlying(dxbc::RootParameterType::UAV): case dxbc::RootParameterType::UAV:
case llvm::to_underlying(dxbc::RootParameterType::SRV): { case dxbc::RootParameterType::SRV: {
const dxbc::RTS0::v2::RootDescriptor &Descriptor = const mcdxbc::RootDescriptor &Descriptor =
RS.ParametersContainer.getRootDescriptor(Loc); RS.ParametersContainer.getRootDescriptor(Loc);
OS << " Register Space: " << Descriptor.RegisterSpace << "\n" OS << " Register Space: " << Descriptor.RegisterSpace << "\n"
<< " Shader Register: " << Descriptor.ShaderRegister << "\n"; << " Shader Register: " << Descriptor.ShaderRegister << "\n";
@ -199,13 +200,16 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
OS << " Flags: " << Descriptor.Flags << "\n"; OS << " Flags: " << Descriptor.Flags << "\n";
break; break;
} }
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): { case dxbc::RootParameterType::DescriptorTable: {
const mcdxbc::DescriptorTable &Table = const mcdxbc::DescriptorTable &Table =
RS.ParametersContainer.getDescriptorTable(Loc); RS.ParametersContainer.getDescriptorTable(Loc);
OS << " NumRanges: " << Table.Ranges.size() << "\n"; OS << " NumRanges: " << Table.Ranges.size() << "\n";
for (const dxbc::RTS0::v2::DescriptorRange Range : Table) { for (const mcdxbc::DescriptorRange Range : Table) {
OS << " - Range Type: " << Range.RangeType << "\n" OS << " - Range Type: "
<< enumToStringRef(Range.RangeType,
dxbc::getDescriptorRangeTypes())
<< "\n"
<< " Register Space: " << Range.RegisterSpace << "\n" << " Register Space: " << Range.RegisterSpace << "\n"
<< " Base Shader Register: " << Range.BaseShaderRegister << "\n" << " Base Shader Register: " << Range.BaseShaderRegister << "\n"
<< " Num Descriptors: " << Range.NumDescriptors << "\n" << " Num Descriptors: " << Range.NumDescriptors << "\n"

View File

@ -1,20 +0,0 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s
target triple = "dxil-unknown-shadermodel6.0-compute"
; CHECK: error: Invalid Descriptor Range type
; CHECK-NOT: Root Signature Definitions
define void @main() #0 {
entry:
ret void
}
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
!6 = !{ !"Invalid", i32 1, i32 0, i32 -1, i32 -1, i32 4 }
!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }

View File

@ -25,26 +25,26 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
;CHECK-NEXT: Version: 2 ;CHECK-NEXT: Version: 2
;CHECK-NEXT: RootParametersOffset: 24 ;CHECK-NEXT: RootParametersOffset: 24
;CHECK-NEXT: NumParameters: 3 ;CHECK-NEXT: NumParameters: 3
;CHECK-NEXT: - Parameter Type: 1 ;CHECK-NEXT: - Parameter Type: Constants32Bit
;CHECK-NEXT: Shader Visibility: 0 ;CHECK-NEXT: Shader Visibility: All
;CHECK-NEXT: Register Space: 2 ;CHECK-NEXT: Register Space: 2
;CHECK-NEXT: Shader Register: 1 ;CHECK-NEXT: Shader Register: 1
;CHECK-NEXT: Num 32 Bit Values: 3 ;CHECK-NEXT: Num 32 Bit Values: 3
;CHECK-NEXT: - Parameter Type: 3 ;CHECK-NEXT: - Parameter Type: SRV
;CHECK-NEXT: Shader Visibility: 1 ;CHECK-NEXT: Shader Visibility: Vertex
;CHECK-NEXT: Register Space: 5 ;CHECK-NEXT: Register Space: 5
;CHECK-NEXT: Shader Register: 4 ;CHECK-NEXT: Shader Register: 4
;CHECK-NEXT: Flags: 4 ;CHECK-NEXT: Flags: 4
;CHECK-NEXT: - Parameter Type: 0 ;CHECK-NEXT: - Parameter Type: DescriptorTable
;CHECK-NEXT: Shader Visibility: 0 ;CHECK-NEXT: Shader Visibility: All
;CHECK-NEXT: NumRanges: 2 ;CHECK-NEXT: NumRanges: 2
;CHECK-NEXT: - Range Type: 0 ;CHECK-NEXT: - Range Type: SRV
;CHECK-NEXT: Register Space: 0 ;CHECK-NEXT: Register Space: 0
;CHECK-NEXT: Base Shader Register: 1 ;CHECK-NEXT: Base Shader Register: 1
;CHECK-NEXT: Num Descriptors: 1 ;CHECK-NEXT: Num Descriptors: 1
;CHECK-NEXT: Offset In Descriptors From Table Start: 4294967295 ;CHECK-NEXT: Offset In Descriptors From Table Start: 4294967295
;CHECK-NEXT: Flags: 4 ;CHECK-NEXT: Flags: 4
;CHECK-NEXT: - Range Type: 1 ;CHECK-NEXT: - Range Type: UAV
;CHECK-NEXT: Register Space: 10 ;CHECK-NEXT: Register Space: 10
;CHECK-NEXT: Base Shader Register: 1 ;CHECK-NEXT: Base Shader Register: 1
;CHECK-NEXT: Num Descriptors: 5 ;CHECK-NEXT: Num Descriptors: 5

View File

@ -1,29 +0,0 @@
# RUN: yaml2obj %s -o %t
# RUN: not obj2yaml 2>&1 %t | FileCheck %s -DFILE=%t
# CHECK: Error reading file: [[FILE]]: Invalid value for parameter type
--- !dxcontainer
Header:
Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
Version:
Major: 1
Minor: 0
PartCount: 1
PartOffsets: [ 60 ]
Parts:
- Name: RTS0
Size: 80
RootSignature:
Version: 2
NumRootParameters: 2
RootParametersOffset: 24
NumStaticSamplers: 0
StaticSamplersOffset: 64
Parameters:
- ParameterType: 255 # INVALID
ShaderVisibility: 2 # Hull
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true

View File

@ -1,33 +0,0 @@
# RUN: yaml2obj %s -o %t
# RUN: not obj2yaml 2>&1 %t | FileCheck %s -DFILE=%t
# CHECK: Error reading file: [[FILE]]: Invalid value for shader visibility
--- !dxcontainer
Header:
Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
Version:
Major: 1
Minor: 0
PartCount: 1
PartOffsets: [ 60 ]
Parts:
- Name: RTS0
Size: 80
RootSignature:
Version: 2
NumRootParameters: 2
RootParametersOffset: 24
NumStaticSamplers: 0
StaticSamplersOffset: 64
Parameters:
- ParameterType: 1 # Constants32Bit
ShaderVisibility: 255 # INVALID
Constants:
Num32BitValues: 21
ShaderRegister: 22
RegisterSpace: 23
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true

View File

@ -20,7 +20,7 @@ Parts:
StaticSamplersOffset: 24 StaticSamplersOffset: 24
Parameters: [] Parameters: []
Samplers: Samplers:
- Filter: 10 - Filter: 16
AddressU: 1 AddressU: 1
AddressV: 2 AddressV: 2
AddressW: 5 AddressW: 5
@ -46,7 +46,7 @@ Parts:
#CHECK-NEXT: StaticSamplersOffset: 24 #CHECK-NEXT: StaticSamplersOffset: 24
#CHECK-NEXT: Parameters: [] #CHECK-NEXT: Parameters: []
#CHECK-NEXT: Samplers: #CHECK-NEXT: Samplers:
#CHECK-NEXT: - Filter: 10 #CHECK-NEXT: - Filter: 16
#CHECK-NEXT: AddressU: 1 #CHECK-NEXT: AddressU: 1
#CHECK-NEXT: AddressV: 2 #CHECK-NEXT: AddressV: 2
#CHECK-NEXT: AddressW: 5 #CHECK-NEXT: AddressW: 5

View File

@ -492,7 +492,7 @@ Parts:
StaticSamplersOffset: 24 StaticSamplersOffset: 24
Parameters: [] Parameters: []
Samplers: Samplers:
- Filter: 10 - Filter: 16
AddressU: 1 AddressU: 1
AddressV: 2 AddressV: 2
AddressW: 5 AddressW: 5
@ -517,7 +517,7 @@ Parts:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,