removing binaryformat dependency on mc

This commit is contained in:
Joao Saffran 2025-08-20 14:41:14 -07:00
parent 8c143ba0ce
commit e57236c70a
9 changed files with 140 additions and 139 deletions

View File

@ -241,6 +241,16 @@ enum class SamplerFilter : uint32_t {
#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();
#define TEXTURE_ADDRESS_MODE(Val, Enum) Enum = Val,
@ -250,6 +260,16 @@ enum class TextureAddressMode : uint32_t {
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,
enum class ComparisonFunc : uint32_t {
#include "DXContainerConstants.def"
@ -257,11 +277,31 @@ enum class ComparisonFunc : uint32_t {
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,
enum class StaticBorderColor : uint32_t {
#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 PartType parsePartType(StringRef S);

View File

@ -34,12 +34,8 @@ LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version,
dxbc::DescriptorRangeType Type,
uint32_t FlagsVal);
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 verifyMaxAnisotropy(uint32_t MaxAnisotropy);
LLVM_ABI bool verifyComparisonFunc(uint32_t ComparisonFunc);
LLVM_ABI bool verifyBorderColor(uint32_t BorderColor);
LLVM_ABI bool verifyLOD(float LOD);
} // namespace rootsig

View File

@ -60,6 +60,22 @@ struct DescriptorTable {
}
};
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 {
SmallVector<RootParameterInfo> ParametersInfo;
@ -125,7 +141,7 @@ struct RootSignatureDesc {
uint32_t StaticSamplersOffset = 0u;
uint32_t NumStaticSamplers = 0u;
mcdxbc::RootParametersContainer ParametersContainer;
SmallVector<dxbc::RTS0::v1::StaticSampler> StaticSamplers;
SmallVector<StaticSampler> StaticSamplers;
LLVM_ABI void write(raw_ostream &OS) const;

View File

@ -51,13 +51,13 @@ static std::optional<StringRef> extractMdStringValue(MDNode *Node,
return NodeText->getString();
}
static Expected<dxbc::ShaderVisibility>
extractShaderVisibility(MDNode *Node, unsigned int OpId) {
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 (!dxbc::isValidShaderVisibility(*Val))
return make_error<RootSignatureValidationError<uint32_t>>(
"ShaderVisibility", *Val);
return dxbc::ShaderVisibility(*Val);
if (!VerifyFn(*Val))
return make_error<RootSignatureValidationError<uint32_t>>(ErrText, *Val);
return static_cast<T>(*Val);
}
return make_error<InvalidRSMetadataValue>("ShaderVisibility");
}
@ -236,7 +236,9 @@ Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD,
return make_error<InvalidRSMetadataFormat>("RootConstants Element");
Expected<dxbc::ShaderVisibility> Visibility =
extractShaderVisibility(RootConstantNode, 1);
extractEnumValue<dxbc::ShaderVisibility>(RootConstantNode, 1,
"ShaderVisibility",
dxbc::isValidShaderVisibility);
if (auto E = Visibility.takeError())
return Error(std::move(E));
@ -290,7 +292,9 @@ Error MetadataParser::parseRootDescriptors(
}
Expected<dxbc::ShaderVisibility> Visibility =
extractShaderVisibility(RootDescriptorNode, 1);
extractEnumValue<dxbc::ShaderVisibility>(RootDescriptorNode, 1,
"ShaderVisibility",
dxbc::isValidShaderVisibility);
if (auto E = Visibility.takeError())
return Error(std::move(E));
@ -377,7 +381,9 @@ Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD,
return make_error<InvalidRSMetadataFormat>("Descriptor Table");
Expected<dxbc::ShaderVisibility> Visibility =
extractShaderVisibility(DescriptorTableNode, 1);
extractEnumValue<dxbc::ShaderVisibility>(DescriptorTableNode, 1,
"ShaderVisibility",
dxbc::isValidShaderVisibility);
if (auto E = Visibility.takeError())
return Error(std::move(E));
@ -403,26 +409,34 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
if (StaticSamplerNode->getNumOperands() != 14)
return make_error<InvalidRSMetadataFormat>("Static Sampler");
dxbc::RTS0::v1::StaticSampler Sampler;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 1))
Sampler.Filter = *Val;
else
return make_error<InvalidRSMetadataValue>("Filter");
mcdxbc::StaticSampler Sampler;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 2))
Sampler.AddressU = *Val;
else
return make_error<InvalidRSMetadataValue>("AddressU");
Expected<dxbc::SamplerFilter> Filter = extractEnumValue<dxbc::SamplerFilter>(
StaticSamplerNode, 1, "Filter", dxbc::isValidSamplerFilter);
if (auto E = Filter.takeError())
return Error(std::move(E));
Sampler.Filter = *Filter;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 3))
Sampler.AddressV = *Val;
else
return make_error<InvalidRSMetadataValue>("AddressV");
Expected<dxbc::TextureAddressMode> AddressU =
extractEnumValue<dxbc::TextureAddressMode>(
StaticSamplerNode, 2, "AddressU", dxbc::isValidAddress);
if (auto E = AddressU.takeError())
return Error(std::move(E));
Sampler.AddressU = *AddressU;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 4))
Sampler.AddressW = *Val;
else
return make_error<InvalidRSMetadataValue>("AddressW");
Expected<dxbc::TextureAddressMode> AddressV =
extractEnumValue<dxbc::TextureAddressMode>(
StaticSamplerNode, 3, "AddressV", dxbc::isValidAddress);
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))
Sampler.MipLODBias = *Val;
@ -434,15 +448,19 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
else
return make_error<InvalidRSMetadataValue>("MaxAnisotropy");
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 7))
Sampler.ComparisonFunc = *Val;
else
return make_error<InvalidRSMetadataValue>("ComparisonFunc");
Expected<dxbc::ComparisonFunc> ComparisonFunc =
extractEnumValue<dxbc::ComparisonFunc>(
StaticSamplerNode, 7, "ComparisonFunc", dxbc::isValidComparisonFunc);
if (auto E = ComparisonFunc.takeError())
return Error(std::move(E));
Sampler.ComparisonFunc = *ComparisonFunc;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 8))
Sampler.BorderColor = *Val;
else
return make_error<InvalidRSMetadataValue>("ComparisonFunc");
Expected<dxbc::StaticBorderColor> BorderColor =
extractEnumValue<dxbc::StaticBorderColor>(
StaticSamplerNode, 8, "BorderColor", dxbc::isValidBorderColor);
if (auto E = BorderColor.takeError())
return Error(std::move(E));
Sampler.BorderColor = *BorderColor;
if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 9))
Sampler.MinLOD = *Val;
@ -464,10 +482,13 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
else
return make_error<InvalidRSMetadataValue>("RegisterSpace");
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 13))
Sampler.ShaderVisibility = *Val;
else
return make_error<InvalidRSMetadataValue>("ShaderVisibility");
Expected<dxbc::ShaderVisibility> Visibility =
extractEnumValue<dxbc::ShaderVisibility>(StaticSamplerNode, 13,
"ShaderVisibility",
dxbc::isValidShaderVisibility);
if (auto E = Visibility.takeError())
return Error(std::move(E));
Sampler.ShaderVisibility = *Visibility;
RSD.StaticSamplers.push_back(Sampler);
return Error::success();
@ -591,30 +612,7 @@ Error MetadataParser::validateRootSignature(
}
}
for (const dxbc::RTS0::v1::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));
for (const mcdxbc::StaticSampler &Sampler : RSD.StaticSamplers) {
if (!hlsl::rootsig::verifyMipLODBias(Sampler.MipLODBias))
DeferredErrs = joinErrors(std::move(DeferredErrs),
@ -627,18 +625,6 @@ Error MetadataParser::validateRootSignature(
make_error<RootSignatureValidationError<uint32_t>>(
"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))
DeferredErrs = joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<float>>(
@ -660,12 +646,6 @@ Error MetadataParser::validateRootSignature(
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"RegisterSpace", Sampler.RegisterSpace));
if (!dxbc::isValidShaderVisibility(Sampler.ShaderVisibility))
DeferredErrs =
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"ShaderVisibility", Sampler.ShaderVisibility));
}
return DeferredErrs;

View File

@ -128,27 +128,6 @@ bool verifyNumDescriptors(uint32_t NumDescriptors) {
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) {
return MipLODBias >= -16.f && MipLODBias <= 15.99f;
}
@ -157,26 +136,6 @@ bool verifyMaxAnisotropy(uint32_t MaxAnisotropy) {
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); }
} // namespace rootsig

