ソースを参照

Merged PR 61: Implement DxilRuntimeRefleciton API for runtime

DxilRuntimeReflection uses RDATTableReader to obtain information about the library. InitFromRDAT call will allocate all memory required to get DXIL_LIBRARY_DESC.
Young Kim 7 年 前
コミット
33a8ad5130

+ 0 - 338
include/dxc/HLSL/DxilPipelineStateValidation.h

@@ -158,83 +158,6 @@ struct PSVResourceBindInfo0
   uint32_t UpperBound;
 };
 
-struct RuntimeDataResourceInfo
-{
-  uint32_t ResType;      // PSVResourceType
-  uint32_t Space;
-  uint32_t LowerBound;
-  uint32_t UpperBound;
-  uint32_t Kind;         // PSVResourceKind
-  uint32_t Name;         // offset for string table
-  uint32_t ID;           // id per resource class
-  uint32_t flags;        // flag for resource.
-};
-
-struct RuntimeDataFunctionInfo {
-  uint32_t Name;                 // offset for string table
-  uint32_t UnmangledName;        // offset for string table
-  uint32_t Resources;            // index to an index table
-  uint32_t FunctionDependencies; // index to a list of functions that function depends on
-  uint32_t ShaderKind;           // shader kind
-  uint32_t PayloadSizeInBytes;   // payload count for miss, closest hit, any hit
-                                 // shader, or parameter size for call shader
-  uint32_t AttributeSizeInBytes; // attribute size for closest hit and any hit
-  uint32_t FeatureInfo1;         // required feature info
-  uint32_t FeatureInfo2;         // required feature info
-  uint32_t ShaderStageFlag;      // valid shader stage flag
-  uint32_t MinShaderTarget;      // minimum shader target
-};
-
-// Index table is a sequence of rows, where each row has a count as a first
-// element followed by the count number of elements pre computing values
-struct IndexTableReader {
-private:
-  const uint32_t *m_table;
-  uint32_t m_size;
-
-public:
-  class IndexRow {
-  private:
-    const uint32_t *m_values;
-    const uint32_t m_count;
-  public:
-    IndexRow(const uint32_t *values, uint32_t count)
-      : m_values(values), m_count(count) {}
-    uint32_t Count() { return m_count; }
-    uint32_t At(uint32_t i) { return m_values[i]; }
-  };
-
-  IndexTableReader() : m_table(nullptr), m_size(0) {}
-  IndexTableReader(const uint32_t *table, uint32_t size)
-    : m_table(table), m_size(size) {}
-
-  void SetTable(const uint32_t *table) {
-    m_table = table;
-  }
-
-  void SetSize(uint32_t size) {
-    m_size = size;
-  }
-
-  IndexRow getRow(uint32_t i) {
-    return IndexRow(&m_table[i] + 1, m_table[i]);
-  }
-};
-
-struct RuntimeDataTableHeader {
-  uint32_t tableType; // DataTableType
-  uint32_t size;
-  uint32_t offset;
-};
-
-enum RuntimeDataPartType : uint32_t {
-  Invalid = 0,
-  String,
-  Function,
-  Resource,
-  Index
-};
-
 // Helpers for output dependencies (ViewID and Input-Output tables)
 struct PSVComponentMask {
   uint32_t *Mask;
@@ -413,267 +336,6 @@ struct PSVInitInfo
   uint8_t SigOutputVectors[4] = {0, 0, 0, 0};
 };
 
