Skip to content

Commit 68e037d

Browse files
committed
attempted crash fix kai
1 parent 82887e5 commit 68e037d

1 file changed

Lines changed: 99 additions & 26 deletions

File tree

src/games/kai-vanillaplus/addon.cpp

Lines changed: 99 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ constexpr uint32_t kLightingSceneCbRegister = 0u;
6060
constexpr uint32_t kLightingXeGtaoRegister = 22u;
6161
constexpr uint32_t kXeGtaoPushConstantsLayoutParam = 4u;
6262
constexpr uint64_t kSceneCbMinimumBytes = 95u * 16u;
63+
constexpr uint64_t kSceneCbMaximumBytes = 64u * 1024u;
6364
constexpr uint64_t kXeGTAODeferredStartupGuardFrames = 3u;
6465
constexpr uint64_t kXeGTAOStartupDispatchGuardFrames = 16u;
6566
constexpr uint64_t kXeGTAOStartupRequireCurrentSceneCbvFrames = 64u;
67+
constexpr uint64_t kXeGTAOFallbackStartupQuarantineFrames = 240u;
6668
constexpr uint64_t kXeGTAOClearStartupGuardFrames = 8u;
6769
constexpr uint64_t kXeGTAOResizeDispatchGuardFrames = 4u;
6870
constexpr uint64_t kXeGTAOFallbackSceneCbvMaxAgeFrames = 2u;
@@ -367,6 +369,7 @@ float xegtao_depth_mip_sampling_offset = 3.3f;
367369
float xegtao_denoise_blur_beta = 8.f;
368370
float xegtao_debug_mode = 0.f;
369371
float xegtao_runtime_debug_logging = 0.f;
372+
float xegtao_enable_fallbacks = 1.f;
370373
float xegtao_foliage_ao_blend = 1.0f;
371374
float xegtao_foliage_mask_method = 0.f; // 0=SSS parity(t1 strict), 1=legacy broad(t1), 2=t10 strict
372375

@@ -2095,6 +2098,10 @@ uint32_t ClampBooleanToggle(float value) {
20952098
return static_cast<uint32_t>(std::clamp(std::round(value), 0.f, 1.f));
20962099
}
20972100

2101+
bool AreXeGTAOFallbacksEnabled() {
2102+
return ClampBooleanToggle(xegtao_enable_fallbacks) != 0u;
2103+
}
2104+
20982105
bool IsXeGTAOFixLevelAtLeast(XeGTAOFixMode level) {
20992106
return ClampXeGTAOFixMode() >= static_cast<uint32_t>(level);
21002107
}
@@ -2135,47 +2142,72 @@ float ClampXeGTAOIsFastJitterAmount() {
21352142
return std::clamp(xegtao_isfast_jitter_amount, 0.f, 1.f);
21362143
}
21372144

