[DX] Add support for PSV resource bindings
authorChris Bieneman <chris.bieneman@me.com>
Thu, 2 Feb 2023 19:11:34 +0000 (13:11 -0600)
committerChris Bieneman <chris.bieneman@me.com>
Thu, 2 Feb 2023 22:50:34 +0000 (16:50 -0600)
This patch continues implementing DirectX pipeline state validation
information by adding support for resource binding metadata.

Reviewed By: python3kgae

Differential Revision: https://reviews.llvm.org/D143130

34 files changed:
llvm/include/llvm/BinaryFormat/DXContainer.h
llvm/include/llvm/MC/DXContainerPSVInfo.h
llvm/include/llvm/Object/DXContainer.h
llvm/include/llvm/ObjectYAML/DXContainerYAML.h
llvm/lib/MC/DXContainerPSVInfo.cpp
llvm/lib/Object/DXContainer.cpp
llvm/lib/ObjectYAML/DXContainerEmitter.cpp
llvm/lib/ObjectYAML/DXContainerYAML.cpp
llvm/test/ObjectYAML/DXContainer/PSVv0-amplification.yaml
llvm/test/ObjectYAML/DXContainer/PSVv0-compute.yaml
llvm/test/ObjectYAML/DXContainer/PSVv0-domain.yaml
llvm/test/ObjectYAML/DXContainer/PSVv0-geometry.yaml
llvm/test/ObjectYAML/DXContainer/PSVv0-hull.yaml
llvm/test/ObjectYAML/DXContainer/PSVv0-mesh.yaml
llvm/test/ObjectYAML/DXContainer/PSVv0-pixel.yaml
llvm/test/ObjectYAML/DXContainer/PSVv0-vertex.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-amplification.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-compute.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-domain.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-geometry.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-hull.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-mesh.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-pixel.yaml
llvm/test/ObjectYAML/DXContainer/PSVv1-vertex.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-amplification.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-compute.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-domain.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-geometry.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-hull.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-mesh.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-pixel.yaml
llvm/test/ObjectYAML/DXContainer/PSVv2-vertex.yaml
llvm/tools/obj2yaml/dxcontainer2yaml.cpp
llvm/unittests/Object/DXContainerTest.cpp

index 9c975de..3436349 100644 (file)
@@ -288,6 +288,20 @@ struct RuntimeInfo {
   void swapBytes(Triple::EnvironmentType Stage) { StageInfo.swapBytes(Stage); }
 };
 
+struct ResourceBindInfo {
+  uint32_t Type;
+  uint32_t Space;
+  uint32_t LowerBound;
+  uint32_t UpperBound;
+
+  void swapBytes() {
+    sys::swapByteOrder(Type);
+    sys::swapByteOrder(Space);
+    sys::swapByteOrder(LowerBound);
+    sys::swapByteOrder(UpperBound);
+  }
+};
+
 } // namespace v0
 
 namespace v1 {
@@ -348,6 +362,16 @@ struct RuntimeInfo : public v1::RuntimeInfo {
   }
 };
 
+struct ResourceBindInfo : public v0::ResourceBindInfo {
+  uint32_t Kind;
+  uint32_t Flags;
+
+  void swapBytes() {
+    sys::swapByteOrder(Kind);
+    sys::swapByteOrder(Flags);
+  }
+};
+
 } // namespace v2
 } // namespace PSV
 