-struct ResourceTableReader;
-struct FunctionTableReader;
-
-struct RuntimeDataContext {
-  PSVStringTable *pStringTableReader;
-  IndexTableReader *pIndexTableReader;
-  ResourceTableReader *pResourceTableReader;
-  FunctionTableReader *pFunctionTableReader;
-};
-
-struct ResourceReader {
-private:
-  const RuntimeDataResourceInfo *m_ResourceInfo;
-  RuntimeDataContext *m_Context;
-public:
-  ResourceReader(const RuntimeDataResourceInfo *resInfo,
-                 RuntimeDataContext *context)
-      : m_ResourceInfo(resInfo), m_Context(context) {}
-  PSVResourceType GetResourceType() {
-    return (PSVResourceType)m_ResourceInfo->ResType;
-  }
-  uint32_t GetSpace() {
-    return m_ResourceInfo->Space;
-  }
-  uint32_t GetLowerBound() {
-    return m_ResourceInfo->LowerBound;
-  }
-  uint32_t GetUpperBound() {
-    return m_ResourceInfo->UpperBound;
-  }
-  PSVResourceKind GetResourceKind() { return (PSVResourceKind)m_ResourceInfo->Kind; }
-  uint32_t GetID() {
-    return m_ResourceInfo->ID;
-  }
-  const char *GetName() {
-    return m_Context->pStringTableReader->Get(m_ResourceInfo->Name);
-  }
-};
-
-struct ResourceTableReader {
-private:
-  const RuntimeDataResourceInfo *m_ResourceInfo; // pointer to an array of resource bind infos
-  RuntimeDataContext *m_Context;
-  uint32_t m_CBufferCount;
-  uint32_t m_SamplerCount;
-  uint32_t m_SRVCount;
-  uint32_t m_UAVCount;
-
-public:
-  ResourceTableReader()
-      : m_ResourceInfo(nullptr), m_Context(nullptr), m_CBufferCount(0),
-        m_SamplerCount(0), m_SRVCount(0), m_UAVCount(0){};
-  ResourceTableReader(const RuntimeDataResourceInfo *info1,
-                      RuntimeDataContext *context, uint32_t CBufferCount,
-                      uint32_t SamplerCount, uint32_t SRVCount,
-                      uint32_t UAVCount)
-      : m_ResourceInfo(info1), m_Context(context),
-        m_CBufferCount(CBufferCount), m_SamplerCount(SamplerCount),
-        m_SRVCount(SRVCount), m_UAVCount(UAVCount){};
-
-  void SetResourceInfo(const RuntimeDataResourceInfo *ptr, uint32_t count) { 
-    m_ResourceInfo = ptr;
-    // Assuming that resources are in order of CBuffer, Sampler, SRV, and UAV,
-    // count the number for each resource class
-    m_CBufferCount = 0;
-    m_SamplerCount = 0;
-    m_SRVCount = 0;
-    m_UAVCount = 0;
-
-    for (uint32_t i = 0; i < count; ++i) {
-      const RuntimeDataResourceInfo *curPtr = &ptr[i];
-      if (curPtr->ResType == (uint32_t)PSVResourceType::CBV)
-        m_CBufferCount++;
-      else if (curPtr->ResType == (uint32_t)PSVResourceType::Sampler)
-        m_SamplerCount++;
-      else if (curPtr->ResType == (uint32_t)PSVResourceType::SRVRaw ||
-          curPtr->ResType == (uint32_t)PSVResourceType::SRVStructured ||
-          curPtr->ResType == (uint32_t)PSVResourceType::SRVTyped)
-        m_SRVCount++;
-      else if (curPtr->ResType == (uint32_t)PSVResourceType::UAVRaw ||
-          curPtr->ResType == (uint32_t)PSVResourceType::UAVStructured ||
-          curPtr->ResType == (uint32_t)PSVResourceType::UAVStructuredWithCounter ||
-          curPtr->ResType == (uint32_t)PSVResourceType::UAVTyped)
-        m_UAVCount++;
-    }
-  }
-
-  void SetContext(RuntimeDataContext *context) { m_Context = context; }
-
-  uint32_t GetNumResources() {
-    return m_CBufferCount + m_SamplerCount + m_SRVCount + m_UAVCount;
-  }
-  ResourceReader GetItem(uint32_t i) {
-    _Analysis_assume_(i < GetNumResources());
-    return ResourceReader(&m_ResourceInfo[i], m_Context);
-  }
-
-  uint32_t GetNumCBuffers() { return m_CBufferCount; }
-  ResourceReader GetCBuffer(uint32_t i) {
-    _Analysis_assume_(i < m_CBufferCount);
-    return ResourceReader(&m_ResourceInfo[i], m_Context);
-  }
-
-  uint32_t GetNumSamplers() { return m_SamplerCount; }
-  ResourceReader GetSampler(uint32_t i) {
-    _Analysis_assume_(i < m_SamplerCount);
-    uint32_t offset = (m_CBufferCount + i);
-    return ResourceReader(&m_ResourceInfo[offset], m_Context);
-  }
-
-  uint32_t GetNumSRVs() { return m_SRVCount; }
-  ResourceReader GetSRV(uint32_t i) {
-    _Analysis_assume_(i < m_SRVCount);
-    uint32_t offset = (m_CBufferCount + m_SamplerCount + i);
-    return ResourceReader(&m_ResourceInfo[offset], m_Context);
-  }
-
-  uint32_t GetNumUAVs() { return m_UAVCount; }
-  ResourceReader GetUAV(uint32_t i) {
-    _Analysis_assume_(i < m_UAVCount);
-    uint32_t offset = (m_CBufferCount + m_SamplerCount + m_SRVCount + i);
-    return ResourceReader(&m_ResourceInfo[offset], m_Context);
-  }
-};
-
-struct FunctionReader {
-private:
-  const RuntimeDataFunctionInfo *m_RuntimeDataFunctionInfo;
-  RuntimeDataContext *m_Context;
-public:
-  FunctionReader() : m_RuntimeDataFunctionInfo(nullptr), m_Context(nullptr){}
-  FunctionReader(const RuntimeDataFunctionInfo *functionInfo,
-                 RuntimeDataContext *context)
-      : m_RuntimeDataFunctionInfo(functionInfo), m_Context(context){}
-
-  const char *GetName() { return m_Context->pStringTableReader->Get(m_RuntimeDataFunctionInfo->Name); }
-  const char *GetUnmangledName() {
-    return m_Context->pStringTableReader->Get(
-        m_RuntimeDataFunctionInfo->UnmangledName);
-  }
-  uint64_t GetFeatureFlag() {
-    uint64_t flag = static_cast<uint64_t>(m_RuntimeDataFunctionInfo->FeatureInfo2) << 32;
-    flag |= static_cast<uint64_t>(m_RuntimeDataFunctionInfo->FeatureInfo1);
-    return flag;
-  }
-  uint32_t GetShaderStageFlag() { return m_RuntimeDataFunctionInfo->ShaderStageFlag; }
-  uint32_t GetMinShaderTarget() { return m_RuntimeDataFunctionInfo->MinShaderTarget; }
-  uint32_t GetNumResources() {
-    if (m_RuntimeDataFunctionInfo->Resources == UINT_MAX)
-      return 0;
-    return m_Context->pIndexTableReader->getRow(m_RuntimeDataFunctionInfo->Resources).Count();
-  }
-  ResourceReader GetResource(uint32_t i) {
-    uint32_t resIndex = m_Context->pIndexTableReader->getRow(m_RuntimeDataFunctionInfo->Resources).At(i);
-    return m_Context->pResourceTableReader->GetItem(resIndex);
-  }
-
-  uint32_t GetNumDependencies() {
-    if (m_RuntimeDataFunctionInfo->FunctionDependencies == UINT_MAX)
-      return 0;
-    return m_Context->pIndexTableReader
-        ->getRow(m_RuntimeDataFunctionInfo->FunctionDependencies).Count();
-  }
-
-  const char *GetDependency(uint32_t i) {
-    uint32_t resIndex =
-        m_Context->pIndexTableReader
-            ->getRow(m_RuntimeDataFunctionInfo->FunctionDependencies).At(i);
-    return m_Context->pStringTableReader->Get(resIndex);
-  }
-
-  uint32_t GetPayloadSizeInBytes() { return m_RuntimeDataFunctionInfo->PayloadSizeInBytes; }
-  uint32_t GetAttributeSizeInBytes() { return m_RuntimeDataFunctionInfo->AttributeSizeInBytes; }
-  // payload (hit shaders) and parameters (call shaders) are mutually exclusive
-  uint32_t GetParameterSizeInBytes() { return m_RuntimeDataFunctionInfo->PayloadSizeInBytes; }
-  PSVShaderKind GetShaderKind() { return (PSVShaderKind) m_RuntimeDataFunctionInfo->ShaderKind; }
-};
-
-struct FunctionTableReader {
-private:
-  const RuntimeDataFunctionInfo *m_infos;
-  uint32_t m_count;
-  RuntimeDataContext *m_context;
-public:
-  FunctionTableReader() : m_infos(nullptr), m_count(0), m_context(nullptr) {}
-  FunctionTableReader(const RuntimeDataFunctionInfo *functionInfos,
-                      uint32_t count, RuntimeDataContext *context)
-      : m_infos(functionInfos), m_count(count), m_context(context) {}
-
-  FunctionReader GetItem(uint32_t i) {
-    return FunctionReader(&m_infos[i], m_context);
-  }
-  uint32_t GetNumFunctions() { return m_count; }
-
-  void SetFunctionInfo(const RuntimeDataFunctionInfo *ptr) { m_infos = ptr; }
-  void SetCount(uint32_t count) { m_count = count; }
-  void SetContext(RuntimeDataContext *context) { m_context = context; }
-};
-
-class DxilRuntimeData {
-private:
-  uint32_t m_TableCount;
-  PSVStringTable m_StringReader;
-  IndexTableReader m_IndexTableReader;
-  ResourceTableReader m_ResourceTableReader;
-  FunctionTableReader m_FunctionTableReader;
-  RuntimeDataContext m_Context;
-public:
-  DxilRuntimeData()
-      : m_TableCount(0), m_StringReader(), m_ResourceTableReader(),
-        m_FunctionTableReader(), m_IndexTableReader(), m_Context() {
-    m_Context = {&m_StringReader, &m_IndexTableReader, &m_ResourceTableReader,
-                 &m_FunctionTableReader};
-    m_ResourceTableReader.SetContext(&m_Context);
-    m_FunctionTableReader.SetContext(&m_Context);
-  }
-  DxilRuntimeData(const char *ptr) {
-    InitFromRDAT(ptr);
-  }
-  // initializing reader from RDAT. return true if no error has occured.
-  bool InitFromRDAT(const char *ptr) {
-    if (ptr) {
-      uint32_t TableCount = (uint32_t)*ptr;
-      RuntimeDataTableHeader *records = (RuntimeDataTableHeader *)(ptr + 4);
-      for (uint32_t i = 0; i < TableCount; ++i) {
-        RuntimeDataTableHeader *curRecord = &records[i];
-        switch (curRecord->tableType) {
-          case RuntimeDataPartType::Resource: {
-            m_ResourceTableReader.SetResourceInfo(
-                (RuntimeDataResourceInfo *)(ptr + curRecord->offset),
-                curRecord->size / sizeof(RuntimeDataResourceInfo));
-            break;
-          }
-          case RuntimeDataPartType::String: {
-            m_StringReader = PSVStringTable(ptr + curRecord->offset, curRecord->size);
-            break;
-          }
-          case RuntimeDataPartType::Function: {
-            m_FunctionTableReader.SetFunctionInfo(
-                (RuntimeDataFunctionInfo *)(ptr + curRecord->offset));
-            m_FunctionTableReader.SetCount(curRecord->size /
-                                           sizeof(RuntimeDataFunctionInfo));
-            break;
-          }
-          case RuntimeDataPartType::Index: {
-            m_IndexTableReader = IndexTableReader(
-                (uint32_t *)(ptr + curRecord->offset), curRecord->size / 4);
-            break;
-          }
-          default:
-            return false;
-        }
-      }
-      return true;
-    }
-    return false;
-  }
-  FunctionTableReader *GetFunctionTableReader() { return &m_FunctionTableReader; }
-  ResourceTableReader *GetResourceTableReader() { return &m_ResourceTableReader; }
-};
-
 class DxilPipelineStateValidation
 {
   uint32_t m_uPSVRuntimeInfoSize;

+ 428 - 0
include/dxc/HLSL/DxilRuntimeReflection.h

@@ -0,0 +1,428 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilLibraryReflection.h                                                   //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Defines shader reflection for runtime usage.                              //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include <windows.h>
+#include <unordered_map>
+#include <vector>
+#include "DxilConstants.h"
+
+namespace hlsl {
+namespace DXIL {
+namespace RDAT {
+
+struct RuntimeDataTableHeader {
+  uint32_t tableType; // RuntimeDataPartType
+  uint32_t size;
+  uint32_t offset;
+};
+
+enum RuntimeDataPartType : uint32_t {
+  Invalid = 0,
+  String,
+  Function,
+  Resource,
+  Index
+};
+
+// Index table is a sequence of rows, where each row has a count as a first
+// element followed by the count number of elements pre computing values
+class IndexTableReader {
+private:
+  const uint32_t *m_table;
+  uint32_t m_size;
+
+public:
+  class IndexRow {
+  private:
+    const uint32_t *m_values;
+    const uint32_t m_count;
+
+  public:
+    IndexRow(const uint32_t *values, uint32_t count)
+        : m_values(values), m_count(count) {}
+    uint32_t Count() { return m_count; }
+    uint32_t At(uint32_t i) { return m_values[i]; }
+  };
+
+  IndexTableReader() : m_table(nullptr), m_size(0) {}
+  IndexTableReader(const uint32_t *table, uint32_t size)
+      : m_table(table), m_size(size) {}
+
+  void SetTable(const uint32_t *table) { m_table = table; }
+
+  void SetSize(uint32_t size) { m_size = size; }
+
+  IndexRow getRow(uint32_t i) { return IndexRow(&m_table[i] + 1, m_table[i]); }
+};
+
+class StringTableReader {
+  const char *m_table;
+  uint32_t m_size;
+public:
+  StringTableReader() : m_table(nullptr), m_size(0) {}
+  StringTableReader(const char *table, uint32_t size)
+      : m_table(table), m_size(size) {}
+  const char *Get(uint32_t offset) const {
+    _Analysis_assume_(offset < m_size && m_table &&
+                      m_table[m_size - 1] == '\0');
+    return m_table + offset;
+  }
+};
+
+struct RuntimeDataResourceInfo {
+  uint32_t Class; // hlsl::DXIL::ResourceClass
+  uint32_t Kind;  // hlsl::DXIL::ResourceKind
+  uint32_t ID;    // id per class
+  uint32_t Space;
+  uint32_t LowerBound;
+  uint32_t UpperBound;
+  uint32_t Name;  // resource name as an offset for string table
+  uint32_t Flags; // Not implemented yet
+};
+
+struct RuntimeDataFunctionInfo {
+  uint32_t Name;                 // offset for string table
+  uint32_t UnmangledName;        // offset for string table
+  uint32_t Resources;            // index to an index table
+  uint32_t FunctionDependencies; // index to a list of functions that function
+                                 // depends on
+  uint32_t ShaderKind;
+  uint32_t PayloadSizeInBytes;   // 1) hit, miss, or closest shader: payload count
+                                 // 2) call shader: parameter size 
+  uint32_t AttributeSizeInBytes; // attribute size for closest hit and any hit
+  uint32_t FeatureInfo1;         // first 32 bits of feature flag
+  uint32_t FeatureInfo2;         // second 32 bits of feature flag
+  uint32_t ShaderStageFlag;      // valid shader stage flag. Not implemented yet.
+  uint32_t MinShaderTarget;      // minimum shader target. Not implemented yet.
+};
+
+class ResourceTableReader;
+class FunctionTableReader;
+
+struct RuntimeDataContext {
+  StringTableReader *pStringTableReader;
+  IndexTableReader *pIndexTableReader;
+  ResourceTableReader *pResourceTableReader;
+  FunctionTableReader *pFunctionTableReader;
+};
+
+class ResourceReader {
+private:
+  const RuntimeDataResourceInfo *m_ResourceInfo;
+  RuntimeDataContext *m_Context;
+
+public:
+  ResourceReader(const RuntimeDataResourceInfo *resInfo,
+                 RuntimeDataContext *context)
+      : m_ResourceInfo(resInfo), m_Context(context) {}
+  hlsl::DXIL::ResourceClass GetResourceClass() const {
+    return (hlsl::DXIL::ResourceClass)m_ResourceInfo->Class;
+  }
+  uint32_t GetSpace() const { return m_ResourceInfo->Space; }
+  uint32_t GetLowerBound() const { return m_ResourceInfo->LowerBound; }
+  uint32_t GetUpperBound() const { return m_ResourceInfo->UpperBound; }
+  hlsl::DXIL::ResourceKind GetResourceKind() const {
+    return (hlsl::DXIL::ResourceKind)m_ResourceInfo->Kind;
+  }
+  uint32_t GetID() const { return m_ResourceInfo->ID; }
+  const char *GetName() const {
+    return m_Context->pStringTableReader->Get(m_ResourceInfo->Name);
+  }
+  uint32_t GetFlags() const { return m_ResourceInfo->Flags; }
+};
+
+class ResourceTableReader {
+private:
+  const RuntimeDataResourceInfo
+      *m_ResourceInfo; // pointer to an array of resource bind infos
+  RuntimeDataContext *m_Context;
+  uint32_t m_CBufferCount;
+  uint32_t m_SamplerCount;
+  uint32_t m_SRVCount;
+  uint32_t m_UAVCount;
+
+public:
+  ResourceTableReader()
+      : m_ResourceInfo(nullptr), m_Context(nullptr), m_CBufferCount(0),
+        m_SamplerCount(0), m_SRVCount(0), m_UAVCount(0){};
+  ResourceTableReader(const RuntimeDataResourceInfo *info1,
+                      RuntimeDataContext *context, uint32_t CBufferCount,
+                      uint32_t SamplerCount, uint32_t SRVCount,
+                      uint32_t UAVCount)
+      : m_ResourceInfo(info1), m_Context(context), m_CBufferCount(CBufferCount),
+        m_SamplerCount(SamplerCount), m_SRVCount(SRVCount),
+        m_UAVCount(UAVCount){};
+
+  void SetResourceInfo(const RuntimeDataResourceInfo *ptr, uint32_t count) {
+    m_ResourceInfo = ptr;
+    // Assuming that resources are in order of CBuffer, Sampler, SRV, and UAV,
+    // count the number for each resource class
+    m_CBufferCount = 0;
+    m_SamplerCount = 0;
+    m_SRVCount = 0;
+    m_UAVCount = 0;
+
+    for (uint32_t i = 0; i < count; ++i) {
+      const RuntimeDataResourceInfo *curPtr = &ptr[i];
+      if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::CBuffer)
+        m_CBufferCount++;
+      else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::Sampler)
+        m_SamplerCount++;
+      else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::SRV)
+        m_SRVCount++;
+      else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::UAV)
+        m_UAVCount++;
+    }
+  }
+
+  void SetContext(RuntimeDataContext *context) { m_Context = context; }
+
+  uint32_t GetNumResources() const {
+    return m_CBufferCount + m_SamplerCount + m_SRVCount + m_UAVCount;
+  }
+  ResourceReader GetItem(uint32_t i) const {
+    _Analysis_assume_(i < GetNumResources());
+    return ResourceReader(&m_ResourceInfo[i], m_Context);
+  }
+
+  uint32_t GetNumCBuffers() const { return m_CBufferCount; }
+  ResourceReader GetCBuffer(uint32_t i) {
+    _Analysis_assume_(i < m_CBufferCount);
+    return ResourceReader(&m_ResourceInfo[i], m_Context);
+  }
+
+  uint32_t GetNumSamplers() const { return m_SamplerCount; }
+  ResourceReader GetSampler(uint32_t i) {
+    _Analysis_assume_(i < m_SamplerCount);
+    uint32_t offset = (m_CBufferCount + i);
+    return ResourceReader(&m_ResourceInfo[offset], m_Context);
+  }
+
+  uint32_t GetNumSRVs() const { return m_SRVCount; }
+  ResourceReader GetSRV(uint32_t i) {
+    _Analysis_assume_(i < m_SRVCount);
+    uint32_t offset = (m_CBufferCount + m_SamplerCount + i);
+    return ResourceReader(&m_ResourceInfo[offset], m_Context);
+  }
+
+  uint32_t GetNumUAVs() const { return m_UAVCount; }
+  ResourceReader GetUAV(uint32_t i) {
+    _Analysis_assume_(i < m_UAVCount);
+    uint32_t offset = (m_CBufferCount + m_SamplerCount + m_SRVCount + i);
+    return ResourceReader(&m_ResourceInfo[offset], m_Context);
+  }
+};
+
+class FunctionReader {
+private:
+  const RuntimeDataFunctionInfo *m_RuntimeDataFunctionInfo;
+  RuntimeDataContext *m_Context;
+
+public:
+  FunctionReader() : m_RuntimeDataFunctionInfo(nullptr), m_Context(nullptr) {}
+  FunctionReader(const RuntimeDataFunctionInfo *functionInfo,
+                 RuntimeDataContext *context)
+      : m_RuntimeDataFunctionInfo(functionInfo), m_Context(context) {}
+
+  const char *GetName() const {
+    return m_Context->pStringTableReader->Get(m_RuntimeDataFunctionInfo->Name);
+  }
+  const char *GetUnmangledName() const {
+    return m_Context->pStringTableReader->Get(
+        m_RuntimeDataFunctionInfo->UnmangledName);
+  }
+  uint64_t GetFeatureFlag() const {
+    uint64_t flag =
+        static_cast<uint64_t>(m_RuntimeDataFunctionInfo->FeatureInfo2) << 32;
+    flag |= static_cast<uint64_t>(m_RuntimeDataFunctionInfo->FeatureInfo1);
+    return flag;
+  }
+  uint32_t GetFeatureInfo1() const {
+    return m_RuntimeDataFunctionInfo->FeatureInfo1;
+  }
+  uint32_t GetFeatureInfo2() const {
+    return m_RuntimeDataFunctionInfo->FeatureInfo2;
+  }
+
+  uint32_t GetShaderStageFlag() const {
+    return m_RuntimeDataFunctionInfo->ShaderStageFlag;
+  }
+  uint32_t GetMinShaderTarget() const {
+    return m_RuntimeDataFunctionInfo->MinShaderTarget;
+  }
+  uint32_t GetNumResources() const {
+    if (m_RuntimeDataFunctionInfo->Resources == UINT_MAX)
+      return 0;
+    return m_Context->pIndexTableReader
+      ->getRow(m_RuntimeDataFunctionInfo->Resources)
+      .Count();
+  }
+  ResourceReader GetResource(uint32_t i) const {
+    uint32_t resIndex = m_Context->pIndexTableReader
+      ->getRow(m_RuntimeDataFunctionInfo->Resources)
+      .At(i);
+    return m_Context->pResourceTableReader->GetItem(resIndex);
+  }
+  uint32_t GetNumDependencies() const {
+    if (m_RuntimeDataFunctionInfo->FunctionDependencies == UINT_MAX)
+      return 0;
+    return m_Context->pIndexTableReader
+      ->getRow(m_RuntimeDataFunctionInfo->FunctionDependencies)
+      .Count();
+  }
+  const char *GetDependency(uint32_t i) const {
+    uint32_t resIndex =
+      m_Context->pIndexTableReader
+      ->getRow(m_RuntimeDataFunctionInfo->FunctionDependencies)
+      .At(i);
+    return m_Context->pStringTableReader->Get(resIndex);
+  }
+
+  uint32_t GetPayloadSizeInBytes() const {
+    return m_RuntimeDataFunctionInfo->PayloadSizeInBytes;
+  }
+  uint32_t GetAttributeSizeInBytes() const {
+    return m_RuntimeDataFunctionInfo->AttributeSizeInBytes;
+  }
+  // payload (hit shaders) and parameters (call shaders) are mutually exclusive
+  uint32_t GetParameterSizeInBytes() const {
+    return m_RuntimeDataFunctionInfo->PayloadSizeInBytes;
+  }
+  hlsl::DXIL::ShaderKind GetShaderKind() const {
+    return (hlsl::DXIL::ShaderKind)m_RuntimeDataFunctionInfo->ShaderKind;
+  }
+};
+
+class FunctionTableReader {
+private:
+  const RuntimeDataFunctionInfo *m_infos;
+  uint32_t m_count;
+  RuntimeDataContext *m_context;
+
+public:
+  FunctionTableReader() : m_infos(nullptr), m_count(0), m_context(nullptr) {}
+  FunctionTableReader(const RuntimeDataFunctionInfo *functionInfos,
+                      uint32_t count, RuntimeDataContext *context)
+      : m_infos(functionInfos), m_count(count), m_context(context) {}
+
+  FunctionReader GetItem(uint32_t i) const {
+    return FunctionReader(&m_infos[i], m_context);
+  }
+  uint32_t GetNumFunctions() const { return m_count; }
+
+  void SetFunctionInfo(const RuntimeDataFunctionInfo *ptr) {
+    m_infos = ptr;
+  }
+  void SetCount(uint32_t count) { m_count = count; }
+  void SetContext(RuntimeDataContext *context) { m_context = context; }
+};
+
+class DxilRuntimeData {
+private:
+  uint32_t m_TableCount;
+  StringTableReader m_StringReader;
+  IndexTableReader m_IndexTableReader;
+  ResourceTableReader m_ResourceTableReader;
+  FunctionTableReader m_FunctionTableReader;
+  RuntimeDataContext m_Context;
+
+public:
+  DxilRuntimeData();
+  DxilRuntimeData(const char *ptr);
+  // initializing reader from RDAT. return true if no error has occured.
+  bool InitFromRDAT(const void *pRDAT);
+  FunctionTableReader *GetFunctionTableReader();
+  ResourceTableReader *GetResourceTableReader();
+};
+
+//////////////////////////////////
+/// structures for library runtime
+
+typedef struct DXIL_RESOURCE {
+  uint32_t Class; // hlsl::DXIL::ResourceClass
+  uint32_t Kind;  // hlsl::DXIL::ResourceKind
+  uint32_t ID;    // id per class
+  uint32_t Space;
+  uint32_t UpperBound;
+  uint32_t LowerBound;
+  LPCWSTR Name;
+  uint32_t Flags;
+} DXIL_RESOURCE;
+
+typedef struct DXIL_FUNCTION {
+  LPCWSTR Name;
+  LPCWSTR UnmangledName;
+  uint32_t NumResources;
+  const DXIL_RESOURCE *Resources;
+  uint32_t NumFunctionDependencies;
+  const LPCWSTR *FunctionDependencies;
+  uint32_t ShaderKind;
+  uint32_t PayloadSizeInBytes;   // 1) hit, miss, or closest shader: payload count
+                                 // 2) call shader: parameter size
+  uint32_t AttributeSizeInBytes; // attribute size for closest hit and any hit
+  uint32_t FeatureInfo1;         // first 32 bits of feature flag
+  uint32_t FeatureInfo2;         // second 32 bits of feature flag
+  uint32_t ShaderStageFlag;      // valid shader stage flag. Not implemented yet.
+  uint32_t MinShaderTarget;      // minimum shader target. Not implemented yet.
+} DXIL_FUNCITON;
+
+typedef struct DXIL_SUBOBJECT {
+} DXIL_SUBOBJECT;
+
+typedef struct DXIL_LIBRARY_DESC {
+  uint32_t NumFunctions;
+  DXIL_FUNCITON *pFunction;
+  uint32_t NumResources;
+  DXIL_RESOURCE *pResource;
+  uint32_t NumSubobjects;
+  DXIL_SUBOBJECT *pSubobjects;
+} DXIL_LIBRARY_DESC;
+
+class DxilRuntimeReflection {
+private:
+  typedef std::unordered_map<const char *, std::wstring> StringMap;
+  typedef std::vector<DXIL_RESOURCE> ResourceList;
+  typedef std::vector<DXIL_RESOURCE *> ResourceRefList;
+  typedef std::vector<DXIL_FUNCTION> FunctionList;
+  typedef std::vector<const wchar_t *> WStringList;
+
+  DxilRuntimeData m_RuntimeData;
+  StringMap m_StringMap;
+  ResourceList m_Resources;
+  FunctionList m_Functions;
+  std::unordered_map<DXIL_FUNCTION *, ResourceRefList> m_FuncToResMap;
+  std::unordered_map<DXIL_FUNCTION *, WStringList> m_FuncToStringMap;
+  bool m_initialized;
+
+  const wchar_t *GetWideString(const char *ptr);
+  void AddString(const char *ptr);
+  void InitializeReflection();
+  DXIL_RESOURCE *GetResourcesForFunction(DXIL_FUNCTION &function,
+                                         const FunctionReader &functionReader);
+  const wchar_t **GetDependenciesForFunction(DXIL_FUNCTION &function,
+                             const FunctionReader &functionReader);
+  DXIL_RESOURCE *AddResource(const ResourceReader &resourceReader);
+  DXIL_FUNCTION *AddFunction(const FunctionReader &functionReader);
+
+public:
+  // TODO: Implement pipeline state validation with runtime data
+  // TODO: Update BlobContainer.h to recognize 'RDAT' blob
+  DxilRuntimeReflection()
+      : m_RuntimeData(), m_StringMap(), m_Resources(), m_Functions(),
+        m_FuncToResMap(), m_FuncToStringMap(), m_initialized(false) {}
+  // This call will allocate memory for GetLibraryReflection call
+  bool InitFromRDAT(const void *pRDAT);
+  const DXIL_LIBRARY_DESC GetLibraryReflection();
+};
+
+} // namespace LIB
+} // namespace DXIL
+} // namespace hlsl

