[GPU] Simplify ZPD cvars
This commit is contained in:
committed by
Radosław Gliński
parent
fbd620c22b
commit
73945c06d7
@@ -58,7 +58,10 @@ DEFINE_string(
|
||||
" though some effects may look slightly wrong.\n"
|
||||
" fast: Ask the GPU but don't wait for the answer. Writes a cached\n"
|
||||
" result immediately and updates it when the GPU catches up.\n"
|
||||
" (default)\n"
|
||||
" Cached results bias toward visible when guessing. (default)\n"
|
||||
" fast-alt: Variant of fast mode that keeps cached zero results for\n"
|
||||
" unresolved reports. May improve effects relying on precise\n"
|
||||
" visibility, but may be less stable for occlusion culling.\n"
|
||||
" strict: Ask the GPU and wait for the real result before continuing.\n"
|
||||
" Most accurate, but may be somewhat less performant.",
|
||||
"GPU");
|
||||
@@ -130,6 +133,8 @@ ZPDMode GetZPDMode() {
|
||||
return ZPDMode::kFake;
|
||||
} else if (mode == "strict") {
|
||||
return ZPDMode::kStrict;
|
||||
} else if (mode == "fast-alt") {
|
||||
return ZPDMode::kFastAlt;
|
||||
}
|
||||
return ZPDMode::kFast;
|
||||
}
|
||||
@@ -968,7 +973,7 @@ bool CommandProcessor::BeginZPDReport(uint32_t report_address) {
|
||||
PendingZPDSlot pending_slot = GetPendingZPDSlot(slot_base, end_record);
|
||||
|
||||
if (pending_slot.report_handle != kInvalidReportHandle) {
|
||||
if (GetZPDMode() == ZPDMode::kFast) {
|
||||
if (GetZPDMode() == ZPDMode::kFast || GetZPDMode() == ZPDMode::kFastAlt) {
|
||||
if (pending_slot.has_cached_delta) {
|
||||
carried_cached_delta = pending_slot.cached_delta;
|
||||
has_carried_cached_delta = true;
|
||||
@@ -1008,7 +1013,7 @@ bool CommandProcessor::BeginZPDReport(uint32_t report_address) {
|
||||
// By default, BEGIN drops the cached value so an orphaned END doesn't replay
|
||||
// something from a prior lifetime. The alternate fast path keeps it around
|
||||
// long enough for an async zero to help the next unresolved write.
|
||||
if (!cvars::occlusion_query_fast_preserve_cached_zero) {
|
||||
if (GetZPDMode() != ZPDMode::kFastAlt) {
|
||||
fast_zpd_report_cached_values_.erase(end_record);
|
||||
}
|
||||
|
||||
@@ -1136,7 +1141,7 @@ bool CommandProcessor::EndZPDReport(uint32_t report_address,
|
||||
WriteZPDReport(0, stored_end_record, 0, begin_value, false);
|
||||
}
|
||||
|
||||
if (GetZPDMode() == ZPDMode::kFast) {
|
||||
if (GetZPDMode() == ZPDMode::kFast || GetZPDMode() == ZPDMode::kFastAlt) {
|
||||
bool write_begin = begin_record && report_record_base &&
|
||||
begin_record != report_record_base;
|
||||
// Unknown still means visible in fast mode. Reusing cached zeroes can help
|
||||
@@ -1147,8 +1152,7 @@ bool CommandProcessor::EndZPDReport(uint32_t report_address,
|
||||
if (!resolved_immediately) {
|
||||
speculative = 1;
|
||||
if (has_cached_delta &&
|
||||
(cached_delta != 0 ||
|
||||
cvars::occlusion_query_fast_preserve_cached_zero)) {
|
||||
(cached_delta != 0 || GetZPDMode() == ZPDMode::kFastAlt)) {
|
||||
speculative = cached_delta;
|
||||
}
|
||||
}
|
||||
@@ -1201,7 +1205,7 @@ void CommandProcessor::OpenQuerySegment(bool can_close_submission) {
|
||||
case QueryOpenResult::kDeferred:
|
||||
return;
|
||||
case QueryOpenResult::kPoolExhausted: {
|
||||
if (GetZPDMode() == ZPDMode::kFast) {
|
||||
if (GetZPDMode() == ZPDMode::kFast || GetZPDMode() == ZPDMode::kFastAlt) {
|
||||
// Fast mode favors forward progress over accuracy. Keep a minimal
|
||||
// accumulated value instead of waiting for a slot to become available.
|
||||
auto it = logical_zpd_reports_.find(zpd_active_segment_.report_handle);
|
||||
|
||||
@@ -45,9 +45,10 @@ enum class ReadbackResolveMode {
|
||||
|
||||
// Occlusion queries - ZPD report mode.
|
||||
enum class ZPDMode {
|
||||
kFake, // Fake sample counts, no real GPU queries (fake)
|
||||
kFast, // Real queries with speculative cached writes (fast)
|
||||
kStrict, // Real queries, waits before writeback (strict)
|
||||
kFake, // Fake sample counts, no real GPU queries (fake)
|
||||
kFast, // Real queries with speculative cached writes (fast)
|
||||
kFastAlt, // Fast queries, but preserves cached zeroes (fast-alt)
|
||||
kStrict, // Real queries, waits before writeback (strict)
|
||||
};
|
||||
|
||||
void SaveGPUSetting(GPUSetting setting, uint64_t value);
|
||||
@@ -324,8 +325,7 @@ class CommandProcessor {
|
||||
uint32_t begin_value = 0;
|
||||
uint32_t pending_segments = 0;
|
||||
// Last known delta. Carried forward on forced close so slot doesn't
|
||||
// briefly look fully occluded. 0 is a valid delta if the alternate fast
|
||||
// cvar is enabled.
|
||||
// briefly look fully occluded. 0 is a valid delta for alternate fast path.
|
||||
uint32_t cached_delta = 0;
|
||||
bool has_cached_delta = false;
|
||||
bool ended = false;
|
||||
|
||||
@@ -5312,7 +5312,7 @@ CommandProcessor::QueryOpenResult D3D12CommandProcessor::OpenZPDQuery(
|
||||
bool waited_for_submission = false;
|
||||
|
||||
if (is_pool_exhausted) {
|
||||
if (GetZPDMode() == ZPDMode::kFast) {
|
||||
if (GetZPDMode() == ZPDMode::kFast || GetZPDMode() == ZPDMode::kFastAlt) {
|
||||
return QueryOpenResult::kPoolExhausted;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,13 +71,6 @@ DEFINE_int32(occlusion_query_fake_upper_threshold, 100,
|
||||
"Keep this higher than occlusion_query_fake_lower_threshold.\n"
|
||||
"Ignored if occlusion_query_fake_lower_threshold is -1.",
|
||||
"GPU");
|
||||
DEFINE_bool(occlusion_query_fast_preserve_cached_zero, false,
|
||||
"Alternate fast ZPD behavior that allows saved zero results to be "
|
||||
"used for unresolved fast writes instead of forcing them visible.\n"
|
||||
"This can materially improve flare accuracy in titles that might "
|
||||
"otherwise need strict mode, but it also tends to break occlusion "
|
||||
"culling in some titles.",
|
||||
"GPU");
|
||||
DEFINE_int32(occlusion_query_querybatch_range, 0,
|
||||
"Range of fake sample count values to walk for titles using the "
|
||||
"D3D QueryBatch standard before wrapping back to "
|
||||
@@ -86,7 +79,7 @@ DEFINE_int32(occlusion_query_querybatch_range, 0,
|
||||
"unless necessary for a specific title.",
|
||||
"GPU");
|
||||
DEFINE_double(
|
||||
occlusion_query_sample_count_saturation, 1.0,
|
||||
occlusion_query_saturation, 1.0,
|
||||
"Compress higher occlusion query sample counts before guest writeback.\n"
|
||||
"This can be useful if effects such as lens flares appear too strong.\n"
|
||||
"1.0 = default behavior\n"
|
||||
|
||||
@@ -32,11 +32,9 @@ DECLARE_int32(occlusion_query_fake_lower_threshold);
|
||||
|
||||
DECLARE_int32(occlusion_query_fake_upper_threshold);
|
||||
|
||||
DECLARE_bool(occlusion_query_fast_preserve_cached_zero);
|
||||
|
||||
DECLARE_int32(occlusion_query_querybatch_range);
|
||||
|
||||
DECLARE_double(occlusion_query_sample_count_saturation);
|
||||
DECLARE_double(occlusion_query_saturation);
|
||||
|
||||
DECLARE_int32(anisotropic_override);
|
||||
|
||||
|
||||
@@ -1011,7 +1011,7 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_EVENT_WRITE_ZPD(
|
||||
// No logical report is active for this slot, so this is likely an
|
||||
// orphaned END. In fast mode, replay the last cached delta so polling
|
||||
// code does not sit on the sentinel forever.
|
||||
if (GetZPDMode() == ZPDMode::kFast) {
|
||||
if (GetZPDMode() == ZPDMode::kFast || GetZPDMode() == ZPDMode::kFastAlt) {
|
||||
uint32_t cached_delta = 1;
|
||||
auto cache_it = fast_zpd_report_cached_values_.find(report_record_base);
|
||||
if (cache_it != fast_zpd_report_cached_values_.end()) {
|
||||
|
||||
@@ -3318,7 +3318,8 @@ CommandProcessor::QueryOpenResult VulkanCommandProcessor::OpenZPDQuery(
|
||||
is_pool_exhausted = !zpd_host_query_pool_->has_free_indices();
|
||||
}
|
||||
|
||||
if (is_pool_exhausted && GetZPDMode() == ZPDMode::kFast) {
|
||||
if (is_pool_exhausted &&
|
||||
(GetZPDMode() == ZPDMode::kFast || GetZPDMode() == ZPDMode::kFastAlt)) {
|
||||
return QueryOpenResult::kPoolExhausted;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,8 +102,7 @@ struct XenosZPDReport {
|
||||
|
||||
static uint32_t SaturateSampleCount(uint32_t sample_count) {
|
||||
double saturation = std::clamp(
|
||||
static_cast<double>(cvars::occlusion_query_sample_count_saturation),
|
||||
0.0, 1.0);
|
||||
static_cast<double>(cvars::occlusion_query_saturation), 0.0, 1.0);
|
||||
|
||||
if (sample_count == 0 || saturation >= 1.0) {
|
||||
return sample_count;
|
||||
|
||||
Reference in New Issue
Block a user