index b0c5c43..b630619 100644 (file)
@@ -29,6 +29,7 @@ namespace mcdxbc {
 // RuntimeInfo.
 struct PSVRuntimeInfo {
   dxbc::PSV::v2::RuntimeInfo BaseData;
+  std::vector<dxbc::PSV::v2::ResourceBindInfo> Resources;
 
   // Serialize PSVInfo into the provided raw_ostream. The version field
   // specifies the data version to encode, the default value specifies encoding
@@ -39,6 +40,8 @@ struct PSVRuntimeInfo {
   void swapBytes(Triple::EnvironmentType Stage) {
     BaseData.swapBytes();
     BaseData.swapBytes(Stage);
+    for (auto Res : Resources)
+      Res.swapBytes();
   }
 };
 
index 23f7503..9a496f6 100644 (file)
@@ -27,12 +27,84 @@ namespace object {
 
 namespace DirectX {
 class PSVRuntimeInfo {
+
+  // This class provides a view into the underlying resource array. The Resource
+  // data is little-endian encoded and may not be properly aligned to read
+  // directly from. The dereference operator creates a copy of the data and byte
+  // swaps it as appropriate.
+  struct ResourceArray {
+    StringRef Data;
+    size_t Stride; // size of each element in the list.
+
+    ResourceArray() = default;
+    ResourceArray(StringRef D, size_t S) : Data(D), Stride(S) {}
+
+    using value_type = dxbc::PSV::v2::ResourceBindInfo;
+
+    struct iterator {
+      StringRef Data;
+      size_t Stride; // size of each element in the list.
+      const char *Current;
+
+      iterator(const ResourceArray &A, const char *C)
+          : Data(A.Data), Stride(A.Stride), Current(C) {}
+      iterator(const iterator &) = default;
+
+      value_type operator*() {
+        // Explicitly zero the structure so that unused fields are zeroed. It is
+        // up to the user to know if the fields are used by verifying the PSV
+        // version.
+        value_type Val = {{0, 0, 0, 0}, 0, 0};
+        if (Current >= Data.end())
+          return Val;
+        memcpy(static_cast<void *>(&Val), Current, Stride);
+        if (sys::IsBigEndianHost)
+          Val.swapBytes();
+        return Val;
+      }
+
+      iterator operator++() {
+        if (Current < Data.end())
+          Current += Stride;
+        return *this;
+      }
+
+      iterator operator++(int) {
+        iterator Tmp = *this;
+        ++*this;
+        return Tmp;
+      }
+
+      iterator operator--() {
+        if (Current > Data.begin())
+          Current -= Stride;
+        return *this;
+      }
+
+      iterator operator--(int) {
+        iterator Tmp = *this;
+        --*this;
+        return Tmp;
+      }
+
+      bool operator==(const iterator I) { return I.Current == Current; }
+      bool operator!=(const iterator I) { return !(*this == I); }
+    };
+
+    iterator begin() const { return iterator(*this, Data.begin()); }
+
+    iterator end() const { return iterator(*this, Data.end()); }
+
+    size_t size() const { return Data.size() / Stride; }
+  };
+
   StringRef Data;
   uint32_t Size;
   using InfoStruct =
       std::variant<std::monostate, dxbc::PSV::v0::RuntimeInfo,
                    dxbc::PSV::v1::RuntimeInfo, dxbc::PSV::v2::RuntimeInfo>;
   InfoStruct BasicInfo;
+  ResourceArray Resources;
 
 public:
   PSVRuntimeInfo(StringRef D) : Data(D), Size(0) {}
@@ -41,6 +113,9 @@ public:
   Error parse(uint16_t ShaderKind);
 
   uint32_t getSize() const { return Size; }
+  uint32_t getResourceCount() const { return Resources.size(); }
+  ResourceArray getResources() const { return Resources; }
+
   uint32_t getVersion() const {
     return Size >= sizeof(dxbc::PSV::v2::RuntimeInfo)
                ? 2
index 6fc8ed8..299c8bf 100644 (file)
@@ -71,6 +71,8 @@ struct ShaderHash {
   std::vector<llvm::yaml::Hex8> Digest;
 };
 
+using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo;
+
 struct PSVInfo {
   // The version field isn't actually encoded in the file, but it is inferred by
   // the size of data regions. We include it in the yaml because it simplifies
@@ -78,6 +80,7 @@ struct PSVInfo {
   uint32_t Version;
 
   dxbc::PSV::v2::RuntimeInfo Info;
+  std::vector<ResourceBindInfo> Resources;
 
   void mapInfoForVersion(yaml::IO &IO);
 
@@ -107,6 +110,7 @@ struct Object {
 } // namespace llvm
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::Part)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo)
 namespace llvm {
 
 class raw_ostream;
@@ -145,6 +149,10 @@ template <> struct MappingTraits<DXContainerYAML::Object> {
   static void mapping(IO &IO, DXContainerYAML::Object &Obj);
 };
 
+template <> struct MappingTraits<DXContainerYAML::ResourceBindInfo> {
+  static void mapping(IO &IO, DXContainerYAML::ResourceBindInfo &Res);
+};
+
 } // namespace yaml
 
 } // namespace llvm
index 48a987e..a3444d0 100644 (file)
@@ -12,6 +12,7 @@
 
 using namespace llvm;
 using namespace llvm::mcdxbc;
+using namespace llvm::dxbc::PSV;
 
 void PSVRuntimeInfo::write(raw_ostream &OS, uint32_t Version) const {
   uint32_t InfoSize;
@@ -33,4 +34,14 @@ void PSVRuntimeInfo::write(raw_ostream &OS, uint32_t Version) const {
   OS.write(reinterpret_cast<const char *>(&InfoSizeSwapped), sizeof(uint32_t));
   // Write the info itself.
   OS.write(reinterpret_cast<const char *>(&BaseData), InfoSize);
+
+  uint32_t ResourceCount = static_cast<uint32_t>(Resources.size());
+  if (sys::IsBigEndianHost)
+    sys::swapByteOrder(ResourceCount);
+  OS.write(reinterpret_cast<const char *>(&ResourceCount), sizeof(uint32_t));
+
+  size_t BindingSize = (Version < 2) ? sizeof(v0::ResourceBindInfo)
+                                     : sizeof(v2::ResourceBindInfo);
+  for (const auto &Res : Resources)
+    OS.write(reinterpret_cast<const char *>(&Res), BindingSize);
 }
index 9c797a3..a0f0698 100644 (file)
@@ -229,5 +229,17 @@ Error DirectX::PSVRuntimeInfo::parse(uint16_t ShaderKind) {
   }
   Current += Size;
 
+  uint32_t ResourceCount = 0;
+  if (Error Err = readInteger(Data, Current, ResourceCount))
+    return Err;
+  Current += sizeof(uint32_t);
+
+  Resources.Stride = (PSVVersion < 2) ? sizeof(v0::ResourceBindInfo)
+                                      : sizeof(v2::ResourceBindInfo);
+  size_t BindingDataSize = Resources.Stride * ResourceCount;
+  Resources.Data = Data.substr(Current - Data.begin(), BindingDataSize);
+
+  Current += BindingDataSize;
+
   return Error::success();
 }
index 3e3e3e1..64b13fc 100644 (file)
@@ -199,6 +199,7 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
         continue;
       mcdxbc::PSVRuntimeInfo PSV;
       memcpy(&PSV.BaseData, &P.Info->Info, sizeof(dxbc::PSV::v2::RuntimeInfo));
+      PSV.Resources = P.Info->Resources;
 
       if (sys::IsBigEndianHost)
         PSV.swapBytes(static_cast<Triple::EnvironmentType>(
index 98615c5..741b0cb 100644 (file)
@@ -117,10 +117,20 @@ void MappingTraits<DXContainerYAML::PSVInfo>::mapping(
     IO &IO, DXContainerYAML::PSVInfo &PSV) {
   IO.mapRequired("Version", PSV.Version);
 
+  // Store the PSV version in the YAML context.
+  void *OldContext = IO.getContext();
+  uint32_t Version = PSV.Version;
+  IO.setContext(&Version);
+
   // Shader stage is only included in binaries for v1 and later, but we always
   // include it since it simplifies parsing and file construction.
   IO.mapRequired("ShaderStage", PSV.Info.ShaderStage);
   PSV.mapInfoForVersion(IO);
+
+  IO.mapRequired("Resources", PSV.Resources);
+
+  // Restore the YAML context.
+  IO.setContext(OldContext);
 }
 
 void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
@@ -140,6 +150,21 @@ void MappingTraits<DXContainerYAML::Object>::mapping(
   IO.mapRequired("Parts", Obj.Parts);
 }
 
+void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping(
+    IO &IO, DXContainerYAML::ResourceBindInfo &Res) {
+  IO.mapRequired("Type", Res.Type);
+  IO.mapRequired("Space", Res.Space);
+  IO.mapRequired("LowerBound", Res.LowerBound);
+  IO.mapRequired("UpperBound", Res.UpperBound);
+
+  const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext());
+  if (*PSVVersion < 2)
+    return;
+
+  IO.mapRequired("Kind", Res.Kind);
+  IO.mapRequired("Flags", Res.Flags);
+}
+
 } // namespace yaml
 
 void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) {
index 3ae3efb..4b9999f 100644 (file)
@@ -17,6 +17,15 @@ Parts:
       PayloadSizeInBytes: 4092
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -36,4 +45,13 @@ Parts:
 # CHECK-NEXT: PayloadSizeInBytes: 4092
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index bf21d40..84111d0 100644 (file)
@@ -16,6 +16,15 @@ Parts:
       ShaderStage:     5
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -34,4 +43,13 @@ Parts:
 # CHECK-NEXT: ShaderStage:     5
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index b034232..c5ca43a 100644 (file)
@@ -19,6 +19,15 @@ Parts:
       TessellatorDomain: 2056
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -40,4 +49,13 @@ Parts:
 # CHECK-NEXT: TessellatorDomain: 2056
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 87b6ba7..96e8b27 100644 (file)
@@ -20,6 +20,15 @@ Parts:
       OutputPositionPresent: 1
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -42,4 +51,13 @@ Parts:
 # CHECK-NEXT: OutputPositionPresent: 1
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 5d68a47..8113874 100644 (file)
@@ -20,6 +20,15 @@ Parts:
       TessellatorOutputPrimitive: 8192
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -42,4 +51,13 @@ Parts:
 # CHECK-NEXT: TessellatorOutputPrimitive: 8192
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 23822a0..4d8c6d4 100644 (file)
@@ -21,6 +21,15 @@ Parts:
       MaxOutputPrimitives: 4092
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -44,4 +53,13 @@ Parts:
 # CHECK-NEXT: MaxOutputPrimitives: 4092
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index b655b4f..c05471c 100644 (file)
@@ -18,6 +18,15 @@ Parts:
       SampleFrequency: 96
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -38,4 +47,13 @@ Parts:
 # CHECK-NEXT: SampleFrequency: 96
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 8c22a8f..fe176ad 100644 (file)
@@ -17,6 +17,15 @@ Parts:
       OutputPositionPresent: 1
       MinimumWaveLaneCount: 0
       MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -36,4 +45,13 @@ Parts:
 # CHECK-NEXT: OutputPositionPresent: 1
 # CHECK-NEXT: MinimumWaveLaneCount: 0
 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 7b0e1f5..310df02 100644 (file)
@@ -23,6 +23,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -48,4 +57,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 9c21808..d8233a7 100644 (file)
@@ -22,6 +22,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -46,4 +55,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 86e44d5..87826ed 100644 (file)
@@ -26,6 +26,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -54,4 +63,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 755959c..a081cde 100644 (file)
@@ -27,6 +27,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -56,4 +65,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 60fb396..4c5f60d 100644 (file)
@@ -27,6 +27,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -56,4 +65,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index e7b865c..c969620 100644 (file)
@@ -29,6 +29,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -60,4 +69,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index bd9364a..279fd09 100644 (file)
@@ -24,6 +24,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -50,4 +59,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 19e8e98..aa2a17a 100644 (file)
@@ -23,6 +23,15 @@ Parts:
       SigPatchConstOrPrimElements: 32
       SigInputVectors: 64
       SigOutputVectors: [ 8, 16, 32, 64 ]
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
   - Name:            DXIL
     Size:            24
     Program:
@@ -48,4 +57,13 @@ Parts:
 # CHECK-NEXT: SigPatchConstOrPrimElements: 32
 # CHECK-NEXT: SigInputVectors: 64
 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ]
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
 # CHECK-NEXT: Name
index 058ec0f..f2b431e 100644 (file)
@@ -26,6 +26,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -54,4 +67,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index 932da42..fd477b3 100644 (file)
@@ -25,6 +25,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -52,4 +65,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index 7258a82..f339a42 100644 (file)
@@ -29,6 +29,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -60,4 +73,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index c540257..09150dd 100644 (file)
@@ -30,6 +30,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -62,4 +75,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index 29760b4..9a07346 100644 (file)
@@ -30,6 +30,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -62,4 +75,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index 26441a7..d6e8be4 100644 (file)
@@ -32,6 +32,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -66,4 +79,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index 3a82bbe..841c1e9 100644 (file)
@@ -27,6 +27,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -56,4 +69,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index c0abacf..786cbc7 100644 (file)
@@ -26,6 +26,19 @@ Parts:
       NumThreadsX:     512
       NumThreadsY:     1024
       NumThreadsZ:     2048
+      Resources:
+        - Type:            1
+          Space:           2
+          LowerBound:      3
+          UpperBound:      4
+          Kind:            5
+          Flags:           6
+        - Type:            128
+          Space:           32768
+          LowerBound:      8388608
+          UpperBound:      2147483648
+          Kind:            65535
+          Flags:           16776960
   - Name:            DXIL
     Size:            24
     Program:
@@ -54,4 +67,17 @@ Parts:
 # CHECK-NEXT: NumThreadsX:     512
 # CHECK-NEXT: NumThreadsY:     1024
 # CHECK-NEXT: NumThreadsZ:     2048
+# CHECK-NEXT: Resources:
+# CHECK-NEXT: - Type:            1
+# CHECK-NEXT: Space:           2
+# CHECK-NEXT: LowerBound:      3
+# CHECK-NEXT: UpperBound:      4
+# CHECK-NEXT: Kind:            5
+# CHECK-NEXT: Flags:           6
+# CHECK-NEXT: - Type:            128
+# CHECK-NEXT: Space:           32768
+# CHECK-NEXT: LowerBound:      8388608
+# CHECK-NEXT: UpperBound:      2147483648
+# CHECK-NEXT: Kind:            65535
+# CHECK-NEXT: Flags:           16776960
 # CHECK-NEXT: Name
index 518f113..f33f565 100644 (file)
@@ -89,6 +89,8 @@ dumpDXContainer(MemoryBufferRef Source) {
       else if (const auto *P =
                    std::get_if<dxbc::PSV::v2::RuntimeInfo>(&PSVInfo->getInfo()))
         NewPart.Info = DXContainerYAML::PSVInfo(P);
+      for (auto Res : PSVInfo->getResources())
+        NewPart.Info->Resources.push_back(Res);
       break;
     }
     case dxbc::PartType::Unknown:
index ba04152..4d7daaf 100644 (file)
@@ -9,6 +9,8 @@
 #include "llvm/Object/DXContainer.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Magic.h"
+#include "llvm/ObjectYAML/DXContainerYAML.h"
+#include "llvm/ObjectYAML/yaml2obj.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
@@ -171,3 +173,170 @@ TEST(DXCFile, ParseEmptyParts) {
     EXPECT_TRUE(memcmp(It->Part.Name, "FKE6", 4) == 0);
   }
 }
+
+static Expected<DXContainer>
+generateDXContainer(StringRef Yaml, SmallVectorImpl<char> &BinaryData) {
+  DXContainerYAML::Object Obj;
+  SMDiagnostic GenerateDiag;
+  yaml::Input YIn(
+      Yaml, /*Ctxt=*/nullptr,
+      [](const SMDiagnostic &Diag, void *DiagContext) {
+        *static_cast<SMDiagnostic *>(DiagContext) = Diag;
+      },
+      &GenerateDiag);
+
+  YIn >> Obj;
+  if (YIn.error())
+    return createStringError(YIn.error(), GenerateDiag.getMessage());
+
+  raw_svector_ostream OS(BinaryData);
+  std::string ErrorMsg;
+  if (!yaml::yaml2dxcontainer(
+          Obj, OS, [&ErrorMsg](const Twine &Msg) { ErrorMsg = Msg.str(); }))
+    return createStringError(YIn.error(), ErrorMsg);
+
+  MemoryBufferRef BinaryDataRef = MemoryBufferRef(OS.str(), "");
+
+  return DXContainer::create(BinaryDataRef);
+}
+
+TEST(DXCFile, PSVResourceIterators) {
+  const char *Yaml = 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:       2
+Parts:
+  - Name:            PSV0
+    Size:            144
+    PSVInfo:
+      Version:         0
+      ShaderStage:     14
+      PayloadSizeInBytes: 4092
+      MinimumWaveLaneCount: 0
+      MaximumWaveLaneCount: 4294967295
+      Resources:
+        - Type:            1
+          Space:           1
+          LowerBound:      1
+          UpperBound:      1
+        - Type:            2
+          Space:           2
+          LowerBound:      2
+          UpperBound:      2
+        - Type:            3
+          Space:           3
+          LowerBound:      3
+          UpperBound:      3
+  - Name:            DXIL
+    Size:            24
+    Program:
+      MajorVersion:    6
+      MinorVersion:    0
+      ShaderKind:      14
+      Size:            6
+      DXILMajorVersion: 0
+      DXILMinorVersion: 1
+      DXILSize:        0
+...
+)";
+
+  SmallVector<char, 256> BinaryData;
+  auto C = generateDXContainer(Yaml, BinaryData);
+
+  ASSERT_THAT_EXPECTED(C, Succeeded());
+
+  const auto &PSVInfo = C->getPSVInfo();
+  ASSERT_TRUE(PSVInfo.has_value());
+
+  EXPECT_EQ(PSVInfo->getResourceCount(), 3u);
+
+  auto It = PSVInfo->getResources().begin();
+
+  EXPECT_TRUE(It == PSVInfo->getResources().begin());
+
+  dxbc::PSV::v2::ResourceBindInfo Binding;
+
+  Binding = *It;
+  EXPECT_EQ(Binding.Type, 1u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  ++It;
+  Binding = *It;
+
+  EXPECT_EQ(Binding.Type, 2u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  --It;
+  Binding = *It;
+
+  EXPECT_TRUE(It == PSVInfo->getResources().begin());
+
+  EXPECT_EQ(Binding.Type, 1u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  --It;
+  Binding = *It;
+
+  EXPECT_EQ(Binding.Type, 1u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  ++It;
+  Binding = *It;
+
+  EXPECT_EQ(Binding.Type, 2u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  ++It;
+  Binding = *It;
+
+  EXPECT_EQ(Binding.Type, 3u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  EXPECT_FALSE(It == PSVInfo->getResources().end());
+
+  ++It;
+  Binding = *It;
+
+  EXPECT_TRUE(It == PSVInfo->getResources().end());
+  EXPECT_FALSE(It != PSVInfo->getResources().end());
+
+  EXPECT_EQ(Binding.Type, 0u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  {
+    auto Old = It++;
+    Binding = *Old;
+
+    EXPECT_TRUE(Old == PSVInfo->getResources().end());
+    EXPECT_FALSE(Old != PSVInfo->getResources().end());
+
+    EXPECT_EQ(Binding.Type, 0u);
+    EXPECT_EQ(Binding.Flags, 0u);
+  }
+
+  Binding = *It;
+
+  EXPECT_TRUE(It == PSVInfo->getResources().end());
+
+  EXPECT_EQ(Binding.Type, 0u);
+  EXPECT_EQ(Binding.Flags, 0u);
+
+  {
+    auto Old = It--;
+    Binding = *Old;
+    EXPECT_TRUE(Old == PSVInfo->getResources().end());
+
+    EXPECT_EQ(Binding.Type, 0u);
+    EXPECT_EQ(Binding.Flags, 0u);
+  }
+  
+  Binding = *It;
+
+  EXPECT_EQ(Binding.Type, 3u);
+  EXPECT_EQ(Binding.Flags, 0u);
+}