+ 196 - 0
include/dxc/HLSL/DxilRuntimeReflection.inl

@@ -0,0 +1,196 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilLibraryReflection.cpp                                                 //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Defines shader reflection for runtime usage.                              //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "dxc/hlsl/DxilRuntimeReflection.h"
+
+namespace hlsl {
+namespace DXIL {
+namespace RDAT {
+
+DxilRuntimeData::DxilRuntimeData() : DxilRuntimeData(nullptr) {}
+
+DxilRuntimeData::DxilRuntimeData(const char *ptr)
+    : m_TableCount(0), m_StringReader(), m_ResourceTableReader(),
+      m_FunctionTableReader(), m_IndexTableReader(), m_Context() {
+  m_Context = {&m_StringReader, &m_IndexTableReader, &m_ResourceTableReader,
+               &m_FunctionTableReader};
+  m_ResourceTableReader.SetContext(&m_Context);
+  m_FunctionTableReader.SetContext(&m_Context);
+  InitFromRDAT(ptr);
+}
+
+// initializing reader from RDAT. return true if no error has occured.
+bool DxilRuntimeData::InitFromRDAT(const void *pRDAT) {
+  if (pRDAT) {
+    const char *ptr = static_cast<const char *>(pRDAT);
+    uint32_t TableCount = (uint32_t)*ptr;
+    RuntimeDataTableHeader *records = (RuntimeDataTableHeader *)(ptr + 4);
+    for (uint32_t i = 0; i < TableCount; ++i) {
+      RuntimeDataTableHeader *curRecord = &records[i];
+      switch (curRecord->tableType) {
+      case RuntimeDataPartType::Resource: {
+        m_ResourceTableReader.SetResourceInfo(
+            (RuntimeDataResourceInfo *)(ptr + curRecord->offset),
+            curRecord->size / sizeof(RuntimeDataResourceInfo));
+        break;
+      }
+      case RuntimeDataPartType::String: {
+        m_StringReader =
+            StringTableReader(ptr + curRecord->offset, curRecord->size);
+        break;
+      }
+      case RuntimeDataPartType::Function: {
+        m_FunctionTableReader.SetFunctionInfo(
+            (RuntimeDataFunctionInfo *)(ptr + curRecord->offset));
+        m_FunctionTableReader.SetCount(curRecord->size /
+                                       sizeof(RuntimeDataFunctionInfo));
+        break;
+      }
+      case RuntimeDataPartType::Index: {
+        m_IndexTableReader = IndexTableReader(
+            (uint32_t *)(ptr + curRecord->offset), curRecord->size / 4);
+        break;
+      }
+      default:
+        return false;
+      }
+    }
+    return true;
+  }
+  return false;
+}
+
+FunctionTableReader *DxilRuntimeData::GetFunctionTableReader() {
+  return &m_FunctionTableReader;
+}
+
+ResourceTableReader *DxilRuntimeData::GetResourceTableReader() {
+  return &m_ResourceTableReader;
+}
+
+void DxilRuntimeReflection::AddString(const char *ptr) {
+  if (m_StringMap.find(ptr) == m_StringMap.end()) {
+    int size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, ptr, -1,
+                                     nullptr, 0);
+    if (size != 0) {
+      m_StringMap[ptr] = std::wstring(size, '\0');
+      ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, ptr, -1,
+                            &(m_StringMap[ptr][0]), size);
+    }
+  }
+}
+
+const wchar_t *DxilRuntimeReflection::GetWideString(const char *ptr) {
+  if (m_StringMap.find(ptr) == m_StringMap.end()) {
+    AddString(ptr);
+  }
+  return m_StringMap.at(ptr).data();
+}
+
+bool DxilRuntimeReflection::InitFromRDAT(const void *pRDAT) {
+  m_initialized = m_RuntimeData.InitFromRDAT(pRDAT);
+  if (m_initialized)
+    InitializeReflection();
+  return m_initialized;
+}
+
+const DXIL_LIBRARY_DESC DxilRuntimeReflection::GetLibraryReflection() {
+  DXIL_LIBRARY_DESC reflection;
+  if (m_initialized) {
+    reflection.NumResources =
+        m_RuntimeData.GetResourceTableReader()->GetNumResources();
+    reflection.pResource = m_Resources.data();
+    reflection.NumFunctions =
+        m_RuntimeData.GetFunctionTableReader()->GetNumFunctions();
+    reflection.pFunction = m_Functions.data();
+  }
+  return reflection;
+}
+
+void DxilRuntimeReflection::InitializeReflection() {
+  // First need to reserve spaces for resources because functions will need to
+  // reference them via pointers.
+  m_Resources.reserve(
+      m_RuntimeData.GetResourceTableReader()->GetNumResources());
+  const FunctionTableReader *tableReader =
+      m_RuntimeData.GetFunctionTableReader();
+  for (uint32_t i = 0; i < tableReader->GetNumFunctions(); ++i) {
+    FunctionReader functionReader = tableReader->GetItem(i);
+    AddString(functionReader.GetName());
+    AddFunction(functionReader);
+  }
+}
+
+DXIL_RESOURCE *
+DxilRuntimeReflection::AddResource(const ResourceReader &resourceReader) {
+  if (m_Resources.size() < m_Resources.capacity()) {
+    m_Resources.emplace_back(DXIL_RESOURCE({0}));
+    DXIL_RESOURCE &resource = m_Resources.back();
+    resource.Class = (uint32_t)resourceReader.GetResourceClass();
+    resource.Kind = (uint32_t)resourceReader.GetResourceKind();
+    resource.Space = resourceReader.GetSpace();
+    resource.LowerBound = resourceReader.GetLowerBound();
+    resource.UpperBound = resourceReader.GetUpperBound();
+    resource.ID = resourceReader.GetID();
+    resource.Flags = resourceReader.GetFlags();
+    resource.Name = GetWideString(resourceReader.GetName());
+    return &resource;
+  }
+  // TODO: assert here?
+  return nullptr;
+}
+
+DXIL_RESOURCE *DxilRuntimeReflection::GetResourcesForFunction(
+    DXIL_FUNCTION &function, const FunctionReader &functionReader) {
+  if (m_FuncToResMap.find(&function) == m_FuncToResMap.end())
+    m_FuncToResMap.insert(std::pair<DXIL_FUNCTION *, ResourceRefList>(
+        &function, ResourceRefList()));
+  ResourceRefList &resourceList = m_FuncToResMap.at(&function);
+  for (uint32_t i = 0; i < functionReader.GetNumResources(); ++i) {
+    const ResourceReader resourceReader = functionReader.GetResource(i);
+    resourceList.emplace_back(AddResource(resourceReader));
+  }
+  return resourceList.empty() ? nullptr : *resourceList.data();
+}
+
+const wchar_t **DxilRuntimeReflection::GetDependenciesForFunction(
+    DXIL_FUNCTION &function, const FunctionReader &functionReader) {
+  if (m_FuncToStringMap.find(&function) == m_FuncToStringMap.end())
+    m_FuncToStringMap.insert(
+        std::pair<DXIL_FUNCTION *, WStringList>(&function, WStringList()));
+  WStringList &wStringList = m_FuncToStringMap.at(&function);
+  for (uint32_t i = 0; i < functionReader.GetNumDependencies(); ++i) {
+    wStringList.emplace_back(GetWideString(functionReader.GetDependency(i)));
+  }
+  return wStringList.empty() ? nullptr : wStringList.data();
+}
+
+DXIL_FUNCTION *
+DxilRuntimeReflection::AddFunction(const FunctionReader &functionReader) {
+  m_Functions.emplace_back(DXIL_FUNCTION({0}));
+  DXIL_FUNCTION &function = m_Functions.back();
+  function.Name = GetWideString(functionReader.GetName());
+  function.UnmangledName = GetWideString(functionReader.GetUnmangledName());
+  function.NumResources = functionReader.GetNumResources();
+  function.Resources = GetResourcesForFunction(function, functionReader);
+  function.NumFunctionDependencies = functionReader.GetNumDependencies();
+  function.FunctionDependencies =
+      GetDependenciesForFunction(function, functionReader);
+  function.ShaderKind = (uint32_t)functionReader.GetShaderKind();
+  function.PayloadSizeInBytes = functionReader.GetPayloadSizeInBytes();
+  function.AttributeSizeInBytes = functionReader.GetAttributeSizeInBytes();
+  function.FeatureInfo1 = functionReader.GetFeatureInfo1();
+  function.FeatureInfo2 = functionReader.GetFeatureInfo2();
+  function.ShaderStageFlag = functionReader.GetShaderStageFlag();
+  function.MinShaderTarget = functionReader.GetMinShaderTarget();
+  return &function;
+}
+}}}

