diff --git a/src/xenia/gpu/gpu_flags.cc b/src/xenia/gpu/gpu_flags.cc index 9ed9335fa..c877ba766 100644 --- a/src/xenia/gpu/gpu_flags.cc +++ b/src/xenia/gpu/gpu_flags.cc @@ -59,11 +59,11 @@ DEFINE_bool( "when MSAA is used with fullscreen passes.", "GPU"); -DEFINE_bool(query_occlusion_batched, false, - "Increment the sample count total by a fixed amount on every " - "EVENT_WRITE_ZPD. This provides an approximate batched occlusion " - "query implementation for many titles.", - "GPU"); +DEFINE_int32(query_occlusion_querybatch_range, 0, + "Range of fake ZPD sample count values to cycle for titles that " + "use D3D QueryBatch. 0 disables this behavior entirely. Any non-" + "zero values should only be used if required for specific titles.", + "GPU"); DEFINE_int32(query_occlusion_sample_lower_threshold, 80, "If set to -1 no sample counts are written, games may hang. Else, " "the sample count of every tile will be incremented on every " diff --git a/src/xenia/gpu/gpu_flags.h b/src/xenia/gpu/gpu_flags.h index 1778371eb..ac24c507d 100644 --- a/src/xenia/gpu/gpu_flags.h +++ b/src/xenia/gpu/gpu_flags.h @@ -26,7 +26,7 @@ DECLARE_bool(non_seamless_cube_map); DECLARE_bool(half_pixel_offset); -DECLARE_bool(query_occlusion_batched); +DECLARE_int32(query_occlusion_querybatch_range); DECLARE_int32(query_occlusion_sample_lower_threshold); diff --git a/src/xenia/gpu/pm4_command_processor_implement.h b/src/xenia/gpu/pm4_command_processor_implement.h index 62b6b07cc..870e85833 100644 --- a/src/xenia/gpu/pm4_command_processor_implement.h +++ b/src/xenia/gpu/pm4_command_processor_implement.h @@ -988,11 +988,18 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_EVENT_WRITE_ZPD( // every query. Each ISSUE snapshots the sample count into a new slot and // recovers the total by looking at differences between slots. // END detection isn't sufficient here. - if (cvars::query_occlusion_batched) { + if (cvars::query_occlusion_querybatch_range > 0) { // Mimic batched behavior by reporting a running count and writing it on // every event. - const uint32_t step = std::max(uint32_t(1), samples); - batched_samples = std::min(batched_samples, UINT32_MAX - step) + step; + const uint32_t base = + static_cast(cvars::query_occlusion_sample_lower_threshold); + const uint32_t range = + static_cast(cvars::query_occlusion_querybatch_range); + if (batched_samples < base || batched_samples - base + 1 >= range) { + batched_samples = base; + } else { + ++batched_samples; + } pSampleCounts->ZPass_A = batched_samples; pSampleCounts->Total_A = batched_samples; } else if (is_end_via_z_pass || is_end_via_z_fail) {