View File

@ -335,20 +335,30 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
}
for (const auto &Param : P.RootSignature->samplers()) {
dxbc::RTS0::v1::StaticSampler NewSampler;
NewSampler.Filter = Param.Filter;
NewSampler.AddressU = Param.AddressU;
NewSampler.AddressV = Param.AddressV;
NewSampler.AddressW = Param.AddressW;
assert(dxbc::isValidSamplerFilter(Param.Filter) &&
dxbc::isValidAddress(Param.AddressU) &&
dxbc::isValidAddress(Param.AddressV) &&
dxbc::isValidAddress(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.MaxAnisotropy = Param.MaxAnisotropy;
NewSampler.ComparisonFunc = Param.ComparisonFunc;
NewSampler.BorderColor = Param.BorderColor;
NewSampler.ComparisonFunc = dxbc::ComparisonFunc(Param.ComparisonFunc);
NewSampler.BorderColor = dxbc::StaticBorderColor(Param.BorderColor);
NewSampler.MinLOD = Param.MinLOD;
NewSampler.MaxLOD = Param.MaxLOD;
NewSampler.ShaderRegister = Param.ShaderRegister;
NewSampler.RegisterSpace = Param.RegisterSpace;
NewSampler.ShaderVisibility = Param.ShaderVisibility;
NewSampler.ShaderVisibility =
dxbc::ShaderVisibility(Param.ShaderVisibility);
RS.StaticSamplers.push_back(NewSampler);
}

View File

@ -210,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,
S.ShaderRegister, S.ShaderRegister, &S);

View File

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

View File

@ -492,7 +492,7 @@ Parts:
StaticSamplersOffset: 24
Parameters: []
Samplers:
- Filter: 10
- Filter: 16
AddressU: 1
AddressV: 2
AddressW: 5
@ -517,7 +517,7 @@ Parts:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
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,
0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,