diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp index 35a4ef322d01e..1db8f55a31658 100644 --- a/llvm/lib/MC/DXContainerRootSignature.cpp +++ b/llvm/lib/MC/DXContainerRootSignature.cpp @@ -12,44 +12,56 @@ using namespace llvm; using namespace llvm::mcdxbc; +static uint32_t writePlaceholder(raw_ostream &Stream) { + const uint32_t DummyValue = std::numeric_limits::max(); + uint32_t Offset = Stream.tell(); + support::endian::write(Stream, DummyValue, llvm::endianness::little); + return Offset; +} + +static void rewriteOffset(buffer_ostream &Stream, uint32_t Offset) { + uint32_t Value = + support::endian::byte_swap( + Stream.tell()); + Stream.pwrite(reinterpret_cast(&Value), sizeof(Value), Offset); +} + void RootSignatureDesc::write(raw_ostream &OS) const { - // Root signature header in dxcontainer has 6 uint_32t values. - const uint32_t HeaderSize = 24; - const uint32_t ParameterByteSize = Parameters.size_in_bytes(); - const uint32_t NumParametes = Parameters.size(); + buffer_ostream BOS(OS); + const uint32_t NumParameters = Parameters.size(); const uint32_t Zero = 0; - // Writing header information - support::endian::write(OS, Header.Version, llvm::endianness::little); - support::endian::write(OS, NumParametes, llvm::endianness::little); - support::endian::write(OS, HeaderSize, llvm::endianness::little); + support::endian::write(BOS, Header.Version, llvm::endianness::little); + support::endian::write(BOS, NumParameters, llvm::endianness::little); + + uint32_t HeaderPoint = writePlaceholder(BOS); - // Static samplers still not implemented - support::endian::write(OS, Zero, llvm::endianness::little); - support::endian::write(OS, ParameterByteSize + HeaderSize, - llvm::endianness::little); + support::endian::write(BOS, Zero, llvm::endianness::little); + support::endian::write(BOS, Zero, llvm::endianness::little); + support::endian::write(BOS, Header.Flags, llvm::endianness::little); - support::endian::write(OS, Header.Flags, llvm::endianness::little); + rewriteOffset(BOS, HeaderPoint); - uint32_t ParamsOffset = - HeaderSize + (3 * sizeof(uint32_t) * Parameters.size()); - for (const dxbc::RootParameter &P : Parameters) { - support::endian::write(OS, P.ParameterType, llvm::endianness::little); - support::endian::write(OS, P.ShaderVisibility, llvm::endianness::little); - support::endian::write(OS, ParamsOffset, llvm::endianness::little); + SmallVector ParamsOffsets; + for (const auto &P : Parameters) { + support::endian::write(BOS, P.ParameterType, llvm::endianness::little); + support::endian::write(BOS, P.ShaderVisibility, llvm::endianness::little); - // Size of root parameter, removing the ParameterType and ShaderVisibility. - ParamsOffset += sizeof(dxbc::RootParameter) - 2 * sizeof(uint32_t); + ParamsOffsets.push_back(writePlaceholder(BOS)); } - for (const dxbc::RootParameter &P : Parameters) { + assert(NumParameters == ParamsOffsets.size()); + for (size_t I = 0; I < NumParameters; ++I) { + rewriteOffset(BOS, ParamsOffsets[I]); + const auto &P = Parameters[I]; + switch (P.ParameterType) { case dxbc::RootParameterType::Constants32Bit: { - support::endian::write(OS, P.Constants.ShaderRegister, + support::endian::write(BOS, P.Constants.ShaderRegister, llvm::endianness::little); - support::endian::write(OS, P.Constants.RegisterSpace, + support::endian::write(BOS, P.Constants.RegisterSpace, llvm::endianness::little); - support::endian::write(OS, P.Constants.Num32BitValues, + support::endian::write(BOS, P.Constants.Num32BitValues, llvm::endianness::little); } break; case dxbc::RootParameterType::Empty: diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp index 010f70a952ebf..35261b661cf2f 100644 --- a/llvm/lib/Object/DXContainer.cpp +++ b/llvm/lib/Object/DXContainer.cpp @@ -296,16 +296,18 @@ Error DirectX::RootSignature::parse(StringRef Data) { NewParam.ParameterType = support::endian::read(Current); - if (!dxbc::RootSignatureValidations::isValidParameterType(NewParam.ParameterType)) + if (!dxbc::RootSignatureValidations::isValidParameterType( + NewParam.ParameterType)) return validationFailed("unsupported parameter type value read: " + llvm::Twine((uint32_t)NewParam.ParameterType)); Current += sizeof(dxbc::RootParameterType); NewParam.ShaderVisibility = - support::endian::read(Current); - if (!dxbc::RootSignatureValidations::isValidShaderVisibility(NewParam.ShaderVisibility)) + support::endian::read( + Current); + if (!dxbc::RootSignatureValidations::isValidShaderVisibility( + NewParam.ShaderVisibility)) return validationFailed("unsupported shader visility flag value read: " + llvm::Twine((uint32_t)NewParam.ShaderVisibility)); diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll index 035ea373d30ea..1ca6ebb7ddab8 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Flags.ll @@ -23,6 +23,6 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } ; DXC-NEXT: RootSignature: ; DXC-NEXT: Version: 2 ; DXC-NEXT: NumStaticSamplers: 0 -; DXC-NEXT: StaticSamplersOffset: 24 +; DXC-NEXT: StaticSamplersOffset: 0 ; DXC-NEXT: Parameters: [] ; DXC-NEXT: AllowInputAssemblerInputLayout: true diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml index 1b73b830f015f..0d7902afdaa66 100644 --- a/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml +++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-Flags.yaml @@ -25,7 +25,7 @@ Parts: # CHECK-NEXT: RootSignature: # CHECK-NEXT: Version: 2 # CHECK-NEXT: NumStaticSamplers: 0 -# CHECK-NEXT: StaticSamplersOffset: 24 +# CHECK-NEXT: StaticSamplersOffset: 0 # CHECK-NEXT: Parameters: [] # CHECK-NEXT: AllowInputAssemblerInputLayout: true # CHECK-NEXT: DenyGeometryShaderRootAccess: true diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml index bccfacb72819b..8d5ab5c1b0b23 100644 --- a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml +++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml @@ -37,7 +37,7 @@ Parts: # CHECK-NEXT: RootSignature: # CHECK-NEXT: Version: 2 # CHECK-NEXT: NumStaticSamplers: 0 -# CHECK-NEXT: StaticSamplersOffset: 64 +# CHECK-NEXT: StaticSamplersOffset: 0 # CHECK-NEXT: Parameters: # CHECK-NEXT: - ParameterType: Constants32Bit # CHECK-NEXT: ShaderVisibility: Hull diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp index b5fb8d143c0b9..fed941f685272 100644 --- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp +++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp @@ -134,12 +134,12 @@ TEST(RootSignature, ParseRootFlags) { )")); uint8_t Buffer[] = { - 0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, - 0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f, + 0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, }; EXPECT_EQ(Storage.size(), 68u); @@ -184,7 +184,7 @@ TEST(RootSignature, ParseRootConstants) { 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,