Skip to content

Commit 46db044

Browse files
authored
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.
1 parent f6d15f9 commit 46db044

4 files changed

Lines changed: 41 additions & 1 deletion

File tree

lib/HLSL/DxilContainerReflection.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2526,6 +2526,7 @@ class CFunctionReflection final : public ID3D12FunctionReflection {
25262526
typedef SmallSetVector<UINT32, 8> ResourceUseSet;
25272527
ResourceUseSet m_UsedResources;
25282528
ResourceUseSet m_UsedCBs;
2529+
UINT64 m_FeatureFlags;
25292530

25302531
public:
25312532
void Initialize(DxilLibraryReflection* pLibraryReflection, Function *pFunction) {
@@ -2547,6 +2548,9 @@ class CFunctionReflection final : public ID3D12FunctionReflection {
25472548
void AddCBReference(UINT cbIndex) {
25482549
m_UsedCBs.insert(cbIndex);
25492550
}
2551+
void SetFeatureFlags(UINT64 flags) {
2552+
m_FeatureFlags = flags;
2553+
}
25502554

25512555
// ID3D12FunctionReflection
25522556
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_FUNCTION_DESC * pDesc);
@@ -2609,7 +2613,12 @@ HRESULT CFunctionReflection::GetDesc(D3D12_FUNCTION_DESC *pDesc) {
26092613
//Unset: UINT ConversionInstructionCount; // Number of type conversion instructions used
26102614
//Unset: UINT BitwiseInstructionCount; // Number of bitwise arithmetic instructions used
26112615
//Unset: D3D_FEATURE_LEVEL MinFeatureLevel; // Min target of the function byte code
2612-
//Unset: UINT64 RequiredFeatureFlags; // Required feature flags
2616+
2617+
pDesc->RequiredFeatureFlags = m_FeatureFlags & ~(UINT64)D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL;
2618+
if (kind == DXIL::ShaderKind::Pixel && m_pProps &&
2619+
m_pProps->ShaderProps.PS.EarlyDepthStencil) {
2620+
pDesc->RequiredFeatureFlags |= D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL;
2621+
}
26132622

26142623
pDesc->Name = m_Name.c_str();
26152624

@@ -2697,6 +2706,8 @@ void DxilLibraryReflection::AddResourceDependencies() {
26972706
m_FunctionsByPtr[F] = func.get();
26982707
orderedMap[FR.getName()] = func.get();
26992708

2709+
func->SetFeatureFlags(FR.GetFeatureFlags());
2710+
27002711
for (unsigned iRes = 0; iRes < FR.getResources().Count(); ++iRes) {
27012712
auto RR = FR.getResources()[iRes];
27022713
unsigned id = RR.getID();

tools/clang/test/HLSLFileCheck/d3dreflect/lib_global.hlsl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// CHECK-NEXT: D3D12_FUNCTION_DESC: Name: _GLOBAL__sub_I_lib_global.hlsl
1616
// CHECK-NEXT: Shader Version: Library
1717
// CHECK: Flags: 0
18+
// CHECK-NEXT: RequiredFeatureFlags: 0x40000
1819
// CHECK-NEXT: ConstantBuffers: 2
1920
// CHECK-NEXT: BoundResources: 2
2021
// CHECK-NEXT: FunctionParameterCount: 0
@@ -183,6 +184,7 @@
183184
// CHECK-NEXT: D3D12_FUNCTION_DESC: Name: test
184185
// CHECK-NEXT: Shader Version: Pixel
185186
// CHECK: Flags: 0
187+
// CHECK-NEXT: RequiredFeatureFlags: 0x40000
186188
// CHECK-NEXT: ConstantBuffers: 2
187189
// CHECK-NEXT: BoundResources: 4
188190
// CHECK-NEXT: FunctionParameterCount: 0
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %dxc -auto-binding-space 13 -default-linkage external -T lib_6_3 %s | %D3DReflect %s | FileCheck %s
2+
3+
float DoubleMAD(float a, float b, float c) {
4+
return (float)((double)a * (double)b + (double)c);
5+
}
6+
7+
[shader("vertex")]
8+
float4 VSMain(float4 In : IN) : SV_Position {
9+
return In * DoubleMAD(In.x, In.y, In.z);
10+
}
11+
12+
[shader("pixel")]
13+
[earlydepthstencil]
14+
float4 PSMain(float4 In : IN, out float Depth : SV_Depth) : SV_Target {
15+
Depth = In.z;
16+
return In;
17+
}
18+
19+
// CHECK: ID3D12LibraryReflection:
20+
// CHECK: FunctionCount: 3
21+
// CHECK-LABEL: D3D12_FUNCTION_DESC: Name: \01?DoubleMAD@@YAMMMM@Z
22+
// CHECK: RequiredFeatureFlags: 0x1
23+
// CHECK-LABEL: D3D12_FUNCTION_DESC: Name: PSMain
24+
// CHECK: RequiredFeatureFlags: 0x2
25+
// CHECK-LABEL: D3D12_FUNCTION_DESC: Name: VSMain
26+
// CHECK: RequiredFeatureFlags: 0x1

tools/clang/unittests/HLSLTestLib/D3DReflectionDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ void D3DReflectionDumper::Dump(D3D12_FUNCTION_DESC &Desc) {
171171
DumpShaderVersion(Desc.Version);
172172
WriteLn("Creator: ", Desc.Creator ? Desc.Creator : "<nullptr>");
173173
WriteLn("Flags: ", std::hex, std::showbase, Desc.Flags);
174+
WriteLn("RequiredFeatureFlags: ", std::hex, std::showbase, Desc.RequiredFeatureFlags);
174175
WriteLn("ConstantBuffers: ", Desc.ConstantBuffers);
175176
WriteLn("BoundResources: ", Desc.BoundResources);
176177
WriteLn("FunctionParameterCount: ", Desc.FunctionParameterCount);

0 commit comments

Comments
 (0)