浏览代码

Fill in RequiredFeatureFlags in library function reflection (#4774)

ID3D12FunctionReflection was leaving the `RequiredFeatureFlags` blank, but the information is available.  This change fixes that omission.

Like the equivalent for ID3D12ShaderReflection (see `DxilShaderReflection::GetRequiresFlags`), the flags are the same between the `SHADER_FEATURE_*` flags and `D3D_SHADER_REQUIRES_*` flags, except that `D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL` collides with `SHADER_FEATURE_COMPUTE_SHADERS_PLUS_RAW_AND_STRUCTURED_BUFFERS_VIA_SHADER_4_X` not exposed in `RequiredFeatureFlags`.  So, the `D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL` flag is patched in based on the flag captured in the shader props (`ShaderProps.PS.EarlyDepthStencil`) for library pixel shader entry points.
Tex Riddell 2 年之前
父节点
当前提交
46db0442d9

+ 12 - 1
lib/HLSL/DxilContainerReflection.cpp

@@ -2526,6 +2526,7 @@ protected:
   typedef SmallSetVector<UINT32, 8> ResourceUseSet;
   ResourceUseSet m_UsedResources;
   ResourceUseSet m_UsedCBs;
+  UINT64 m_FeatureFlags;
 
 public:
   void Initialize(DxilLibraryReflection* pLibraryReflection, Function *pFunction) {
@@ -2547,6 +2548,9 @@ public:
   void AddCBReference(UINT cbIndex) {
     m_UsedCBs.insert(cbIndex);
   }
+  void SetFeatureFlags(UINT64 flags) {
+    m_FeatureFlags = flags;
+  }
 
   // ID3D12FunctionReflection
   STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_FUNCTION_DESC * pDesc);
@@ -2609,7 +2613,12 @@ HRESULT CFunctionReflection::GetDesc(D3D12_FUNCTION_DESC *pDesc) {
   //Unset:  UINT                    ConversionInstructionCount;  // Number of type conversion instructions used
   //Unset:  UINT                    BitwiseInstructionCount;     // Number of bitwise arithmetic instructions used
   //Unset:  D3D_FEATURE_LEVEL       MinFeatureLevel;             // Min target of the function byte code
-  //Unset:  UINT64                  RequiredFeatureFlags;        // Required feature flags
+
+  pDesc->RequiredFeatureFlags = m_FeatureFlags & ~(UINT64)D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL;
+  if (kind == DXIL::ShaderKind::Pixel && m_pProps &&
+      m_pProps->ShaderProps.PS.EarlyDepthStencil) {
+    pDesc->RequiredFeatureFlags |= D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL;
+  }
 
   pDesc->Name = m_Name.c_str();
 
@@ -2697,6 +2706,8 @@ void DxilLibraryReflection::AddResourceDependencies() {
     m_FunctionsByPtr[F] = func.get();
     orderedMap[FR.getName()] = func.get();
 
+    func->SetFeatureFlags(FR.GetFeatureFlags());
+
     for (unsigned iRes = 0; iRes < FR.getResources().Count(); ++iRes) {
       auto RR = FR.getResources()[iRes];
       unsigned id = RR.getID();

+ 2 - 0
tools/clang/test/HLSLFileCheck/d3dreflect/lib_global.hlsl

@@ -15,6 +15,7 @@
 // CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: _GLOBAL__sub_I_lib_global.hlsl
 // CHECK-NEXT:       Shader Version: Library
 // CHECK:       Flags: 0
+// CHECK-NEXT:       RequiredFeatureFlags: 0x40000
 // CHECK-NEXT:       ConstantBuffers: 2
 // CHECK-NEXT:       BoundResources: 2
 // CHECK-NEXT:       FunctionParameterCount: 0
@@ -183,6 +184,7 @@
 // CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: test
 // CHECK-NEXT:       Shader Version: Pixel
 // CHECK:       Flags: 0
+// CHECK-NEXT:       RequiredFeatureFlags: 0x40000
 // CHECK-NEXT:       ConstantBuffers: 2
 // CHECK-NEXT:       BoundResources: 4
 // CHECK-NEXT:       FunctionParameterCount: 0

+ 26 - 0
tools/clang/test/HLSLFileCheck/d3dreflect/lib_requires_flags.hlsl

@@ -0,0 +1,26 @@
+// RUN: %dxc -auto-binding-space 13 -default-linkage external -T lib_6_3 %s | %D3DReflect %s | FileCheck %s
+
+float DoubleMAD(float a, float b, float c) {
+  return (float)((double)a * (double)b + (double)c);
+}
+
+[shader("vertex")]
+float4 VSMain(float4 In : IN) : SV_Position {
+  return In * DoubleMAD(In.x, In.y, In.z);
+}
+
+[shader("pixel")]
+[earlydepthstencil]
+float4 PSMain(float4 In : IN, out float Depth : SV_Depth) : SV_Target {
+  Depth = In.z;
+  return In;
+}
+
+// CHECK: ID3D12LibraryReflection:
+// CHECK:     FunctionCount: 3
+// CHECK-LABEL:     D3D12_FUNCTION_DESC: Name: \01?DoubleMAD@@YAMMMM@Z
+// CHECK:       RequiredFeatureFlags: 0x1
+// CHECK-LABEL:     D3D12_FUNCTION_DESC: Name: PSMain
+// CHECK:       RequiredFeatureFlags: 0x2
+// CHECK-LABEL:     D3D12_FUNCTION_DESC: Name: VSMain
+// CHECK:       RequiredFeatureFlags: 0x1

+ 1 - 0
tools/clang/unittests/HLSLTestLib/D3DReflectionDumper.cpp

@@ -171,6 +171,7 @@ void D3DReflectionDumper::Dump(D3D12_FUNCTION_DESC &Desc) {
   DumpShaderVersion(Desc.Version);
   WriteLn("Creator: ", Desc.Creator ? Desc.Creator : "<nullptr>");
   WriteLn("Flags: ", std::hex, std::showbase, Desc.Flags);
+  WriteLn("RequiredFeatureFlags: ", std::hex, std::showbase, Desc.RequiredFeatureFlags);
   WriteLn("ConstantBuffers: ", Desc.ConstantBuffers);
   WriteLn("BoundResources: ", Desc.BoundResources);
   WriteLn("FunctionParameterCount: ", Desc.FunctionParameterCount);