2138-
bool IsSceneCbvCandidateValid(reshade::api::device* device, const reshade::api::buffer_range& range) {
2139-
if (device == nullptr) return false;
2140-
if (range.buffer.handle == 0u) return false;
2145+
bool TryNormalizeSceneCbvRange(
2146+
reshade::api::device* device,
2147+
const reshade::api::buffer_range& input,
2148+
reshade::api::buffer_range* output) {
2149+
if (device == nullptr || output == nullptr) return false;
2150+
if (input.buffer.handle == 0u) return false;
21412151

2142-
const auto desc = device->get_resource_desc(range.buffer);
2152+
const auto desc = device->get_resource_desc(input.buffer);
21432153
if (desc.type != reshade::api::resource_type::buffer) return false;
21442154
if (desc.buffer.size < kSceneCbMinimumBytes) return false;
2145-
if (range.offset >= desc.buffer.size) return false;
2155+
if (input.offset >= desc.buffer.size) return false;
21462156

2147-
// In D3D11-style paths size may be UINT64_MAX (whole buffer) or 0 (unknown),
2148-
// so only validate explicit ranges.
2149-
if (range.size != 0u && range.size != UINT64_MAX) {
2150-
if (range.size < kSceneCbMinimumBytes) return false;
2151-
if (range.size > desc.buffer.size) return false;
2152-
if (range.offset > desc.buffer.size - range.size) return false;
2153-
}
2157+
const uint64_t available_bytes = desc.buffer.size - input.offset;
2158+
const bool has_unknown_size = input.size == 0u || input.size == UINT64_MAX;
2159+
if (!has_unknown_size && input.size < kSceneCbMinimumBytes) return false;
2160+
2161+
uint64_t normalized_size = has_unknown_size ? available_bytes : input.size;
2162+
if (normalized_size > available_bytes) normalized_size = available_bytes;
2163+
if (normalized_size > kSceneCbMaximumBytes) normalized_size = kSceneCbMaximumBytes;
21542164

2165+
// Constant buffer payload is 16-byte aligned; align down to keep updates valid.
2166+
normalized_size &= ~0xFu;
2167+
if (normalized_size < kSceneCbMinimumBytes) return false;
2168+
2169+
reshade::api::buffer_range normalized = input;
2170+
normalized.size = normalized_size;
2171+
*output = normalized;
21552172
return true;
21562173
}
21572174

2175+
bool IsSceneCbvCandidateValid(reshade::api::device* device, const reshade::api::buffer_range& range) {
2176+
reshade::api::buffer_range normalized = {};
2177+
return TryNormalizeSceneCbvRange(device, range, &normalized);
2178+
}
2179+
21582180
void CacheFallbackSceneCbv(reshade::api::command_list* cmd_list, const reshade::api::buffer_range& range) {
2181+
if (!AreXeGTAOFallbacksEnabled()) return;
21592182
if (cmd_list == nullptr) return;
21602183
auto* device = cmd_list->get_device();
21612184
if (device == nullptr) return;
21622185

21632186
auto* data = device->get_private_data<DeviceData>();
21642187
if (data == nullptr) return;
21652188

2166-
if (range.buffer.handle == 0u) return;
2167-
if (!IsSceneCbvCandidateValid(device, range)) return;
2168-
data->fallback_scene_cbv = range;
2189+
// Startup quarantine: keep fallback paths dormant during unstable bootstrap.
2190+
if (data->present_frame_index < kXeGTAOFallbackStartupQuarantineFrames) return;
2191+
2192+
reshade::api::buffer_range normalized = {};
2193+
if (!TryNormalizeSceneCbvRange(device, range, &normalized)) return;
2194+
data->fallback_scene_cbv = normalized;
21692195
data->fallback_scene_cbv_seen = true;
21702196
data->fallback_scene_cbv_frame = data->present_frame_index;
21712197
}
21722198

21732199
bool TryAdoptFallbackSceneCbv(reshade::api::device* device, DeviceData* data) {
21742200
if (device == nullptr || data == nullptr) return false;
2201+
if (!AreXeGTAOFallbacksEnabled()) return false;
2202+
2203+
// Startup quarantine: avoid binding fallback CBV until runtime settles.
2204+
if (data->present_frame_index < kXeGTAOFallbackStartupQuarantineFrames) return false;
21752205

2206+
reshade::api::buffer_range normalized_current = {};
21762207
if (data->captured_scene_cbv_valid
21772208
&& data->captured_scene_cbv_source == XeGTAOSceneCbvSource::kCurrentLighting
2178-
&& IsSceneCbvCandidateValid(device, data->captured_scene_cbv)) {
2209+
&& TryNormalizeSceneCbvRange(device, data->captured_scene_cbv, &normalized_current)) {
2210+
data->captured_scene_cbv = normalized_current;
21792211
return true;
21802212
}
21812213

@@ -2193,9 +2225,12 @@ bool TryAdoptFallbackSceneCbv(reshade::api::device* device, DeviceData* data) {
21932225
&& data->present_frame_index - data->fallback_scene_cbv_frame > kXeGTAOFallbackSceneCbvMaxAgeFrames) {
21942226
return false;
21952227
}
2196-
if (!IsSceneCbvCandidateValid(device, data->fallback_scene_cbv)) return false;
2228+
reshade::api::buffer_range normalized_fallback = {};
2229+
if (!TryNormalizeSceneCbvRange(device, data->fallback_scene_cbv, &normalized_fallback)) return false;
21972230

2198-
data->captured_scene_cbv = data->fallback_scene_cbv;
2231+
data->fallback_scene_cbv = normalized_fallback;
2232+
2233+
data->captured_scene_cbv = normalized_fallback;
21992234
data->captured_scene_cbv_valid = true;
22002235
data->captured_scene_cbv_frame = data->present_frame_index;
22012236
data->captured_scene_cbv_source = XeGTAOSceneCbvSource::kFallback;
@@ -3395,7 +3430,12 @@ bool RunXeGTAOForFrame(
33953430
|| data->captured_scene_cbv.buffer.handle == 0u
33963431
|| !IsSceneCbvCandidateValid(device, data->captured_scene_cbv)) {
33973432
std::string reason = "lighting scene CB b0 is not captured";
3398-
if (!data->fallback_scene_cbv_seen) {
3433+
if (data->present_frame_index < kXeGTAOFallbackStartupQuarantineFrames) {
3434+
reason += std::format(
3435+
" (fallback startup quarantine active: frame {} < {})",
3436+
data->present_frame_index,
3437+
kXeGTAOFallbackStartupQuarantineFrames);
3438+
} else if (!data->fallback_scene_cbv_seen) {
33993439
reason += " (tracked + fallback cache missing)";
34003440
} else if (!IsSceneCbvCandidateValid(device, data->fallback_scene_cbv)) {
34013441
reason += " (fallback cache rejected by validation)";
@@ -3454,6 +3494,12 @@ bool RunXeGTAOForFrame(
34543494
note_predispatch_reject("lighting scene CB b0 became invalid before dispatch");
34553495
return fail("lighting scene CB b0 became invalid before dispatch");
34563496
}
3497+
reshade::api::buffer_range normalized_scene_cbv = {};
3498+
if (!TryNormalizeSceneCbvRange(device, data->captured_scene_cbv, &normalized_scene_cbv)) {
3499+
note_predispatch_reject("lighting scene CB b0 range is unsafe for dispatch");
3500+
return fail("lighting scene CB b0 range is unsafe for dispatch");
3501+
}
3502+
data->captured_scene_cbv = normalized_scene_cbv;
34573503
const uint32_t fix_mode = ClampXeGTAOFixMode();
34583504
const bool l5_pass_isolation =
34593505
fix_mode >= static_cast<uint32_t>(XeGTAOFixMode::kPassIsolationDiagnostics);
@@ -3899,8 +3945,9 @@ void CaptureTrackedConstantBuffer(
38993945
if (device == nullptr) return;
39003946
auto* data = device->get_private_data<DeviceData>();
39013947
if (data == nullptr) return;
3902-
if (!IsSceneCbvCandidateValid(device, range)) return;
3903-
data->captured_scene_cbv = range;
3948+
reshade::api::buffer_range normalized = {};
3949+
if (!TryNormalizeSceneCbvRange(device, range, &normalized)) return;
3950+
data->captured_scene_cbv = normalized;
39043951
data->captured_scene_cbv_valid = true;
39053952
data->captured_scene_cbv_frame = data->present_frame_index;
39063953
data->captured_scene_cbv_source = XeGTAOSceneCbvSource::kCurrentLighting;
@@ -4291,10 +4338,11 @@ void ResolveXeGTAOInputsFromCurrentBindings(reshade::api::command_list* cmd_list
42914338
if (kLightingSceneCbRegister >= range.dx_register_index
42924339
&& kLightingSceneCbRegister < (range.dx_register_index + range.count)) {
42934340
reshade::api::buffer_range cbv = {};
4341+
reshade::api::buffer_range normalized_cbv = {};
42944342
const uint32_t descriptor_index = kLightingSceneCbRegister - range.dx_register_index;
42954343
if (TryGetBufferRangeFromBoundDescriptorTable(device, table, range, descriptor_index, &cbv)
4296-
&& IsSceneCbvCandidateValid(device, cbv)) {
4297-
data->captured_scene_cbv = cbv;
4344+
&& TryNormalizeSceneCbvRange(device, cbv, &normalized_cbv)) {
4345+
data->captured_scene_cbv = normalized_cbv;
42984346
data->captured_scene_cbv_valid = true;
42994347
data->captured_scene_cbv_frame = data->present_frame_index;
43004348
data->captured_scene_cbv_source = XeGTAOSceneCbvSource::kCurrentLighting;
@@ -5297,14 +5345,15 @@ void OnPresentAdvanceFrame(
52975345
AddonLog(
52985346
reshade::log::level::info,
52995347
std::format(
5300-
"XeGTAO startup mode: fix={}, l5(prefilter={}, main={}, denoise={}, composite={}), probeA={}, probeB={}",
5348+
"XeGTAO startup mode: fix={}, l5(prefilter={}, main={}, denoise={}, composite={}), probeA={}, probeB={}, fallbacks={}",
53015349
GetXeGTAOFixModeName(ClampXeGTAOFixMode()),
53025350
ClampBooleanToggle(xegtao_fix_l5_prefilter),
53035351
ClampBooleanToggle(xegtao_fix_l5_main),
53045352
ClampBooleanToggle(xegtao_fix_l5_denoise),
53055353
ClampBooleanToggle(xegtao_fix_l5_composite),
53065354
ClampBooleanToggle(xegtao_probe_a_dispatch_no_t22),
5307-
ClampBooleanToggle(xegtao_probe_b_t22_no_dispatch)));
5355+
ClampBooleanToggle(xegtao_probe_b_t22_no_dispatch),
5356+
ClampBooleanToggle(xegtao_enable_fallbacks)));
53085357
}
53095358
const uint64_t frame = data->present_frame_index;
53105359
if (data->xegtao_deferred_dispatch_pending
@@ -5355,7 +5404,9 @@ void OnPresentAdvanceFrame(
53555404
reshade::api::resource_view deferred_mrt_normal_srv =
53565405
data->xegtao_deferred_mrt_normal_srv;
53575406
bool deferred_mrt_normal_valid = deferred_mrt_normal_srv.handle != 0u;
5358-
if (!deferred_mrt_normal_valid && fallback_lighting_mrt0.handle != 0u) {
5407+
if (!deferred_mrt_normal_valid
5408+
&& AreXeGTAOFallbacksEnabled()
5409+
&& fallback_lighting_mrt0.handle != 0u) {
53595410
deferred_mrt_normal_srv = fallback_lighting_mrt0;
53605411
deferred_mrt_normal_valid = true;
53615412
}
@@ -5366,6 +5417,14 @@ void OnPresentAdvanceFrame(
53665417
data->xegtao_deferred_scene_cbv_valid
53675418
&& data->xegtao_deferred_scene_cbv.buffer.handle != 0u
53685419
&& IsSceneCbvCandidateValid(device, data->xegtao_deferred_scene_cbv);
5420+
if (deferred_scene_cbv_valid) {
5421+
reshade::api::buffer_range normalized_deferred_scene_cbv = {};
5422+
if (TryNormalizeSceneCbvRange(device, data->xegtao_deferred_scene_cbv, &normalized_deferred_scene_cbv)) {
5423+
data->xegtao_deferred_scene_cbv = normalized_deferred_scene_cbv;
5424+
} else {
5425+
deferred_scene_cbv_valid = false;
5426+
}
5427+
}
53695428

53705429
if (!deferred_scene_cbv_valid && data->fallback_scene_cbv_seen) {
53715430
data->captured_scene_cbv = data->xegtao_deferred_scene_cbv;
@@ -5536,6 +5595,7 @@ void OnPresentAdvanceFrame(
55365595
xegtao_probe_a_dispatch_no_t22 = static_cast<float>(ClampBooleanToggle(xegtao_probe_a_dispatch_no_t22));
55375596
xegtao_probe_b_t22_no_dispatch = static_cast<float>(ClampBooleanToggle(xegtao_probe_b_t22_no_dispatch));
55385597
xegtao_runtime_debug_logging = static_cast<float>(ClampBooleanToggle(xegtao_runtime_debug_logging));
5598+
xegtao_enable_fallbacks = static_cast<float>(ClampBooleanToggle(xegtao_enable_fallbacks));
55395599
g_enable_runtime_addon_logs.store(xegtao_runtime_debug_logging >= 0.5f, std::memory_order_relaxed);
55405600
xegtao_denoiser_mode = 0.f;
55415601
xegtao_isfast_jitter_amount = std::clamp(xegtao_isfast_jitter_amount, 0.f, 1.f);
@@ -6108,6 +6168,19 @@ renodx::utils::settings::Settings settings = {
61086168
.is_visible = []() { return IsAdvancedSettingsMode(); },
61096169
},
61106170
new renodx::utils::settings::Setting{
6171+
.key = "XeGTAOFallbacks",
6172+
.binding = &xegtao_enable_fallbacks,
6173+
.value_type = renodx::utils::settings::SettingValueType::BOOLEAN,
6174+
.default_value = 1.f,
6175+
.label = "Fallbacks",
6176+
.section = "XeGTAO",
6177+
.tooltip =
6178+
"Off disables XeGTAO fallback sources (fallback scene CBV and deferred MRT-normal fallback). On enables those fallback paths.",
6179+
.labels = {"Off", "On"},
6180+
.is_enabled = []() { return xegtao_mode >= 0.5f; },
6181+
.is_visible = []() { return true; },
6182+
},
6183+
new renodx::utils::settings::Setting{
61116184
.key = "XeGTAORuntimeDebugLogging",
61126185
.binding = &xegtao_runtime_debug_logging,
61136186
.value_type = renodx::utils::settings::SettingValueType::BOOLEAN,

0 commit comments

Comments
 (0)