|
10 | 10 | #include "llvm/BinaryFormat/DXContainer.h" |
11 | 11 | #include "llvm/Object/Error.h" |
12 | 12 | #include "llvm/Support/Alignment.h" |
| 13 | +#include "llvm/Support/Endian.h" |
13 | 14 | #include "llvm/Support/FormatVariadic.h" |
14 | 15 |
|
15 | 16 | using namespace llvm; |
@@ -92,6 +93,15 @@ Error DXContainer::parseHash(StringRef Part) { |
92 | 93 | return Error::success(); |
93 | 94 | } |
94 | 95 |
|
| 96 | +Error DXContainer::parseRootSignature(StringRef Part) { |
| 97 | + if (RootSignature) |
| 98 | + return parseFailed("More than one RTS0 part is present in the file"); |
| 99 | + RootSignature = DirectX::RootSignature(); |
| 100 | + if (Error Err = RootSignature->parse(Part)) |
| 101 | + return Err; |
| 102 | + return Error::success(); |
| 103 | +} |
| 104 | + |
95 | 105 | Error DXContainer::parsePSVInfo(StringRef Part) { |
96 | 106 | if (PSVInfo) |
97 | 107 | return parseFailed("More than one PSV0 part is present in the file"); |
@@ -193,6 +203,10 @@ Error DXContainer::parsePartOffsets() { |
193 | 203 | break; |
194 | 204 | case dxbc::PartType::Unknown: |
195 | 205 | break; |
| 206 | + case dxbc::PartType::RTS0: |
| 207 | + if (Error Err = parseRootSignature(PartData)) |
| 208 | + return Err; |
| 209 | + break; |
196 | 210 | } |
197 | 211 | } |
198 | 212 |
|
@@ -228,6 +242,53 @@ void DXContainer::PartIterator::updateIteratorImpl(const uint32_t Offset) { |
228 | 242 | IteratorState.Offset = Offset; |
229 | 243 | } |
230 | 244 |
|
| 245 | +Error DirectX::RootSignature::parse(StringRef Data) { |
| 246 | + const char *Current = Data.begin(); |
| 247 | + |
| 248 | + // Root Signature headers expects 6 integers to be present. |
| 249 | + if (Data.size() < 6 * sizeof(uint32_t)) |
| 250 | + return parseFailed( |
| 251 | + "Invalid root signature, insufficient space for header."); |
| 252 | + |
| 253 | + uint32_t VValue = |
| 254 | + support::endian::read<uint32_t, llvm::endianness::little>(Current); |
| 255 | + Current += sizeof(uint32_t); |
| 256 | + |
| 257 | + Expected<uint32_t> MaybeVersion = |
| 258 | + dxbc::RootSignatureValidations::validateVersion(VValue); |
| 259 | + if (Error E = MaybeVersion.takeError()) |
| 260 | + return E; |
| 261 | + Version = MaybeVersion.get(); |
| 262 | + |
| 263 | + NumParameters = |
| 264 | + support::endian::read<uint32_t, llvm::endianness::little>(Current); |
| 265 | + Current += sizeof(uint32_t); |
| 266 | + |
| 267 | + RootParametersOffset = |
| 268 | + support::endian::read<uint32_t, llvm::endianness::little>(Current); |
| 269 | + Current += sizeof(uint32_t); |
| 270 | + |
| 271 | + NumStaticSamplers = |
| 272 | + support::endian::read<uint32_t, llvm::endianness::little>(Current); |
| 273 | + Current += sizeof(uint32_t); |
| 274 | + |
| 275 | + StaticSamplersOffset = |
| 276 | + support::endian::read<uint32_t, llvm::endianness::little>(Current); |
| 277 | + Current += sizeof(uint32_t); |
| 278 | + |
| 279 | + uint32_t FValue = |
| 280 | + support::endian::read<uint32_t, llvm::endianness::little>(Current); |
| 281 | + Current += sizeof(uint32_t); |
| 282 | + |
| 283 | + Expected<uint32_t> MaybeFlag = |
| 284 | + dxbc::RootSignatureValidations::validateRootFlag(FValue); |
| 285 | + if (Error E = MaybeFlag.takeError()) |
| 286 | + return E; |
| 287 | + Flags = MaybeFlag.get(); |
| 288 | + |
| 289 | + return Error::success(); |
| 290 | +} |
| 291 | + |
231 | 292 | Error DirectX::PSVRuntimeInfo::parse(uint16_t ShaderKind) { |
232 | 293 | Triple::EnvironmentType ShaderStage = dxbc::getShaderStage(ShaderKind); |
233 | 294 |
|
|
0 commit comments