+ 13 - 27
lib/HLSL/DxilContainerAssembler.cpp

@@ -28,12 +28,14 @@
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/dxcapi.impl.h"
 #include "dxc/HLSL/DxilPipelineStateValidation.h"
+#include "dxc/HLSL/DxilRuntimeReflection.h"
 #include <algorithm>
 #include <functional>
 
 using namespace llvm;
 using namespace hlsl;
 using namespace hlsl::DXIL::PSV;
+using namespace hlsl::DXIL::RDAT;
 
 static DxilProgramSigSemantic KindToSystemValue(Semantic::Kind kind, DXIL::TessellatorDomain domain) {
   switch (kind) {
@@ -810,6 +812,8 @@ public:
   }
 };
 
+using namespace DXIL;
+
 class DxilRDATWriter : public DxilPartWriter {
 private:
   const DxilModule &m_Module;
@@ -853,20 +857,21 @@ private:
   }
 
   void InsertToResourceTable(DxilResourceBase &resource,
-                             PSVResourceType resType,
+                             ResourceClass resourceClass,
                              ResourceTable &resourceTable,
                              StringTable &stringTable,
                              uint32_t &resourceIndex) {
     uint32_t stringIndex = stringTable.Insert(resource.GetGlobalName());
     UpdateFunctionToResourceInfo(&resource, resourceIndex++);
     RuntimeDataResourceInfo info = {};
+    info.ID = resource.GetID();
+    info.Class = static_cast<uint32_t>(resourceClass);
     info.Kind = static_cast<uint32_t>(resource.GetKind());
-    info.ResType = (uint32_t)resType,
     info.Space = resource.GetSpaceID();
     info.LowerBound = resource.GetLowerBound();
     info.UpperBound = resource.GetUpperBound();
     info.Name = stringIndex;
-    info.ID = resource.GetID();
+    info.Flags = 0;
     resourceTable.Insert(info);
   }
 
