brintos

brintos / llvm-project-archived public Read only

0
0
Text · 50.9 KiB · d6f7b26 Raw
1252 lines · cpp
1//===- DXContainerTest.cpp - Tests for DXContainerFile --------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Object/DXContainer.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/BinaryFormat/Magic.h"12#include "llvm/ObjectYAML/DXContainerYAML.h"13#include "llvm/ObjectYAML/yaml2obj.h"14#include "llvm/Support/Error.h"15#include "llvm/Support/MemoryBufferRef.h"16#include "llvm/Testing/Support/Error.h"17#include "gtest/gtest.h"18 19using namespace llvm;20using namespace llvm::object;21 22template <std::size_t X> MemoryBufferRef getMemoryBuffer(uint8_t Data[X]) {23  StringRef Obj(reinterpret_cast<char *>(&Data[0]), X);24  return MemoryBufferRef(Obj, "");25}26 27TEST(DXCFile, IdentifyMagic) {28  {29    StringRef Buffer("DXBC");30    EXPECT_EQ(identify_magic(Buffer), file_magic::dxcontainer_object);31  }32  {33    StringRef Buffer("DXBCBlahBlahBlah");34    EXPECT_EQ(identify_magic(Buffer), file_magic::dxcontainer_object);35  }36}37 38TEST(DXCFile, ParseHeaderErrors) {39  uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43};40  EXPECT_THAT_EXPECTED(41      DXContainer::create(getMemoryBuffer<4>(Buffer)),42      FailedWithMessage("Reading structure out of file bounds"));43}44 45TEST(DXCFile, EmptyFile) {46  EXPECT_THAT_EXPECTED(47      DXContainer::create(MemoryBufferRef(StringRef("", 0), "")),48      FailedWithMessage("Reading structure out of file bounds"));49}50 51TEST(DXCFile, ParseHeader) {52  uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,53                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,54                      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,55                      0x70, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};56  DXContainer C =57      llvm::cantFail(DXContainer::create(getMemoryBuffer<32>(Buffer)));58  EXPECT_TRUE(memcmp(C.getHeader().Magic, "DXBC", 4) == 0);59  EXPECT_TRUE(memcmp(C.getHeader().FileHash.Digest,60                     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0);61  EXPECT_EQ(C.getHeader().Version.Major, 1u);62  EXPECT_EQ(C.getHeader().Version.Minor, 0u);63}64 65TEST(DXCFile, ParsePartMissingOffsets) {66  uint8_t Buffer[] = {67      0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,68      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,69      0x00, 0x00, 0x70, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,70  };71  EXPECT_THAT_EXPECTED(72      DXContainer::create(getMemoryBuffer<32>(Buffer)),73      FailedWithMessage("Reading structure out of file bounds"));74}75 76TEST(DXCFile, ParsePartInvalidOffsets) {77  // This test covers a case where the part offset is beyond the buffer size.78  uint8_t Buffer[] = {79      0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,80      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,81      0x70, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,82  };83  EXPECT_THAT_EXPECTED(84      DXContainer::create(getMemoryBuffer<36>(Buffer)),85      FailedWithMessage("Part offset points beyond boundary of the file"));86}87 88TEST(DXCFile, ParsePartTooSmallBuffer) {89  // This test covers a case where there is insufficent space to read a full90  // part name, but the offset for the part is inside the buffer.91  uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,92                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,93                      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,94                      0x26, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,95                      0x24, 0x00, 0x00, 0x00, 0x46, 0x4B};96  EXPECT_THAT_EXPECTED(97      DXContainer::create(getMemoryBuffer<38>(Buffer)),98      FailedWithMessage("File not large enough to read part name"));99}100 101TEST(DXCFile, ParsePartNoSize) {102  // This test covers a case where the part's header is readable, but the size103  // the part extends beyond the boundaries of the file.104  uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00,105                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,106                      0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x0D, 0x00,107                      0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,108                      0x46, 0x4B, 0x45, 0x30, 0x00, 0x00};109  EXPECT_THAT_EXPECTED(110      DXContainer::create(getMemoryBuffer<42>(Buffer)),111      FailedWithMessage("Reading part size out of file bounds"));112}113 114TEST(DXCFile, ParseOverlappingParts) {115  // This test covers a case where a part's offset is inside the size range116  // covered by the previous part.117  uint8_t Buffer[] = {118      0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,119      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,120      0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,121      0x2C, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x30, 0x08, 0x00, 0x00, 0x00,122      0x46, 0x4B, 0x45, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,123  };124  EXPECT_THAT_EXPECTED(125      DXContainer::create(getMemoryBuffer<60>(Buffer)),126      FailedWithMessage(127          "Part offset for part 1 begins before the previous part ends"));128}129 130TEST(DXCFile, ParseEmptyParts) {131  uint8_t Buffer[] = {132      0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,133      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,134      0x70, 0x0D, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,135      0x44, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,136      0x5C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,137      0x46, 0x4B, 0x45, 0x30, 0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x31,138      0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x32, 0x00, 0x00, 0x00, 0x00,139      0x46, 0x4B, 0x45, 0x33, 0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x34,140      0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x35, 0x00, 0x00, 0x00, 0x00,141      0x46, 0x4B, 0x45, 0x36, 0x00, 0x00, 0x00, 0x00,142  };143  DXContainer C =144      llvm::cantFail(DXContainer::create(getMemoryBuffer<116>(Buffer)));145  EXPECT_EQ(C.getHeader().PartCount, 7u);146 147  // All the part sizes are 0, which makes a nice test of the range based for148  int ElementsVisited = 0;149  for (auto Part : C) {150    EXPECT_EQ(Part.Part.Size, 0u);151    EXPECT_EQ(Part.Data.size(), 0u);152    ++ElementsVisited;153  }154  EXPECT_EQ(ElementsVisited, 7);155 156  {157    // These are all intended to be fake part names so that the parser doesn't158    // try to parse the part data.159    auto It = C.begin();160    EXPECT_TRUE(memcmp(It->Part.Name, "FKE0", 4) == 0);161    ++It;162    EXPECT_TRUE(memcmp(It->Part.Name, "FKE1", 4) == 0);163    ++It;164    EXPECT_TRUE(memcmp(It->Part.Name, "FKE2", 4) == 0);165    ++It;166    EXPECT_TRUE(memcmp(It->Part.Name, "FKE3", 4) == 0);167    ++It;168    EXPECT_TRUE(memcmp(It->Part.Name, "FKE4", 4) == 0);169    ++It;170    EXPECT_TRUE(memcmp(It->Part.Name, "FKE5", 4) == 0);171    ++It;172    EXPECT_TRUE(memcmp(It->Part.Name, "FKE6", 4) == 0);173    ++It; // Don't increment past the end174    EXPECT_TRUE(memcmp(It->Part.Name, "FKE6", 4) == 0);175  }176}177 178// This test verify DXIL part are correctly parsed.179// This test is based on the binary output constructed from this yaml.180// --- !dxcontainer181// Header:182//   Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,183//                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]184//   Version:185//     Major:           1186//     Minor:           0187//   PartCount:       1188// Parts:189//   - Name:            DXIL190//     Size:            28191//     Program:192//       MajorVersion:    6193//       MinorVersion:    5194//       ShaderKind:      5195//       Size:            8196//       DXILMajorVersion: 1197//       DXILMinorVersion: 5198//       DXILSize:        4199//       DXIL:            [ 0x42, 0x43, 0xC0, 0xDE, ]200// ...201TEST(DXCFile, ParseDXILPart) {202  uint8_t Buffer[] = {203      0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,204      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,205      0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,206      0x44, 0x58, 0x49, 0x4c, 0x1c, 0x00, 0x00, 0x00, 0x65, 0x00, 0x05, 0x00,207      0x08, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x05, 0x01, 0x00, 0x00,208      0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde};209  DXContainer C =210      llvm::cantFail(DXContainer::create(getMemoryBuffer<116>(Buffer)));211  EXPECT_EQ(C.getHeader().PartCount, 1u);212  const std::optional<object::DXContainer::DXILData> &DXIL = C.getDXIL();213  EXPECT_TRUE(DXIL.has_value());214  dxbc::ProgramHeader Header = DXIL->first;215  EXPECT_EQ(Header.getMajorVersion(), 6u);216  EXPECT_EQ(Header.getMinorVersion(), 5u);217  EXPECT_EQ(Header.ShaderKind, 5u);218  EXPECT_EQ(Header.Size, 8u);219  EXPECT_EQ(Header.Bitcode.MajorVersion, 1u);220  EXPECT_EQ(Header.Bitcode.MinorVersion, 5u);221}222 223static Expected<DXContainer>224generateDXContainer(StringRef Yaml, SmallVectorImpl<char> &BinaryData) {225  DXContainerYAML::Object Obj;226  SMDiagnostic GenerateDiag;227  yaml::Input YIn(228      Yaml, /*Ctxt=*/nullptr,229      [](const SMDiagnostic &Diag, void *DiagContext) {230        *static_cast<SMDiagnostic *>(DiagContext) = Diag;231      },232      &GenerateDiag);233 234  YIn >> Obj;235  if (YIn.error())236    return createStringError(YIn.error(), GenerateDiag.getMessage());237 238  raw_svector_ostream OS(BinaryData);239  std::string ErrorMsg;240  if (!yaml::yaml2dxcontainer(241          Obj, OS, [&ErrorMsg](const Twine &Msg) { ErrorMsg = Msg.str(); }))242    return createStringError(YIn.error(), ErrorMsg);243 244  MemoryBufferRef BinaryDataRef = MemoryBufferRef(OS.str(), "");245 246  return DXContainer::create(BinaryDataRef);247}248 249TEST(DXCFile, PSVResourceIterators) {250  const char *Yaml = R"(251--- !dxcontainer252Header:253  Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 254                     0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]255  Version:256    Major:           1257    Minor:           0258  PartCount:       2259Parts:260  - Name:            PSV0261    Size:            144262    PSVInfo:263      Version:         0264      ShaderStage:     14265      PayloadSizeInBytes: 4092266      MinimumWaveLaneCount: 0267      MaximumWaveLaneCount: 4294967295268      ResourceStride:  16269      Resources:270        - Type:            Sampler271          Space:           1272          LowerBound:      1273          UpperBound:      1274        - Type:            CBV275          Space:           2276          LowerBound:      2277          UpperBound:      2278        - Type:            SRVTyped279          Space:           3280          LowerBound:      3281          UpperBound:      3282  - Name:            DXIL283    Size:            24284    Program:285      MajorVersion:    6286      MinorVersion:    0287      ShaderKind:      14288      Size:            6289      DXILMajorVersion: 1290      DXILMinorVersion: 0291      DXILSize:        0292...293)";294 295  SmallVector<char, 256> BinaryData;296  auto C = generateDXContainer(Yaml, BinaryData);297 298  ASSERT_THAT_EXPECTED(C, Succeeded());299 300  const auto &PSVInfo = C->getPSVInfo();301  ASSERT_TRUE(PSVInfo.has_value());302 303  EXPECT_EQ(PSVInfo->getResourceCount(), 3u);304 305  auto It = PSVInfo->getResources().begin();306 307  EXPECT_TRUE(It == PSVInfo->getResources().begin());308 309  dxbc::PSV::v2::ResourceBindInfo Binding;310 311  Binding = *It;312  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);313  EXPECT_EQ(Binding.Flags, 0u);314 315  ++It;316  Binding = *It;317 318  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::CBV);319  EXPECT_EQ(Binding.Flags, 0u);320 321  --It;322  Binding = *It;323 324  EXPECT_TRUE(It == PSVInfo->getResources().begin());325 326  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);327  EXPECT_EQ(Binding.Flags, 0u);328 329  --It;330  Binding = *It;331 332  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);333  EXPECT_EQ(Binding.Flags, 0u);334 335  ++It;336  Binding = *It;337 338  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::CBV);339  EXPECT_EQ(Binding.Flags, 0u);340 341  ++It;342  Binding = *It;343 344  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVTyped);345  EXPECT_EQ(Binding.Flags, 0u);346 347  EXPECT_FALSE(It == PSVInfo->getResources().end());348 349  ++It;350  Binding = *It;351 352  EXPECT_TRUE(It == PSVInfo->getResources().end());353  EXPECT_FALSE(It != PSVInfo->getResources().end());354 355  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);356  EXPECT_EQ(Binding.Flags, 0u);357 358  {359    auto Old = It++;360    Binding = *Old;361 362    EXPECT_TRUE(Old == PSVInfo->getResources().end());363    EXPECT_FALSE(Old != PSVInfo->getResources().end());364 365    EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);366    EXPECT_EQ(Binding.Flags, 0u);367  }368 369  Binding = *It;370 371  EXPECT_TRUE(It == PSVInfo->getResources().end());372 373  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);374  EXPECT_EQ(Binding.Flags, 0u);375 376  {377    auto Old = It--;378    Binding = *Old;379    EXPECT_TRUE(Old == PSVInfo->getResources().end());380 381    EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);382    EXPECT_EQ(Binding.Flags, 0u);383  }384 385  Binding = *It;386 387  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVTyped);388  EXPECT_EQ(Binding.Flags, 0u);389}390 391// The malicious file bits in these tests are mutations of the binary produced392// by the following YAML:393//394// --- !dxcontainer395// Header:396//   Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,397//                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]398//   Version:399//     Major:           1400//     Minor:           0401//   PartCount:       3402// Parts:403//   - Name:            DXIL404//     Size:            24405//     Program:406//       MajorVersion:    6407//       MinorVersion:    0408//       ShaderKind:      14409//       Size:            6410//       DXILMajorVersion: 1411//       DXILMinorVersion: 0412//       DXILSize:        0413//   - Name:            PSV0414//     Size:            36415//     PSVInfo:416//       Version:         0417//       ShaderStage:     5418//       MinimumWaveLaneCount: 0419//       MaximumWaveLaneCount: 0420//       ResourceStride:       16421//       Resources: []422//   - Name: BLEH423//     Size: 16424// ...425 426TEST(DXCFile, MaliciousFiles) {427 428  // In this file blob, the file size is specified as 96 bytes (0x60), and the429  // PSV0 data is specified as 24 bytes (0x18) which extends beyond the size of430  // the file.431  {432    uint8_t Buffer[] = {433        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,434        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,435        0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,436        0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x18, 0x00, 0x00, 0x00,437        0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,438        0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,439        0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,440        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,441    };442    EXPECT_THAT_EXPECTED(443        DXContainer::create(getMemoryBuffer<96>(Buffer)),444        FailedWithMessage(445            "Pipeline state data extends beyond the bounds of the part"));446  }447 448  // PSV extends beyond part, but in file range. In this blob the file size is449  // 144 bytes (0x90), and the PSV part is 36 bytes (0x24), and the PSV data is450  // 40 bytes (0x40).451  {452    uint8_t Buffer[] = {453        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,454        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,455        0x90, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,456        0x4C, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,457        0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00,458        0x44, 0x58, 0x49, 0x4C, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,459        0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00,460        0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,461        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,462        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,463        0x42, 0x4C, 0x45, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,464        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,465    };466    EXPECT_THAT_EXPECTED(467        DXContainer::create(getMemoryBuffer<144>(Buffer)),468        FailedWithMessage(469            "Pipeline state data extends beyond the bounds of the part"));470  }471 472  // In this file blob, the file is 116 bytes (0x74). The file structure is473  // valid except that it specifies 1 16 byte resource binding which would474  // extend beyond the range of the part and file.475  {476    uint8_t Buffer[] = {477        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,478        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,479        0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,480        0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x18, 0x00, 0x00, 0x00,481        0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,482        0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,483        0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,484        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,485        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,486        0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,487    };488    EXPECT_THAT_EXPECTED(489        DXContainer::create(getMemoryBuffer<116>(Buffer)),490        FailedWithMessage(491            "Resource binding data extends beyond the bounds of the part"));492  }493 494  // In this file blob, the file is 116 bytes (0x74). The file structure is495  // valid except that it specifies 1 16 byte resource binding which would496  // extend beyond the range of the part and into the `BLEH` part.497  {498    uint8_t Buffer[] = {499        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,500        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,501        0x90, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,502        0x4C, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,503        0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00,504        0x44, 0x58, 0x49, 0x4C, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,505        0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00,506        0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,507        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,508        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,509        0x42, 0x4C, 0x45, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,510        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,511    };512    EXPECT_THAT_EXPECTED(513        DXContainer::create(getMemoryBuffer<144>(Buffer)),514        FailedWithMessage(515            "Resource binding data extends beyond the bounds of the part"));516  }517}518 519// This test verifies that the resource iterator follows the stride even if the520// stride doesn't match an expected or known value. In this test, the resource521// data is structured validly, with 32 bytes per resource. This test is based on522// editing the binary output constructed from this yaml.523//524// --- !dxcontainer525// Header:526//   Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,527//                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]528//   Version:529//     Major:           1530//     Minor:           0531//   PartCount:       2532// Parts:533//   - Name:            DXIL534//     Size:            24535//     Program:536//       MajorVersion:    6537//       MinorVersion:    0538//       ShaderKind:      14539//       Size:            6540//       DXILMajorVersion: 1541//       DXILMinorVersion: 0542//       DXILSize:        0543//   - Name:            PSV0544//     Size:            100545//     PSVInfo:546//       Version:         0547//       ShaderStage:     5548//       MinimumWaveLaneCount: 0549//       MaximumWaveLaneCount: 0550//       ResourceStride:       16551//       Resources:552//         - Type:            1553//           Space:           2554//           LowerBound:      3555//           UpperBound:      4556//         - Type:            5557//           Space:           6558//           LowerBound:      7559//           UpperBound:      8560// ...561TEST(DXCFile, PSVResourceIteratorsStride) {562  uint8_t Buffer[] = {563        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,564        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 565        0x28, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x18, 0x00, 0x00, 0x00,566        0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x00, 0x01, 0x00, 0x00,567        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x64, 0x00, 0x00, 0x00,568        0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,569        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,570        0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,571        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,572        0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,573        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,574        0x00, 0x00, 0x00, 0x00,575    }; 576    DXContainer C =577      llvm::cantFail(DXContainer::create(getMemoryBuffer<180>(Buffer)));578 579  const auto &PSVInfo = C.getPSVInfo();580  ASSERT_TRUE(PSVInfo.has_value());581 582  ASSERT_EQ(PSVInfo->getResourceCount(), 2u);583 584  auto It = PSVInfo->getResources().begin();585 586  EXPECT_TRUE(It == PSVInfo->getResources().begin());587 588  dxbc::PSV::v2::ResourceBindInfo Binding;589 590  Binding = *It;591  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);592  EXPECT_EQ(Binding.Space, 2u);593  EXPECT_EQ(Binding.LowerBound, 3u);594  EXPECT_EQ(Binding.UpperBound, 4u);595 596  ++It;597  Binding = *It;598 599  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVStructured);600  EXPECT_EQ(Binding.Space, 6u);601  EXPECT_EQ(Binding.LowerBound, 7u);602  EXPECT_EQ(Binding.UpperBound, 8u);603 604  --It;605  Binding = *It;606 607  EXPECT_TRUE(It == PSVInfo->getResources().begin());608 609  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);610  EXPECT_EQ(Binding.Space, 2u);611  EXPECT_EQ(Binding.LowerBound, 3u);612  EXPECT_EQ(Binding.UpperBound, 4u);613 614  --It;615  Binding = *It;616 617  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);618  EXPECT_EQ(Binding.Space, 2u);619  EXPECT_EQ(Binding.LowerBound, 3u);620  EXPECT_EQ(Binding.UpperBound, 4u);621 622  ++It;623  Binding = *It;624 625  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVStructured);626  EXPECT_EQ(Binding.Space, 6u);627  EXPECT_EQ(Binding.LowerBound, 7u);628  EXPECT_EQ(Binding.UpperBound, 8u);;629 630 631  EXPECT_FALSE(It == PSVInfo->getResources().end());632 633  ++It;634  Binding = *It;635 636  EXPECT_TRUE(It == PSVInfo->getResources().end());637  EXPECT_FALSE(It != PSVInfo->getResources().end());638 639  EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);640  EXPECT_EQ(Binding.Flags, 0u);641}642 643// This test binary is created using mutations of the yaml in the SigElements644// test found under test/ObjectYAML/DXContainer/SigElements.yaml.645 646TEST(DXCFile, MisalignedStringTable) {647  uint8_t Buffer[] = {648      0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,649      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,650      0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,651      0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x18, 0x00, 0x00, 0x00,652      0x60, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c,653      0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,654      0x50, 0x53, 0x56, 0x30, 0x68, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,655      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,656      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,657      0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x10, 0x20, 0x40,658      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,659      0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,660      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,661      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};662  EXPECT_THAT_EXPECTED(DXContainer::create(getMemoryBuffer<168>(Buffer)),663                       FailedWithMessage("String table misaligned"));664}665 666// This test binary is created using mutations of the yaml in the SigElements667// test found under test/ObjectYAML/DXContainer/SigElements.yaml.668TEST(DXCFile, SigElementsExtendBeyondPart) {669  uint8_t Buffer[] = {670      0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,671      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,672      0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,673      0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x18, 0x00, 0x00, 0x00,674      0x60, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c,675      0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,676      0x50, 0x53, 0x56, 0x30, 0x54, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,677      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,678      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,679      0x05, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x08, 0x10, 0x20, 0x40,680      0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x00,681      0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,682      0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,683      0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x03, 0x00};684  EXPECT_THAT_EXPECTED(685      DXContainer::create(getMemoryBuffer<164>(Buffer)),686      FailedWithMessage(687          "Signature elements extend beyond the size of the part"));688}689 690TEST(DXCFile, MalformedSignature) {691  /*692  The tests here exercise the DXContainer Signature section parser. These tests693  are based on modifying the binary described by the following yaml:694 695  --- !dxcontainer696  Header:697    Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,698                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]699    Version:700      Major:           1701      Minor:           0702    FileSize:        128703    PartCount:       1704    PartOffsets:     [ 64 ]705  Parts:706    - Name:            ISG1707      Size:            52708      Signature:709        Parameters:710          - Stream:          0711            Name:            AAA712            Index:           0713            SystemValue:     Undefined714            CompType:        Float32715            Register:        0716            Mask:            7717            ExclusiveMask:   2718            MinPrecision:    Default719  ...720 721  The unmodified hex sequence is:722 723  uint8_t Buffer[] = {724    0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,725  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80,726  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,727  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,728  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,729  0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08,730  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,731  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,732  0x00, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00,733  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00734  };735 736  */737 738  {739 740    // This binary says the signature has 10 parameters, but the part data is741    // only big enough for 1.742    uint8_t Buffer[] = {743        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,744        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,745        0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,746        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,747        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,748        0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,749        0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,750        0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,751        0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,752        0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,753        0x00, 0x00, 0x00, 0x00};754    EXPECT_THAT_EXPECTED(755        DXContainer::create(getMemoryBuffer<164>(Buffer)),756        FailedWithMessage(757            "Signature parameters extend beyond the part boundary"));758  }759 760  {761 762    // This binary only has one parameter, but the start offset is beyond the763    // size of the part.764    uint8_t Buffer[] = {765        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,766        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,767        0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,768        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,769        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,770        0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,771        0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,772        0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,773        0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,774        0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,775        0x00, 0x00, 0x00, 0x00};776    EXPECT_THAT_EXPECTED(777        DXContainer::create(getMemoryBuffer<164>(Buffer)),778        FailedWithMessage(779            "Signature parameters extend beyond the part boundary"));780  }781 782  {783 784    // This parameter has a name offset of 3, which is before the start of the785    // string table.786    uint8_t Buffer[] = {787        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,788        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,789        0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,790        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,791        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,792        0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,793        0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,794        0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,795        0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,796        0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,797        0x00, 0x00, 0x00, 0x00};798    EXPECT_THAT_EXPECTED(799        DXContainer::create(getMemoryBuffer<164>(Buffer)),800        FailedWithMessage("Invalid parameter name offset: name starts before "801                          "the first name offset"));802  }803 804  {805    // This parameter has a name offset of 255, which is after the end of the806    // part.807    uint8_t Buffer[] = {808        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,809        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,810        0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,811        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,812        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,813        0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,814        0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,815        0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,816        0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,817        0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,818        0x00, 0x00, 0x00, 0x00};819    EXPECT_THAT_EXPECTED(820        DXContainer::create(getMemoryBuffer<164>(Buffer)),821        FailedWithMessage("Invalid parameter name offset: name starts after "822                          "the end of the part data"));823  }824}825 826TEST(RootSignature, RootParameters) {827  {828    // Root Parameters offset has changed to 36, additional padding was added,829    // as well as fixing the parameter offset.830    uint8_t Buffer[] = {831        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,832        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,833        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,834        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,835        0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,836        0x2c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,837        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,838        0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,839        0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,840        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,841        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,842        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,843        0x00};844 845    DXContainer C =846        llvm::cantFail(DXContainer::create(getMemoryBuffer<144>(Buffer)));847 848    auto MaybeRS = C.getRootSignature();849    ASSERT_TRUE(MaybeRS.has_value());850    const auto &RS = MaybeRS.value();851    ASSERT_EQ(RS.getVersion(), 2u);852    ASSERT_EQ(RS.getNumParameters(), 1u);853    ASSERT_EQ(RS.getRootParametersOffset(), 36u);854    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);855    ASSERT_EQ(RS.getStaticSamplersOffset(), 44u);856    ASSERT_EQ(RS.getFlags(), 17u);857 858    auto RootParam = *RS.param_headers().begin();859    ASSERT_EQ((unsigned)RootParam.ParameterType, 1u);860    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 2u);861    auto ParamView = RS.getParameter(RootParam);862    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());863 864    DirectX::RootConstantView *RootConstantsView =865        dyn_cast<DirectX::RootConstantView>(&*ParamView);866    ASSERT_TRUE(RootConstantsView != nullptr);867    auto Constants = RootConstantsView->read();868 869    ASSERT_THAT_ERROR(Constants.takeError(), Succeeded());870 871    ASSERT_EQ(Constants->ShaderRegister, 15u);872    ASSERT_EQ(Constants->RegisterSpace, 14u);873    ASSERT_EQ(Constants->Num32BitValues, 16u);874  }875}876 877TEST(RootSignature, ParseRootFlags) {878  {879    uint8_t Buffer[] = {880        0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F,881        0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00, 0x00, 0x00,882        0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,883        0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,884        0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,885        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,886    };887    DXContainer C =888        llvm::cantFail(DXContainer::create(getMemoryBuffer<68>(Buffer)));889 890    const auto &RS = C.getRootSignature();891    ASSERT_TRUE(RS.has_value());892    ASSERT_EQ(RS->getVersion(), 2u);893    ASSERT_EQ(RS->getNumParameters(), 0u);894    ASSERT_EQ(RS->getRootParametersOffset(), 24u);895    ASSERT_EQ(RS->getNumStaticSamplers(), 0u);896    ASSERT_EQ(RS->getStaticSamplersOffset(), 0u);897    ASSERT_EQ(RS->getFlags(), 0x01u);898  }899  {900    // this parameter has the root signature definition missing some values.901    uint8_t Buffer[] = {902        0x44, 0x58, 0x42, 0x43, 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35,903        0x6F, 0x05, 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1, 0x01, 0x00,904        0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24,905        0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x18, 0x00, 0x00, 0x00,906        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,907        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,908    };909    EXPECT_THAT_EXPECTED(910        DXContainer::create(getMemoryBuffer<64>(Buffer)),911        FailedWithMessage(912            "Invalid root signature, insufficient space for header."));913  }914}915 916TEST(RootSignature, ParseRootConstant) {917  {918    uint8_t Buffer[] = {919        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,920        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,921        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,922        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,923        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,924        0x2c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,925        0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,926        0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,927        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,928        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,929        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,930        0x00};931    DXContainer C =932        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));933 934    auto MaybeRS = C.getRootSignature();935    ASSERT_TRUE(MaybeRS.has_value());936    const auto &RS = MaybeRS.value();937    ASSERT_EQ(RS.getVersion(), 2u);938    ASSERT_EQ(RS.getNumParameters(), 1u);939    ASSERT_EQ(RS.getRootParametersOffset(), 24u);940    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);941    ASSERT_EQ(RS.getStaticSamplersOffset(), 44u);942    ASSERT_EQ(RS.getFlags(), 17u);943 944    auto RootParam = *RS.param_headers().begin();945    ASSERT_EQ((unsigned)RootParam.ParameterType, 1u);946    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 2u);947    auto ParamView = RS.getParameter(RootParam);948    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());949 950    DirectX::RootConstantView *RootConstantsView =951        dyn_cast<DirectX::RootConstantView>(&*ParamView);952    ASSERT_TRUE(RootConstantsView != nullptr);953    auto Constants = RootConstantsView->read();954 955    ASSERT_THAT_ERROR(Constants.takeError(), Succeeded());956 957    ASSERT_EQ(Constants->ShaderRegister, 15u);958    ASSERT_EQ(Constants->RegisterSpace, 14u);959    ASSERT_EQ(Constants->Num32BitValues, 16u);960  }961}962 963TEST(RootSignature, ParseRootDescriptor) {964  {965    uint8_t Buffer[] = {966        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,967        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,968        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,969        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,970        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,971        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,972        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,973        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,974        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,975        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,976        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,977        0x00};978    DXContainer C =979        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));980 981    auto MaybeRS = C.getRootSignature();982    ASSERT_TRUE(MaybeRS.has_value());983    const auto &RS = MaybeRS.value();984    ASSERT_EQ(RS.getVersion(), 1u);985    ASSERT_EQ(RS.getNumParameters(), 1u);986    ASSERT_EQ(RS.getRootParametersOffset(), 24u);987    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);988    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);989    ASSERT_EQ(RS.getFlags(), 17u);990 991    auto RootParam = *RS.param_headers().begin();992    ASSERT_EQ((unsigned)RootParam.ParameterType, 2u);993    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);994    auto ParamView = RS.getParameter(RootParam);995    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());996 997    DirectX::RootDescriptorView *RootDescriptorView =998        dyn_cast<DirectX::RootDescriptorView>(&*ParamView);999    ASSERT_TRUE(RootDescriptorView != nullptr);1000    auto Descriptor = RootDescriptorView->read(RS.getVersion());1001 1002    ASSERT_THAT_ERROR(Descriptor.takeError(), Succeeded());1003 1004    ASSERT_EQ(Descriptor->ShaderRegister, 31u);1005    ASSERT_EQ(Descriptor->RegisterSpace, 32u);1006  }1007 1008  {1009    uint8_t Buffer[] = {1010        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,1011        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,1012        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,1013        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,1014        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1015        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,1016        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,1017        0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1018        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1019        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1020        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1021        0x00};1022    DXContainer C =1023        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));1024 1025    auto MaybeRS = C.getRootSignature();1026    ASSERT_TRUE(MaybeRS.has_value());1027    const auto &RS = MaybeRS.value();1028    ASSERT_EQ(RS.getVersion(), 2u);1029    ASSERT_EQ(RS.getNumParameters(), 1u);1030    ASSERT_EQ(RS.getRootParametersOffset(), 24u);1031    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);1032    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);1033    ASSERT_EQ(RS.getFlags(), 17u);1034 1035    auto RootParam = *RS.param_headers().begin();1036    ASSERT_EQ((unsigned)RootParam.ParameterType, 2u);1037    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);1038    auto ParamView = RS.getParameter(RootParam);1039    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());1040 1041    DirectX::RootDescriptorView *RootDescriptorView =1042        dyn_cast<DirectX::RootDescriptorView>(&*ParamView);1043    ASSERT_TRUE(RootDescriptorView != nullptr);1044    auto Descriptor = RootDescriptorView->read(RS.getVersion());1045 1046    ASSERT_THAT_ERROR(Descriptor.takeError(), Succeeded());1047 1048    ASSERT_EQ(Descriptor->ShaderRegister, 31u);1049    ASSERT_EQ(Descriptor->RegisterSpace, 32u);1050    ASSERT_EQ(Descriptor->Flags, 4u);1051  }1052}1053 1054TEST(RootSignature, ParseDescriptorTable) {1055  {1056    uint8_t Buffer[] = {1057        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,1058        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,1059        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,1060        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,1061        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1062        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1063        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1064        0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,1065        0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,1066        0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1067        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1068        0x00};1069    DXContainer C =1070        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));1071 1072    auto MaybeRS = C.getRootSignature();1073    ASSERT_TRUE(MaybeRS.has_value());1074    const auto &RS = MaybeRS.value();1075    ASSERT_EQ(RS.getVersion(), 2u);1076    ASSERT_EQ(RS.getNumParameters(), 1u);1077    ASSERT_EQ(RS.getRootParametersOffset(), 24u);1078    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);1079    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);1080    ASSERT_EQ(RS.getFlags(), 17u);1081 1082    auto RootParam = *RS.param_headers().begin();1083    ASSERT_EQ((unsigned)RootParam.ParameterType, 0u);1084    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);1085    auto ParamView = RS.getParameter(RootParam);1086    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());1087 1088    auto *DescriptorTableView =1089        dyn_cast<DirectX::DescriptorTableView>(&*ParamView);1090    ASSERT_TRUE(DescriptorTableView != nullptr);1091    auto Table = DescriptorTableView->read<dxbc::RTS0::v2::DescriptorRange>();1092 1093    ASSERT_THAT_ERROR(Table.takeError(), Succeeded());1094 1095    ASSERT_EQ(Table->NumRanges, 1u);1096 1097    auto Range = *Table->begin();1098 1099    ASSERT_EQ(Range.RangeType, 0u);1100    ASSERT_EQ(Range.NumDescriptors, -1u);1101    ASSERT_EQ(Range.BaseShaderRegister, 42u);1102    ASSERT_EQ(Range.RegisterSpace, 43u);1103    ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, 41u);1104    ASSERT_EQ(Range.Flags, 65536u);1105  }1106 1107  {1108    uint8_t Buffer[] = {1109        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,1110        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,1111        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,1112        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1113        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1114        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1115        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1116        0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,1117        0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,1118        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1119        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1120        0x00};1121    DXContainer C =1122        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));1123 1124    auto MaybeRS = C.getRootSignature();1125    ASSERT_TRUE(MaybeRS.has_value());1126    const auto &RS = MaybeRS.value();1127    ASSERT_EQ(RS.getVersion(), 1u);1128    ASSERT_EQ(RS.getNumParameters(), 1u);1129    ASSERT_EQ(RS.getRootParametersOffset(), 24u);1130    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);1131    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);1132    ASSERT_EQ(RS.getFlags(), 17u);1133 1134    auto RootParam = *RS.param_headers().begin();1135    ASSERT_EQ((unsigned)RootParam.ParameterType, 0u);1136    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);1137    auto ParamView = RS.getParameter(RootParam);1138    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());1139 1140    auto *DescriptorTableView =1141        dyn_cast<DirectX::DescriptorTableView>(&*ParamView);1142    ASSERT_TRUE(DescriptorTableView != nullptr);1143    auto Table = DescriptorTableView->read<dxbc::RTS0::v1::DescriptorRange>();1144 1145    ASSERT_THAT_ERROR(Table.takeError(), Succeeded());1146 1147    ASSERT_EQ(Table->NumRanges, 1u);1148 1149    auto Range = *Table->begin();1150 1151    ASSERT_EQ(Range.RangeType, 0u);1152    ASSERT_EQ(Range.NumDescriptors, -1u);1153    ASSERT_EQ(Range.BaseShaderRegister, 42u);1154    ASSERT_EQ(Range.RegisterSpace, 43u);1155    ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, 41u);1156  }1157}1158 1159TEST(RootSignature, ParseStaticSamplers) {1160  {1161    uint8_t Buffer[] = {1162        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1163        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1164        0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,1165        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1166        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1167        0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,1168        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1169        0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,1170        0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,1171        0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,1172        0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,1173        0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};1174    DXContainer C =1175        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));1176 1177    auto MaybeRS = C.getRootSignature();1178    ASSERT_TRUE(MaybeRS.has_value());1179    const auto &RS = MaybeRS.value();1180    ASSERT_EQ(RS.getVersion(), 2u);1181    ASSERT_EQ(RS.getNumParameters(), 0u);1182    ASSERT_EQ(RS.getRootParametersOffset(), 0u);1183    ASSERT_EQ(RS.getNumStaticSamplers(), 1u);1184    ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);1185    ASSERT_EQ(RS.getFlags(), 17u);1186 1187    auto Sampler = *RS.samplers().begin();1188 1189    ASSERT_EQ(Sampler.Filter, 10u);1190    ASSERT_EQ(Sampler.AddressU, 1u);1191    ASSERT_EQ(Sampler.AddressV, 2u);1192    ASSERT_EQ(Sampler.AddressW, 5u);1193    ASSERT_FLOAT_EQ(Sampler.MipLODBias, 1.23f);1194    ASSERT_EQ(Sampler.MaxAnisotropy, 20u);1195    ASSERT_EQ(Sampler.ComparisonFunc, 4u);1196    ASSERT_EQ(Sampler.BorderColor, 0u);1197    ASSERT_FLOAT_EQ(Sampler.MinLOD, 4.56f);1198    ASSERT_FLOAT_EQ(Sampler.MaxLOD, 8.9f);1199    ASSERT_EQ(Sampler.ShaderRegister, 31u);1200    ASSERT_EQ(Sampler.RegisterSpace, 32u);1201    ASSERT_EQ(Sampler.ShaderVisibility, 7u);1202  }1203  {1204    // this is testing static sampler parsing for root signature version 1.2,1205    // it changes: the version number, the size of root signature being emitted1206    // and the values for flag fields.1207    uint8_t Buffer[] = {1208        0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1209        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1210        0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,1211        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1212        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1213        0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,1214        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1215        0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,1216        0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,1217        0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,1218        0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,1219        0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,1220        0x01, 0x00, 0x00, 0x00};1221    DXContainer C =1222        llvm::cantFail(DXContainer::create(getMemoryBuffer<148>(Buffer)));1223 1224    auto MaybeRS = C.getRootSignature();1225    ASSERT_TRUE(MaybeRS.has_value());1226    const auto &RS = MaybeRS.value();1227    ASSERT_EQ(RS.getVersion(), 3U);1228    ASSERT_EQ(RS.getNumParameters(), 0U);1229    ASSERT_EQ(RS.getRootParametersOffset(), 0U);1230    ASSERT_EQ(RS.getNumStaticSamplers(), 1U);1231    ASSERT_EQ(RS.getStaticSamplersOffset(), 24U);1232    ASSERT_EQ(RS.getFlags(), 17U);1233 1234    auto Sampler = *RS.samplers().begin();1235 1236    ASSERT_EQ(Sampler.Filter, 10U);1237    ASSERT_EQ(Sampler.AddressU, 1U);1238    ASSERT_EQ(Sampler.AddressV, 2U);1239    ASSERT_EQ(Sampler.AddressW, 5U);1240    ASSERT_FLOAT_EQ(Sampler.MipLODBias, 1.23F);1241    ASSERT_EQ(Sampler.MaxAnisotropy, 20U);1242    ASSERT_EQ(Sampler.ComparisonFunc, 4U);1243    ASSERT_EQ(Sampler.BorderColor, 0U);1244    ASSERT_FLOAT_EQ(Sampler.MinLOD, 4.56F);1245    ASSERT_FLOAT_EQ(Sampler.MaxLOD, 8.9F);1246    ASSERT_EQ(Sampler.ShaderRegister, 31U);1247    ASSERT_EQ(Sampler.RegisterSpace, 32U);1248    ASSERT_EQ(Sampler.ShaderVisibility, 7U);1249    ASSERT_EQ(Sampler.Flags, 1U);1250  }1251}1252