Bläddra i källkod

Fixed a validation failure with stripping reflect with library shaders. (#2182)

Adam Yang 6 år sedan
förälder
incheckning
24e71b12e5

+ 6 - 4
lib/DXIL/DxilModule.cpp

@@ -1434,10 +1434,12 @@ void DxilModule::StripReflection() {
 
 
   // Resource
-  StripResourcesReflection(m_CBuffers);
-  StripResourcesReflection(m_UAVs);
-  StripResourcesReflection(m_SRVs);
-  StripResourcesReflection(m_Samplers);
+  if (!GetShaderModel()->IsLib()) {
+    StripResourcesReflection(m_CBuffers);
+    StripResourcesReflection(m_UAVs);
+    StripResourcesReflection(m_SRVs);
+    StripResourcesReflection(m_Samplers);
+  }
 
   // Unused global.
   SmallVector<GlobalVariable *,2> UnusedGlobals;

+ 19 - 19
lib/DxilContainer/DxilContainerAssembler.cpp

@@ -971,7 +971,6 @@ using namespace DXIL;
 
 class DxilRDATWriter : public DxilPartWriter {
 private:
-  const DxilModule &m_Module;
   SmallVector<char, 1024> m_RDATBuffer;
 
   std::vector<std::unique_ptr<RDATPart>> m_Parts;
@@ -1070,21 +1069,21 @@ private:
     m_pResourceTable->Insert(info);
   }
 
-  void UpdateResourceInfo() {
+  void UpdateResourceInfo(const DxilModule &DM) {
     // Try to allocate string table for resources. String table is a sequence
     // of strings delimited by \0
     uint32_t resourceIndex = 0;
-    for (auto &resource : m_Module.GetCBuffers()) {
+    for (auto &resource : DM.GetCBuffers()) {
       InsertToResourceTable(*resource.get(), ResourceClass::CBuffer, resourceIndex);
 
     }
-    for (auto &resource : m_Module.GetSamplers()) {
+    for (auto &resource : DM.GetSamplers()) {
       InsertToResourceTable(*resource.get(), ResourceClass::Sampler, resourceIndex);
     }
-    for (auto &resource : m_Module.GetSRVs()) {
+    for (auto &resource : DM.GetSRVs()) {
       InsertToResourceTable(*resource.get(), ResourceClass::SRV, resourceIndex);
     }
-    for (auto &resource : m_Module.GetUAVs()) {
+    for (auto &resource : DM.GetUAVs()) {
       InsertToResourceTable(*resource.get(), ResourceClass::UAV, resourceIndex);
     }
   }
@@ -1102,8 +1101,8 @@ private:
     }
   }
 
-  void UpdateFunctionInfo() {
-    for (auto &function : m_Module.GetModule()->getFunctionList()) {
+  void UpdateFunctionInfo(const DxilModule &DM) {
+    for (auto &function : DM.GetModule()->getFunctionList()) {
       if (function.isDeclaration() && !function.isIntrinsic()) {
         if (OP::IsDxilOpFunc(&function)) {
           // update min shader model and shader stage mask per function
@@ -1114,7 +1113,7 @@ private:
         }
       }
     }
-    for (auto &function : m_Module.GetModule()->getFunctionList()) {
+    for (auto &function : DM.GetModule()->getFunctionList()) {
       if (!function.isDeclaration()) {
         StringRef mangled = function.getName();
         StringRef unmangled = hlsl::dxilutil::DemangleFunctionName(function.getName());
@@ -1135,8 +1134,8 @@ private:
           functionDependencies =
               m_pIndexArraysPart->AddIndex(m_FuncToDependencies[&function].begin(),
                                   m_FuncToDependencies[&function].end());
-        if (m_Module.HasDxilFunctionProps(&function)) {
-          auto props = m_Module.GetDxilFunctionProps(&function);
+        if (DM.HasDxilFunctionProps(&function)) {
+          auto props = DM.GetDxilFunctionProps(&function);
           if (props.IsClosestHit() || props.IsAnyHit()) {
             payloadSizeInBytes = props.ShaderProps.Ray.payloadSizeInBytes;
             attrSizeInBytes = props.ShaderProps.Ray.attributeSizeInBytes;
@@ -1149,7 +1148,7 @@ private:
           }
           shaderKind = (uint32_t)props.shaderKind;
         }
-        ShaderFlags flags = ShaderFlags::CollectShaderFlags(&function, &m_Module);
+        ShaderFlags flags = ShaderFlags::CollectShaderFlags(&function, &DM);
         RuntimeDataFunctionInfo info = {};
         info.Name = mangledIndex;
         info.UnmangledName = unmangledIndex;
@@ -1193,10 +1192,10 @@ private:
     }
   }
 
-  void UpdateSubobjectInfo() {
-    if (!m_Module.GetSubobjects())
+  void UpdateSubobjectInfo(const DxilModule &DM) {
+    if (!DM.GetSubobjects())
       return;
-    for (auto &it : m_Module.GetSubobjects()->GetSubobjects()) {
+    for (auto &it : DM.GetSubobjects()->GetSubobjects()) {
       auto &obj = *it.second;
       RuntimeDataSubobjectInfo info = {};
       info.Name = m_pStringBufferPart->Insert(obj.GetName());
@@ -1280,11 +1279,11 @@ private:
 
 public:
   DxilRDATWriter(const DxilModule &module, uint32_t InfoVersion = 0)
-      : m_Module(module), m_RDATBuffer(), m_Parts(), m_FuncToResNameOffset() {
+      : m_RDATBuffer(), m_Parts(), m_FuncToResNameOffset() {
     CreateParts();
-    UpdateResourceInfo();
-    UpdateFunctionInfo();
-    UpdateSubobjectInfo();
+    UpdateResourceInfo(module);
+    UpdateFunctionInfo(module);
+    UpdateSubobjectInfo(module);
 
     // Delete any empty parts:
     std::vector<std::unique_ptr<RDATPart>>::iterator it = m_Parts.begin();
@@ -1540,6 +1539,7 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
         DFCC_RuntimeData, pRDATWriter->size(),
         [&](AbstractMemoryStream *pStream) { pRDATWriter->write(pStream); });
     bMetadataStripped |= pModule->StripSubobjectsFromMetadata();
+    pModule->ResetSubobjects(nullptr);
   } else {
     // Write the DxilPipelineStateValidation (PSV0) part.
     pPSVWriter = llvm::make_unique<DxilPSVWriter>(*pModule);

+ 22 - 0
tools/clang/test/CodeGenHLSL/batch/compiler_options/Qstrip_reflect_lib.hlsl

@@ -0,0 +1,22 @@
+// RUN: %dxc -T lib_6_3 %s /Qstrip_reflect | FileCheck %s
+
+// Check that validation doesn't complain about RDAT mismatch with resources
+// because names are now gone.
+
+// CHECK: @main
+
+Texture2D tex0;
+Texture2D tex1;
+Texture2D tex2;
+
+SamplerState samp0;
+SamplerState samp1;
+SamplerState samp2;
+
+[shader("pixel")]
+float4 main(float2 uv : TEXCOORD) : SV_Target  {
+  return
+    tex0.Sample(samp0, uv) +
+    tex1.Sample(samp1, uv) +
+    tex2.Sample(samp2, uv);
+} 

+ 28 - 0
tools/clang/test/CodeGenHLSL/batch/compiler_options/Qstrip_reflect_subobj.hlsl

@@ -0,0 +1,28 @@
+// RUN: %dxc -T lib_6_3 -Qstrip_reflect %s | FileCheck %s
+
+// CHECK: ; GlobalRootSignature grs = { <48 bytes> };
+// CHECK: ; StateObjectConfig soc = { STATE_OBJECT_FLAG_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS };
+// CHECK: ; LocalRootSignature lrs = { <48 bytes> };
+// CHECK: ; SubobjectToExportsAssociation sea = { "grs", { "a", "b", "foo", "c" }  };
+// CHECK: ; SubobjectToExportsAssociation sea2 = { "grs", { }  };
+// CHECK: ; SubobjectToExportsAssociation sea3 = { "grs", { }  };
+// CHECK: ; RaytracingShaderConfig rsc = { MaxPayloadSizeInBytes = 128, MaxAttributeSizeInBytes = 64 };
+// CHECK: ; RaytracingPipelineConfig rpc = { MaxTraceRecursionDepth = 512 };
+// CHECK: ; HitGroup trHitGt = { HitGroupType = Triangle, Anyhit = "a", Closesthit = "b", Intersection = "" };
+// CHECK: ; HitGroup ppHitGt = { HitGroupType = ProceduralPrimitive, Anyhit = "a", Closesthit = "b", Intersection = "c" };
+
+GlobalRootSignature grs = {"CBV(b0)"};
+StateObjectConfig soc = { STATE_OBJECT_FLAGS_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITONS };
+LocalRootSignature lrs = {"UAV(u0, visibility = SHADER_VISIBILITY_GEOMETRY), RootFlags(LOCAL_ROOT_SIGNATURE)"};
+SubobjectToExportsAssociation sea = { "grs", "a;b;foo;c" };
+// Empty association is well-defined: it creates a default association
+SubobjectToExportsAssociation sea2 = { "grs", ";" };
+SubobjectToExportsAssociation sea3 = { "grs", "" };
+RaytracingShaderConfig rsc = { 128, 64 };
+RaytracingPipelineConfig rpc = { 512 };
+TriangleHitGroup trHitGt = { "a", "b" };
+ProceduralPrimitiveHitGroup ppHitGt = { "a", "b", "c"};
+
+int main(int i : INDEX) : SV_Target {
+  return 1;
+}