Skip to content

Commit 22bb078

Browse files
authored
Fix downlevel validator compatibility with DXR 1.1 flag (#6333)
It turns out that in the prior validator version, if a subobject required DXR 1.1, the DXR 1.1 flag would be set on each function in RDAT output, as well as the global flags. It didn't appear this was the case through a D3DReflect test because that goes through disassembly to assembly step, where subobjects are lost because they aren't in the llvm IR. The previous change assumed this was not the case when the subobjects were removed, but this removal occurs after the RDATWriter constructor, which does the full RDAT serialization since size if required right away. This restores the detection code and hooks it into DxilModule::ComputeShaderCompatInfo when validator version is in range [1.5, 1.7]. DXR 1.1 was introduced in 1.5, and we no longer tag every function as requiring DXR 1.1 based on subobjects in 1.8. At the moment, there is no way to CHECK the subobject RDAT in D3DReflect because they get stripped from the module (even reflection and debug modules) before serialization, and the test path for D3DReflect goes through a disassemble/re-assemble step between the prior stage and the D3DReflect stage. Fixes #6321 (really).
1 parent 76f00d0 commit 22bb078

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

lib/DXIL/DxilModule.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,13 +2191,39 @@ static void AdjustMinimumShaderModelAndFlags(const DxilFunctionProps *props,
21912191
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 1);
21922192
}
21932193

2194+
static bool RequiresRaytracingTier1_1(const DxilSubobjects *pSubobjects) {
2195+
if (!pSubobjects)
2196+
return false;
2197+
for (const auto &it : pSubobjects->GetSubobjects()) {
2198+
switch (it.second->GetKind()) {
2199+
case DXIL::SubobjectKind::RaytracingPipelineConfig1:
2200+
return true;
2201+
case DXIL::SubobjectKind::StateObjectConfig: {
2202+
uint32_t configFlags;
2203+
if (it.second->GetStateObjectConfig(configFlags) &&
2204+
((configFlags &
2205+
(unsigned)DXIL::StateObjectFlags::AllowStateObjectAdditions) != 0))
2206+
return true;
2207+
} break;
2208+
default:
2209+
break;
2210+
}
2211+
}
2212+
return false;
2213+
}
2214+
21942215
void DxilModule::ComputeShaderCompatInfo() {
21952216
m_FuncToShaderCompat.clear();
21962217

21972218
bool dxil15Plus = DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 5) >= 0;
21982219
bool dxil18Plus = DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 8) >= 0;
21992220
bool dxil19Plus = DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 9) >= 0;
22002221

2222+
// Prior to validator version 1.8, DXR 1.1 flag was set on every function
2223+
// if subobjects contained any DXR 1.1 subobjects.
2224+
bool setDXR11OnAllFunctions =
2225+
dxil15Plus && !dxil18Plus && RequiresRaytracingTier1_1(GetSubobjects());
2226+
22012227
// Initialize worklist with functions that have callers
22022228
SmallSetVector<llvm::Function *, 8> worklist;
22032229

@@ -2212,6 +2238,8 @@ void DxilModule::ComputeShaderCompatInfo() {
22122238
// Insert or lookup info
22132239
ShaderCompatInfo &info = m_FuncToShaderCompat[&function];
22142240
info.shaderFlags = ShaderFlags::CollectShaderFlags(&function, this);
2241+
if (setDXR11OnAllFunctions)
2242+
info.shaderFlags.SetRaytracingTier1_1(true);
22152243
} else if (!function.isIntrinsic() &&
22162244
function.getLinkage() ==
22172245
llvm::GlobalValue::LinkageTypes::ExternalLinkage &&

lib/HLSL/DxilValidation.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,6 +4487,20 @@ static void ValidateResources(ValidationContext &ValCtx) {
44874487
static void ValidateShaderFlags(ValidationContext &ValCtx) {
44884488
ShaderFlags calcFlags;
44894489
ValCtx.DxilMod.CollectShaderFlagsForModule(calcFlags);
4490+
4491+
// Special case for validator version prior to 1.8.
4492+
// If DXR 1.1 flag is set, but our computed flags do not have this set, then
4493+
// this is due to prior versions setting the flag based on DXR 1.1 subobjects,
4494+
// which are gone by this point. Set the flag and the rest should match.
4495+
unsigned valMajor, valMinor;
4496+
ValCtx.DxilMod.GetValidatorVersion(valMajor, valMinor);
4497+
if (DXIL::CompareVersions(valMajor, valMinor, 1, 5) >= 0 &&
4498+
DXIL::CompareVersions(valMajor, valMinor, 1, 8) < 0 &&
4499+
ValCtx.DxilMod.m_ShaderFlags.GetRaytracingTier1_1() &&
4500+
!calcFlags.GetRaytracingTier1_1()) {
4501+
calcFlags.SetRaytracingTier1_1(true);
4502+
}
4503+
44904504
const uint64_t mask = ShaderFlags::GetShaderFlagsRawForCollection();
44914505
uint64_t declaredFlagsRaw = ValCtx.DxilMod.m_ShaderFlags.GetShaderFlagsRaw();
44924506
uint64_t calcFlagsRaw = calcFlags.GetShaderFlagsRaw();

tools/clang/test/HLSLFileCheck/shader_targets/raytracing/subobjects_raytracingPipelineConfig1.hlsl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
// RUN: %dxilver 1.5 | %dxc -T lib_6_3 %s | FileCheck %s
1+
// RUN: %dxilver 1.5 | %dxc -T lib_6_3 -validator-version 1.5 %s | FileCheck %s -check-prefixes=CHECK,CHECK15
2+
// RUN: %dxilver 1.8 | %dxc -T lib_6_3 -validator-version 1.8 %s | FileCheck %s -check-prefixes=CHECK,CHECK18
23

34
// RaytracingTier1_1 flag should not be set on the module based on subobjects.
4-
// This is not even set for compatibility with validator 1.7 because that
5-
// validator did not validate the flags.
6-
// CHECK-NOT: Raytracing tier 1.1 features
5+
// CHECK18-NOT: Raytracing tier 1.1 features
6+
// CHECK15: Raytracing tier 1.1 features
77

88
// CHECK: ; GlobalRootSignature grs = { <48 bytes> };
99
// CHECK: ; StateObjectConfig soc = { STATE_OBJECT_FLAG_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS | STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS };

0 commit comments

Comments
 (0)