[DirectX] Adding support for static samplers in yaml2obj/obj2yaml (#139963)

- Adds support for static samplers ins dxcontainer binary format.
- Adds writing logic to mcdxbc
- adds reading logic to Object
- adds tests
Closes: [126636](https://github.com/llvm/llvm-project/issues/126636)

---------

Co-authored-by: joaosaffran <joao.saffran@microsoft.com>
This commit is contained in:
joaosaffran 2025-05-29 14:02:15 -07:00 committed by GitHub
parent 572b89a1f4
commit c7cbaef1e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 459 additions and 1 deletions

View File

@ -209,6 +209,26 @@ inline bool isValidShaderVisibility(uint32_t V) {
return false;
}
#define STATIC_SAMPLER_FILTER(Val, Enum) Enum = Val,
enum class StaticSamplerFilter : uint32_t {
#include "DXContainerConstants.def"
};
#define TEXTURE_ADDRESS_MODE(Val, Enum) Enum = Val,
enum class TextureAddressMode : uint32_t {
#include "DXContainerConstants.def"
};
#define COMPARISON_FUNCTION(Val, Enum) Enum = Val,
enum class SamplersComparisonFunction : uint32_t {
#include "DXContainerConstants.def"
};
#define STATIC_BORDER_COLOR(Val, Enum) Enum = Val,
enum class SamplersBorderColor : uint32_t {
#include "DXContainerConstants.def"
};
PartType parsePartType(StringRef S);
struct VertexPSVInfo {
@ -600,6 +620,37 @@ static_assert(sizeof(ProgramSignatureElement) == 32,
namespace RTS0 {
namespace v1 {
struct StaticSampler {
uint32_t Filter;
uint32_t AddressU;
uint32_t AddressV;
uint32_t AddressW;
float MipLODBias;
uint32_t MaxAnisotropy;
uint32_t ComparisonFunc;
uint32_t BorderColor;
float MinLOD;
float MaxLOD;
uint32_t ShaderRegister;
uint32_t RegisterSpace;
uint32_t ShaderVisibility;
void swapBytes() {
sys::swapByteOrder(Filter);
sys::swapByteOrder(AddressU);
sys::swapByteOrder(AddressV);
sys::swapByteOrder(AddressW);
sys::swapByteOrder(MipLODBias);
sys::swapByteOrder(MaxAnisotropy);
sys::swapByteOrder(ComparisonFunc);
sys::swapByteOrder(BorderColor);
sys::swapByteOrder(MinLOD);
sys::swapByteOrder(MaxLOD);
sys::swapByteOrder(ShaderRegister);
sys::swapByteOrder(RegisterSpace);
sys::swapByteOrder(ShaderVisibility);
};
};
struct DescriptorRange {
uint32_t RangeType;
uint32_t NumDescriptors;

View File

@ -121,6 +121,79 @@ SHADER_VISIBILITY(7, Mesh)
#undef SHADER_VISIBILITY
#endif // SHADER_VISIBILITY
#ifdef STATIC_SAMPLER_FILTER
STATIC_SAMPLER_FILTER(0, MIN_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x1, MIN_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x4, MIN_POINT_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x5, MIN_POINT_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x10, MIN_LINEAR_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x11, MIN_LINEAR_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x14, MIN_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x15, MIN_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x55, ANISOTROPIC)
STATIC_SAMPLER_FILTER(0x80, COMPARISON_MIN_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x81, COMPARISON_MIN_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x84, COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x85, COMPARISON_MIN_POINT_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x90, COMPARISON_MIN_LINEAR_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x91, COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x94, COMPARISON_MIN_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x95, COMPARISON_MIN_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0xd5, COMPARISON_ANISOTROPIC)
STATIC_SAMPLER_FILTER(0x100, MINIMUM_MIN_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x101, MINIMUM_MIN_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x104, MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x105, MINIMUM_MIN_POINT_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x110, MINIMUM_MIN_LINEAR_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x111, MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x114, MINIMUM_MIN_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x115, MINIMUM_MIN_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x155, MINIMUM_ANISOTROPIC)
STATIC_SAMPLER_FILTER(0x180, MAXIMUM_MIN_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x181, MAXIMUM_MIN_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x184, MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x185, MAXIMUM_MIN_POINT_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x190, MAXIMUM_MIN_LINEAR_MAG_MIP_POINT)
STATIC_SAMPLER_FILTER(0x191, MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x194, MAXIMUM_MIN_MAG_LINEAR_MIP_POINT)
STATIC_SAMPLER_FILTER(0x195, MAXIMUM_MIN_MAG_MIP_LINEAR)
STATIC_SAMPLER_FILTER(0x1d5, MAXIMUM_ANISOTROPIC)
#undef STATIC_SAMPLER_FILTER
#endif // STATIC_SAMPLER_FILTER
#ifdef TEXTURE_ADDRESS_MODE
TEXTURE_ADDRESS_MODE( 1, Wrap)
TEXTURE_ADDRESS_MODE( 2, Mirror)
TEXTURE_ADDRESS_MODE( 3, Clamp)
TEXTURE_ADDRESS_MODE( 4, Border)
TEXTURE_ADDRESS_MODE( 5, MirrorOnce)
#undef TEXTURE_ADDRESS_MODE
#endif // TEXTURE_ADDRESS_MODE
#ifdef COMPARISON_FUNCTION
COMPARISON_FUNCTION( 1, Never)
COMPARISON_FUNCTION( 2, Less)
COMPARISON_FUNCTION( 3, Equal)
COMPARISON_FUNCTION( 4, LessEqual)
COMPARISON_FUNCTION( 5, Greater)
COMPARISON_FUNCTION( 6, NotEqual)
COMPARISON_FUNCTION( 7, GreaterEqual)
COMPARISON_FUNCTION( 8, Always)
#undef COMPARISON_FUNCTION
#endif // COMPARISON_FUNCTION
#ifdef STATIC_BORDER_COLOR
STATIC_BORDER_COLOR( 0, TransparentBlack)
STATIC_BORDER_COLOR( 1, OpaqueBlack)
STATIC_BORDER_COLOR( 2, OpaqueWhite)
STATIC_BORDER_COLOR( 3, OpaqueBlackUint)
STATIC_BORDER_COLOR( 4, OpaqueWhiteUint)
#undef STATIC_BORDER_COLOR
#endif // STATIC_BORDER_COLOR
#ifdef DXIL_MODULE_FLAG
// Only save DXIL module flags which not map to feature flags here.

View File

@ -108,6 +108,7 @@ struct RootSignatureDesc {
uint32_t StaticSamplersOffset = 0u;
uint32_t NumStaticSamplers = 0u;
mcdxbc::RootParametersContainer ParametersContainer;
SmallVector<dxbc::RTS0::v1::StaticSampler> StaticSamplers;
void write(raw_ostream &OS) const;

View File

@ -236,9 +236,11 @@ private:
uint32_t Flags;
ViewArray<dxbc::RTS0::v1::RootParameterHeader> ParametersHeaders;
StringRef PartData;
ViewArray<dxbc::RTS0::v1::StaticSampler> StaticSamplers;
using param_header_iterator =
ViewArray<dxbc::RTS0::v1::RootParameterHeader>::iterator;
using samplers_iterator = ViewArray<dxbc::RTS0::v1::StaticSampler>::iterator;
public:
RootSignature(StringRef PD) : PartData(PD) {}
@ -253,6 +255,9 @@ public:
llvm::iterator_range<param_header_iterator> param_headers() const {
return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
}
llvm::iterator_range<samplers_iterator> samplers() const {
return llvm::make_range(StaticSamplers.begin(), StaticSamplers.end());
}
uint32_t getFlags() const { return Flags; }
llvm::Expected<RootParameterView>

View File

@ -163,6 +163,24 @@ struct RootParameterYamlDesc {
}
};
struct StaticSamplerYamlDesc {
uint32_t Filter = llvm::to_underlying(dxbc::StaticSamplerFilter::ANISOTROPIC);
uint32_t AddressU = llvm::to_underlying(dxbc::TextureAddressMode::Wrap);
uint32_t AddressV = llvm::to_underlying(dxbc::TextureAddressMode::Wrap);
uint32_t AddressW = llvm::to_underlying(dxbc::TextureAddressMode::Wrap);
float MipLODBias = 0.f;
uint32_t MaxAnisotropy = 16u;
uint32_t ComparisonFunc =
llvm::to_underlying(dxbc::SamplersComparisonFunction::LessEqual);
uint32_t BorderColor =
llvm::to_underlying(dxbc::SamplersBorderColor::OpaqueWhite);
float MinLOD = 0.f;
float MaxLOD = std::numeric_limits<float>::max();
uint32_t ShaderRegister;
uint32_t RegisterSpace;
uint32_t ShaderVisibility;
};
struct RootSignatureYamlDesc {
RootSignatureYamlDesc() = default;
@ -173,9 +191,14 @@ struct RootSignatureYamlDesc {
uint32_t StaticSamplersOffset;
RootParameterYamlDesc Parameters;
SmallVector<StaticSamplerYamlDesc> StaticSamplers;
uint32_t getEncodedFlags();
iterator_range<StaticSamplerYamlDesc *> samplers() {
return make_range(StaticSamplers.begin(), StaticSamplers.end());
}
static llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
create(const object::DirectX::RootSignature &Data);
@ -288,6 +311,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::RootParameterLocationYaml)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::DescriptorRangeYaml)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::StaticSamplerYamlDesc)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode)
@ -384,6 +408,10 @@ template <> struct MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml> {
static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &D);
};
template <> struct MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc> {
static void mapping(IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S);
};
} // namespace yaml
} // namespace llvm

View File

@ -31,7 +31,8 @@ static void rewriteOffsetToCurrentByte(raw_svector_ostream &Stream,
size_t RootSignatureDesc::getSize() const {
size_t Size =
sizeof(dxbc::RTS0::v1::RootSignatureHeader) +
ParametersContainer.size() * sizeof(dxbc::RTS0::v1::RootParameterHeader);
ParametersContainer.size() * sizeof(dxbc::RTS0::v1::RootParameterHeader) +
StaticSamplers.size() * sizeof(dxbc::RTS0::v1::StaticSampler);
for (const RootParameterInfo &I : ParametersContainer) {
switch (I.Header.ParameterType) {
@ -141,6 +142,21 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
}
}
}
for (const auto &S : StaticSamplers) {
support::endian::write(BOS, S.Filter, llvm::endianness::little);
support::endian::write(BOS, S.AddressU, llvm::endianness::little);
support::endian::write(BOS, S.AddressV, llvm::endianness::little);
support::endian::write(BOS, S.AddressW, llvm::endianness::little);
support::endian::write(BOS, S.MipLODBias, llvm::endianness::little);
support::endian::write(BOS, S.MaxAnisotropy, llvm::endianness::little);
support::endian::write(BOS, S.ComparisonFunc, llvm::endianness::little);
support::endian::write(BOS, S.BorderColor, llvm::endianness::little);
support::endian::write(BOS, S.MinLOD, llvm::endianness::little);
support::endian::write(BOS, S.MaxLOD, llvm::endianness::little);
support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);
support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);
support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);
}
assert(Storage.size() == getSize());
OS.write(Storage.data(), Storage.size());
}