@@ -877,39 +882,20 @@ private:
     ResourceTable &resourceTable = *(ResourceTable*)m_tables.back().get();
     uint32_t resourceIndex = 0;
     for (auto &resource : m_Module.GetCBuffers()) {
-      InsertToResourceTable(*resource.get(), PSVResourceType::CBV, resourceTable, stringTable,
+      InsertToResourceTable(*resource.get(), ResourceClass::CBuffer, resourceTable, stringTable,
                             resourceIndex);
 
     }
     for (auto &resource : m_Module.GetSamplers()) {
-      InsertToResourceTable(*resource.get(), PSVResourceType::Sampler, resourceTable, stringTable,
+      InsertToResourceTable(*resource.get(), ResourceClass::Sampler, resourceTable, stringTable,
                             resourceIndex);
     }
     for (auto &resource : m_Module.GetSRVs()) {
-      PSVResourceType resType = PSVResourceType::Invalid;
-      if (resource->IsStructuredBuffer()) {
-        resType = PSVResourceType::SRVStructured;
-      } else if (resource->IsRawBuffer()) {
-        resType = PSVResourceType::SRVRaw;
-      } else {
-        resType = PSVResourceType::SRVTyped;
-      }
-      InsertToResourceTable(*resource.get(), resType, resourceTable, stringTable,
+      InsertToResourceTable(*resource.get(), ResourceClass::SRV, resourceTable, stringTable,
                             resourceIndex);
     }
     for (auto &resource : m_Module.GetUAVs()) {
-      PSVResourceType resType = PSVResourceType::Invalid;
-      if (resource->IsStructuredBuffer()) {
-        if (resource->HasCounter())
-          resType = PSVResourceType::UAVStructuredWithCounter;
-        else
-          resType = PSVResourceType::UAVStructured;
-      } else if (resource->IsRawBuffer()) {
-        resType = PSVResourceType::UAVRaw;
-      } else {
-        resType = PSVResourceType::UAVTyped;
-      }
-      InsertToResourceTable(*resource.get(), resType, resourceTable, stringTable,
+      InsertToResourceTable(*resource.get(), ResourceClass::UAV, resourceTable, stringTable,
                             resourceIndex);
     }
   }
@@ -953,7 +939,7 @@ private:
         uint32_t functionDependencies = UINT_MAX;
         uint32_t payloadSizeInBytes = 0;
         uint32_t attrSizeInBytes = 0;
-        uint32_t shaderKind = (uint32_t)PSVShaderKind::Library;
+        uint32_t shaderKind = static_cast<uint32_t>(DXIL::ShaderKind::Library);
 
         if (m_FuncToResNameOffset.find(&function) != m_FuncToResNameOffset.end())
           resourceIndex =

+ 1 - 0
lib/HLSL/DxilContainerReflection.cpp

@@ -23,6 +23,7 @@
 #include "dxc/Support/microcom.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/dxcapi.impl.h"
+#include "dxc/HLSL/DxilRuntimeReflection.inl"
 
 #include <unordered_set>
 

+ 73 - 13
tools/clang/unittests/HLSL/DxilContainerTest.cpp

@@ -20,6 +20,7 @@
 #include <cassert>
 #include <sstream>
 #include <algorithm>
+#include <unordered_set>
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/dxcapi.h"
 #include <atlfile.h>
@@ -33,7 +34,7 @@
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/HLSLOptions.h"
 #include "dxc/HLSL/DxilContainer.h"
-#include "dxc/HLSL/DxilPipelineStateValidation.h"
+#include "dxc/HLSL/DxilRuntimeReflection.h"
 #include "dxc/HLSL/DxilShaderFlags.h"
 #include "dxc/HLSL/DxilUtil.h"
 
@@ -672,12 +673,12 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT) {
     "RWTexture1D<int4> tex : register(u5);"
     "Texture1D<float4> tex2 : register(t0);"
     "RWByteAddressBuffer b_buf;"
+    "float function_import(float x);"
     "float function0(min16float x) { "
     "  return x + 1 + tex[0].x; }"
     "float function1(float x, min12int i) {"
     "  return x + c_buf + b_buf.Load(x) + tex2[i].x; }"
-                       "float function2(float x) {"
-                       "  return x; }";
+    "float function2(float x) { return x + function_import(x); }";
   CComPtr<IDxcCompiler> pCompiler;
   CComPtr<IDxcBlobEncoding> pSource;
   CComPtr<IDxcBlob> pProgram;
@@ -690,20 +691,21 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT) {
                                       L"lib_6_3", nullptr, 0, nullptr, 0,
                                       nullptr, &pResult));
   VERIFY_SUCCEEDED(pResult->GetResult(&pProgram));
-  CComPtr<IDxcContainerReflection> pReflection;
+  CComPtr<IDxcContainerReflection> containerReflection;
   uint32_t partCount;
-  IFT(m_dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection));
-  IFT(pReflection->Load(pProgram));
-  IFT(pReflection->GetPartCount(&partCount));
+  IFT(m_dllSupport.CreateInstance(CLSID_DxcContainerReflection, &containerReflection));
+  IFT(containerReflection->Load(pProgram));
+  IFT(containerReflection->GetPartCount(&partCount));
   bool blobFound = false;
   for (uint32_t i = 0; i < partCount; ++i) {
     uint32_t kind;
-    IFT(pReflection->GetPartKind(i, &kind));
+    IFT(containerReflection->GetPartKind(i, &kind));
     if (kind == (uint32_t)hlsl::DxilFourCC::DFCC_RuntimeData) {
       blobFound = true;
-      using namespace hlsl::DXIL::PSV;
+      using namespace hlsl::DXIL::RDAT;
       CComPtr<IDxcBlob> pBlob;
-      IFT(pReflection->GetPartContent(i, &pBlob));
+      IFT(containerReflection->GetPartContent(i, &pBlob));
+      // Validate using DxilRuntimeData
       DxilRuntimeData context;
       context.InitFromRDAT((char *)pBlob->GetBufferPointer());
       FunctionTableReader *funcTableReader = context.GetFunctionTableReader();
@@ -724,7 +726,8 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT) {
           uint64_t rawFlag = flag.GetShaderFlagsRaw();
           VERIFY_IS_TRUE(funcReader.GetFeatureFlag() == rawFlag);
           ResourceReader resReader = funcReader.GetResource(0);
-          VERIFY_IS_TRUE(resReader.GetResourceKind() == PSVResourceKind::Texture1D);
+          VERIFY_IS_TRUE(resReader.GetResourceClass() == hlsl::DXIL::ResourceClass::UAV);
+          VERIFY_IS_TRUE(resReader.GetResourceKind() == hlsl::DXIL::ResourceKind::Texture1D);
         }
         else if (cur_str.compare("function1") == 0) {
           hlsl::ShaderFlags flag;
@@ -736,12 +739,68 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT) {
         else if (cur_str.compare("function2") == 0) {
           VERIFY_IS_TRUE((funcReader.GetFeatureFlag() & 0xffffffffffffffff) == 0);
           VERIFY_IS_TRUE(funcReader.GetNumResources() == 0);
+          std::string dependency = funcReader.GetDependency(0);
+          VERIFY_IS_TRUE(dependency.find("function_import") != std::string::npos);
         }
         else {
           IFTBOOLMSG(false, E_FAIL, "unknown function name");
         }
       }
       VERIFY_IS_TRUE(resTableReader->GetNumResources() == 4);
+      // This is validation test for DxilRuntimeReflection implemented on DxilRuntimeReflection.inl
+      DxilRuntimeReflection reflection;
+      VERIFY_IS_TRUE(reflection.InitFromRDAT(pBlob->GetBufferPointer()));
+      DXIL_LIBRARY_DESC lib_reflection = reflection.GetLibraryReflection();
+      VERIFY_IS_TRUE(lib_reflection.NumFunctions == 3);
+      for (uint32_t j = 0; j < 3; ++j) {
+        DXIL_FUNCTION function = lib_reflection.pFunction[j];
+        std::string cur_str = str;
+        cur_str.push_back('0' + j);
+        if (cur_str.compare("function0") == 0) {
+          hlsl::ShaderFlags flag;
+          flag.SetUAVLoadAdditionalFormats(true);
+          flag.SetLowPrecisionPresent(true);
+          uint64_t rawFlag = flag.GetShaderFlagsRaw();
+          uint64_t featureFlag = static_cast<uint64_t>(function.FeatureInfo2) << 32;
+          featureFlag |= static_cast<uint64_t>(function.FeatureInfo1);
+          VERIFY_IS_TRUE(featureFlag == rawFlag);
+          VERIFY_IS_TRUE(function.NumResources == 1);
+          VERIFY_IS_TRUE(function.NumFunctionDependencies == 0);
+          const DXIL_RESOURCE resource = function.Resources[0];
+          VERIFY_IS_TRUE(resource.Class == (uint32_t)hlsl::DXIL::ResourceClass::UAV);
+          VERIFY_IS_TRUE(resource.Kind == (uint32_t)hlsl::DXIL::ResourceKind::Texture1D);
+          std::wstring wName = resource.Name;
+          VERIFY_IS_TRUE(wName.compare(L"tex") == 0);
+        }
+        else if (cur_str.compare("function1") == 0) {
+          hlsl::ShaderFlags flag;
+          flag.SetLowPrecisionPresent(true);
+          uint64_t rawFlag = flag.GetShaderFlagsRaw();
+          uint64_t featureFlag = static_cast<uint64_t>(function.FeatureInfo2) << 32;
+          featureFlag |= static_cast<uint64_t>(function.FeatureInfo1);
+          VERIFY_IS_TRUE(featureFlag == rawFlag);
+          VERIFY_IS_TRUE(function.NumResources == 3);
+          VERIFY_IS_TRUE(function.NumFunctionDependencies == 0);
+          std::unordered_set<std::wstring> stringSet = { L"$Globals", L"b_buf", L"tex2" };
+          for (uint32_t j = 0; j < 3; ++j) {
+            const DXIL_RESOURCE resource = function.Resources[j];
+            std::wstring compareName = resource.Name;
+            VERIFY_IS_TRUE(stringSet.find(compareName) != stringSet.end());
+          }
+        }
+        else if (cur_str.compare("function2") == 0) {
+          VERIFY_IS_TRUE(function.FeatureInfo1 == 0);
+          VERIFY_IS_TRUE(function.FeatureInfo2 == 0);
+          VERIFY_IS_TRUE(function.NumResources == 0);
+          VERIFY_IS_TRUE(function.NumFunctionDependencies == 1);
+          std::wstring dependency = function.FunctionDependencies[0];
+          VERIFY_IS_TRUE(dependency.find(L"function_import") != std::wstring::npos);
+        }
+        else {
+          IFTBOOLMSG(false, E_FAIL, "unknown function name");
+        }
+      }
+      VERIFY_IS_TRUE(lib_reflection.NumResources == 4);
     }
   }
   IFTBOOLMSG(blobFound, E_FAIL, "failed to find RDAT blob after compiling");
@@ -787,7 +846,7 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT2) {
     IFT(pReflection->GetPartKind(i, &kind));
     if (kind == (uint32_t)hlsl::DxilFourCC::DFCC_RuntimeData) {
       blobFound = true;
-      using namespace hlsl::DXIL::PSV;
+      using namespace hlsl::DXIL::RDAT;
       CComPtr<IDxcBlob> pBlob;
       IFT(pReflection->GetPartContent(i, &pBlob));
       DxilRuntimeData context;
@@ -799,7 +858,8 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT2) {
       FunctionReader funcReader = funcTableReader->GetItem(0);
       llvm::StringRef name(funcReader.GetUnmangledName());
       VERIFY_IS_TRUE(name.compare("RayGenMain") == 0);
-      VERIFY_IS_TRUE(funcReader.GetShaderKind() == PSVShaderKind::RayGeneration);
+      VERIFY_IS_TRUE(funcReader.GetShaderKind() ==
+                     hlsl::DXIL::ShaderKind::RayGeneration);
       VERIFY_IS_TRUE(funcReader.GetNumResources() == 3);
       VERIFY_IS_TRUE(funcReader.GetNumDependencies() == 1);
       llvm::StringRef dependencyName =