View File

@ -276,6 +276,11 @@ Error DirectX::RootSignature::parse() {
RootParametersOffset,
NumParameters * sizeof(dxbc::RTS0::v1::RootParameterHeader));
StaticSamplers.Stride = sizeof(dxbc::RTS0::v1::StaticSampler);
StaticSamplers.Data = PartData.substr(
StaticSamplersOffset,
NumStaticSamplers * sizeof(dxbc::RTS0::v1::StaticSampler));
return Error::success();
}

View File

@ -331,6 +331,25 @@ 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;
NewSampler.MipLODBias = Param.MipLODBias;
NewSampler.MaxAnisotropy = Param.MaxAnisotropy;
NewSampler.ComparisonFunc = Param.ComparisonFunc;
NewSampler.BorderColor = Param.BorderColor;
NewSampler.MinLOD = Param.MinLOD;
NewSampler.MaxLOD = Param.MaxLOD;
NewSampler.ShaderRegister = Param.ShaderRegister;
NewSampler.RegisterSpace = Param.RegisterSpace;
NewSampler.ShaderVisibility = Param.ShaderVisibility;
RS.StaticSamplers.push_back(NewSampler);
}
RS.write(OS);
break;
}

View File

@ -139,6 +139,26 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
}
}
for (const auto &S : Data.samplers()) {
StaticSamplerYamlDesc NewS;
NewS.Filter = S.Filter;
NewS.AddressU = S.AddressU;
NewS.AddressV = S.AddressV;
NewS.AddressW = S.AddressW;
NewS.MipLODBias = S.MipLODBias;
NewS.MaxAnisotropy = S.MaxAnisotropy;
NewS.ComparisonFunc = S.ComparisonFunc;
NewS.BorderColor = S.BorderColor;
NewS.MinLOD = S.MinLOD;
NewS.MaxLOD = S.MaxLOD;
NewS.ShaderRegister = S.ShaderRegister;
NewS.RegisterSpace = S.RegisterSpace;
NewS.ShaderVisibility = S.ShaderVisibility;
RootSigDesc.StaticSamplers.push_back(NewS);
}
#define ROOT_ELEMENT_FLAG(Num, Val) \
RootSigDesc.Val = \
(Flags & llvm::to_underlying(dxbc::RootElementFlag::Val)) > 0;
@ -340,6 +360,7 @@ void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
IO.mapRequired("NumStaticSamplers", S.NumStaticSamplers);
IO.mapRequired("StaticSamplersOffset", S.StaticSamplersOffset);
IO.mapRequired("Parameters", S.Parameters.Locations, S);
IO.mapOptional("Samplers", S.StaticSamplers);
#define ROOT_ELEMENT_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
@ -421,6 +442,24 @@ void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) {
IO.mapOptional("Filter", S.Filter);
IO.mapOptional("AddressU", S.AddressU);
IO.mapOptional("AddressV", S.AddressV);
IO.mapOptional("AddressW", S.AddressW);
IO.mapOptional("MipLODBias", S.MipLODBias);
IO.mapOptional("MaxAnisotropy", S.MaxAnisotropy);
IO.mapOptional("ComparisonFunc", S.ComparisonFunc);
IO.mapOptional("BorderColor", S.BorderColor);
IO.mapOptional("MinLOD", S.MinLOD);
IO.mapOptional("MaxLOD", S.MaxLOD);
IO.mapRequired("ShaderRegister", S.ShaderRegister);
IO.mapRequired("RegisterSpace", S.RegisterSpace);
IO.mapRequired("ShaderVisibility", S.ShaderVisibility);
}
void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
DXContainerYAML::Part &P) {
IO.mapRequired("Name", P.Name);

View File

@ -0,0 +1,53 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !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: 76
RootSignature:
Version: 2
NumRootParameters: 0
RootParametersOffset: 0
NumStaticSamplers: 1
StaticSamplersOffset: 24
Parameters: []
Samplers:
- ShaderRegister: 31
RegisterSpace: 32
ShaderVisibility: 7
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true
#CHECK: - Name: RTS0
#CHECK-NEXT: Size: 76
#CHECK-NEXT: RootSignature:
#CHECK-NEXT: Version: 2
#CHECK-NEXT: NumRootParameters: 0
#CHECK-NEXT: RootParametersOffset: 0
#CHECK-NEXT: NumStaticSamplers: 1
#CHECK-NEXT: StaticSamplersOffset: 24
#CHECK-NEXT: Parameters: []
#CHECK-NEXT: Samplers:
#CHECK-NEXT: - Filter: 85
#CHECK-NEXT: AddressU: 1
#CHECK-NEXT: AddressV: 1
#CHECK-NEXT: AddressW: 1
#CHECK-NEXT: MipLODBias: 0
#CHECK-NEXT: MaxAnisotropy: 16
#CHECK-NEXT: ComparisonFunc: 4
#CHECK-NEXT: BorderColor: 2
#CHECK-NEXT: MinLOD: 0
#CHECK-NEXT: MaxLOD: 3.40282e+38
#CHECK-NEXT: ShaderRegister: 31
#CHECK-NEXT: RegisterSpace: 32
#CHECK-NEXT: ShaderVisibility: 7
#CHECK-NEXT: AllowInputAssemblerInputLayout: true
#CHECK-NEXT: DenyGeometryShaderRootAccess: true

View File

@ -0,0 +1,63 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !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: 76
RootSignature:
Version: 2
NumRootParameters: 0
RootParametersOffset: 0
NumStaticSamplers: 1
StaticSamplersOffset: 24
Parameters: []
Samplers:
- Filter: 10
AddressU: 1
AddressV: 2
AddressW: 5
MipLODBias: 1.23
MaxAnisotropy: 20
ComparisonFunc: 4
BorderColor: 0
MinLOD: 4.56
MaxLOD: 8.90
ShaderRegister: 31
RegisterSpace: 32
ShaderVisibility: 7
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true
#CHECK: - Name: RTS0
#CHECK-NEXT: Size: 76
#CHECK-NEXT: RootSignature:
#CHECK-NEXT: Version: 2
#CHECK-NEXT: NumRootParameters: 0
#CHECK-NEXT: RootParametersOffset: 0
#CHECK-NEXT: NumStaticSamplers: 1
#CHECK-NEXT: StaticSamplersOffset: 24
#CHECK-NEXT: Parameters: []
#CHECK-NEXT: Samplers:
#CHECK-NEXT: - Filter: 10
#CHECK-NEXT: AddressU: 1
#CHECK-NEXT: AddressV: 2
#CHECK-NEXT: AddressW: 5
#CHECK-NEXT: MipLODBias: 1.23
#CHECK-NEXT: MaxAnisotropy: 20
#CHECK-NEXT: ComparisonFunc: 4
#CHECK-NEXT: BorderColor: 0
#CHECK-NEXT: MinLOD: 4.56
#CHECK-NEXT: MaxLOD: 8.9
#CHECK-NEXT: ShaderRegister: 31
#CHECK-NEXT: RegisterSpace: 32
#CHECK-NEXT: ShaderVisibility: 7
#CHECK-NEXT: AllowInputAssemblerInputLayout: true
#CHECK-NEXT: DenyGeometryShaderRootAccess: true

View File

@ -1155,3 +1155,49 @@ TEST(RootSignature, ParseDescriptorTable) {
ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, 41u);
}
}
TEST(RootSignature, ParseStaticSamplers) {
{
uint8_t Buffer[] = {
0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 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,
0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};
DXContainer C =
llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
auto MaybeRS = C.getRootSignature();
ASSERT_TRUE(MaybeRS.has_value());
const auto &RS = MaybeRS.value();
ASSERT_EQ(RS.getVersion(), 2u);
ASSERT_EQ(RS.getNumParameters(), 0u);
ASSERT_EQ(RS.getRootParametersOffset(), 0u);
ASSERT_EQ(RS.getNumStaticSamplers(), 1u);
ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);
ASSERT_EQ(RS.getFlags(), 17u);
auto Sampler = *RS.samplers().begin();
ASSERT_EQ(Sampler.Filter, 10u);
ASSERT_EQ(Sampler.AddressU, 1u);
ASSERT_EQ(Sampler.AddressV, 2u);
ASSERT_EQ(Sampler.AddressW, 5u);
ASSERT_FLOAT_EQ(Sampler.MipLODBias, 1.23);
ASSERT_EQ(Sampler.MaxAnisotropy, 20u);
ASSERT_EQ(Sampler.ComparisonFunc, 4u);
ASSERT_EQ(Sampler.BorderColor, 0u);
ASSERT_FLOAT_EQ(Sampler.MinLOD, 4.56);
ASSERT_FLOAT_EQ(Sampler.MaxLOD, 8.9);
ASSERT_EQ(Sampler.ShaderRegister, 31u);
ASSERT_EQ(Sampler.RegisterSpace, 32u);
ASSERT_EQ(Sampler.ShaderVisibility, 7u);
}
}

View File

@ -467,3 +467,62 @@ TEST(RootSignature, ParseDescriptorTableV11) {
EXPECT_EQ(Storage.size(), 133u);
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
}
TEST(RootSignature, ParseStaticSamplers) {
SmallString<128> Storage;
// First read a fully explicit yaml with all sizes and offsets provided
ASSERT_TRUE(convert(Storage, R"(--- !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: 76
RootSignature:
Version: 2
NumRootParameters: 0
RootParametersOffset: 0
NumStaticSamplers: 1
StaticSamplersOffset: 24
Parameters: []
Samplers:
- Filter: 10
AddressU: 1
AddressV: 2
AddressW: 5
MipLODBias: 1.23
MaxAnisotropy: 20
ComparisonFunc: 4
BorderColor: 0
MinLOD: 4.56
MaxLOD: 8.90
ShaderRegister: 31
RegisterSpace: 32
ShaderVisibility: 7
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true
)"));
uint8_t Buffer[] = {
0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 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,
0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};
EXPECT_EQ(Storage.size(), 144u);
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 144u) == 0);
}