Reaper: Setup settings and final tuning.
This commit is contained in:
parent
d8ad6aa187
commit
954ad2a61e
|
@ -59,6 +59,7 @@ void LogSettings() {
|
||||||
log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
|
log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
|
||||||
log_setting("Renderer_UseAssemblyShaders", values.use_assembly_shaders.GetValue());
|
log_setting("Renderer_UseAssemblyShaders", values.use_assembly_shaders.GetValue());
|
||||||
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
|
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
|
||||||
|
log_setting("Renderer_UseGarbageCollection", values.use_caches_gc.GetValue());
|
||||||
log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
|
log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
|
||||||
log_setting("Audio_OutputEngine", values.sink_id);
|
log_setting("Audio_OutputEngine", values.sink_id);
|
||||||
log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
|
log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
|
||||||
|
@ -141,6 +142,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||||
values.use_assembly_shaders.SetGlobal(true);
|
values.use_assembly_shaders.SetGlobal(true);
|
||||||
values.use_asynchronous_shaders.SetGlobal(true);
|
values.use_asynchronous_shaders.SetGlobal(true);
|
||||||
values.use_fast_gpu_time.SetGlobal(true);
|
values.use_fast_gpu_time.SetGlobal(true);
|
||||||
|
values.use_caches_gc.SetGlobal(true);
|
||||||
values.bg_red.SetGlobal(true);
|
values.bg_red.SetGlobal(true);
|
||||||
values.bg_green.SetGlobal(true);
|
values.bg_green.SetGlobal(true);
|
||||||
values.bg_blue.SetGlobal(true);
|
values.bg_blue.SetGlobal(true);
|
||||||
|
|
|
@ -152,6 +152,7 @@ struct Values {
|
||||||
Setting<bool> use_assembly_shaders;
|
Setting<bool> use_assembly_shaders;
|
||||||
Setting<bool> use_asynchronous_shaders;
|
Setting<bool> use_asynchronous_shaders;
|
||||||
Setting<bool> use_fast_gpu_time;
|
Setting<bool> use_fast_gpu_time;
|
||||||
|
Setting<bool> use_caches_gc;
|
||||||
|
|
||||||
Setting<float> bg_red;
|
Setting<float> bg_red;
|
||||||
Setting<float> bg_green;
|
Setting<float> bg_green;
|
||||||
|
|
|
@ -350,9 +350,10 @@ BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::TickFrame() {
|
void BufferCache<P>::TickFrame() {
|
||||||
|
const bool enabled_gc = Settings::values.use_caches_gc.GetValue();
|
||||||
SCOPE_EXIT({
|
SCOPE_EXIT({
|
||||||
++frame_tick;
|
++frame_tick;
|
||||||
delayed_destruction_ring.Tick();
|
delayed_destruction_ring.Tick();
|
||||||
});
|
});
|
||||||
// Calculate hits and shots and move hit bits to the right
|
// Calculate hits and shots and move hit bits to the right
|
||||||
const u32 hits = std::reduce(uniform_cache_hits.begin(), uniform_cache_hits.end());
|
const u32 hits = std::reduce(uniform_cache_hits.begin(), uniform_cache_hits.end());
|
||||||
|
@ -367,7 +368,7 @@ void BufferCache<P>::TickFrame() {
|
||||||
const bool skip_preferred = hits * 256 < shots * 251;
|
const bool skip_preferred = hits * 256 < shots * 251;
|
||||||
uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0;
|
uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0;
|
||||||
|
|
||||||
const bool activate_gc = total_used_memory >= expected_memory;
|
const bool activate_gc = enabled_gc && total_used_memory >= expected_memory;
|
||||||
if (!activate_gc) {
|
if (!activate_gc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,10 @@ enum class ImageFlagBits : u32 {
|
||||||
Picked = 1 << 7, ///< Temporary flag to mark the image as picked
|
Picked = 1 << 7, ///< Temporary flag to mark the image as picked
|
||||||
|
|
||||||
// Garbage Collection Flags
|
// Garbage Collection Flags
|
||||||
BadOverlap = 1 << 8, ///< This image overlaps other but doesn't fit, has higher
|
BadOverlap = 1 << 8, ///< This image overlaps other but doesn't fit, has higher
|
||||||
///< garbage collection priority
|
///< garbage collection priority
|
||||||
Alias = 1 << 9, ///< This image has aliases and has priority on garbage
|
Alias = 1 << 9, ///< This image has aliases and has priority on garbage
|
||||||
///< collection
|
///< collection
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
|
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "video_core/compatible_formats.h"
|
#include "video_core/compatible_formats.h"
|
||||||
#include "video_core/delayed_destruction_ring.h"
|
#include "video_core/delayed_destruction_ring.h"
|
||||||
#include "video_core/dirty_flags.h"
|
#include "video_core/dirty_flags.h"
|
||||||
|
@ -384,6 +385,15 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void TextureCache<P>::TickFrame() {
|
void TextureCache<P>::TickFrame() {
|
||||||
|
const bool enabled_gc = Settings::values.use_caches_gc.GetValue();
|
||||||
|
if (!enabled_gc) {
|
||||||
|
// @Note(Blinkhawk): compile error with SCOPE_EXIT on msvc.
|
||||||
|
sentenced_images.Tick();
|
||||||
|
sentenced_framebuffers.Tick();
|
||||||
|
sentenced_image_view.Tick();
|
||||||
|
++frame_tick;
|
||||||
|
return;
|
||||||
|
}
|
||||||
const bool high_priority_mode = total_used_memory >= expected_memory;
|
const bool high_priority_mode = total_used_memory >= expected_memory;
|
||||||
const bool aggressive_mode = total_used_memory >= critical_memory;
|
const bool aggressive_mode = total_used_memory >= critical_memory;
|
||||||
const u64 ticks_to_destroy = high_priority_mode ? 60 : 100;
|
const u64 ticks_to_destroy = high_priority_mode ? 60 : 100;
|
||||||
|
@ -397,22 +407,20 @@ void TextureCache<P>::TickFrame() {
|
||||||
}
|
}
|
||||||
const auto [image_id, image] = *deletion_iterator;
|
const auto [image_id, image] = *deletion_iterator;
|
||||||
const bool is_alias = True(image->flags & ImageFlagBits::Alias);
|
const bool is_alias = True(image->flags & ImageFlagBits::Alias);
|
||||||
if (is_alias && image->aliased_images.size() <= 1) {
|
|
||||||
++deletion_iterator;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap);
|
const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap);
|
||||||
const bool must_download = image->IsSafeDownload();
|
const bool must_download = image->IsSafeDownload();
|
||||||
const u64 ticks_needed = is_bad_overlap ? ticks_to_destroy >> 4 : ticks_to_destroy;
|
bool should_care = is_bad_overlap || is_alias || (high_priority_mode && !must_download);
|
||||||
const bool should_care =
|
const u64 ticks_needed =
|
||||||
aggressive_mode || is_bad_overlap || is_alias || (high_priority_mode && !must_download);
|
is_bad_overlap
|
||||||
|
? ticks_to_destroy >> 4
|
||||||
|
: ((should_care && aggressive_mode) ? ticks_to_destroy >> 1 : ticks_to_destroy);
|
||||||
|
should_care |= aggressive_mode;
|
||||||
if (should_care && image->frame_tick + ticks_needed < frame_tick) {
|
if (should_care && image->frame_tick + ticks_needed < frame_tick) {
|
||||||
if (is_bad_overlap) {
|
if (is_bad_overlap) {
|
||||||
const bool overlap_check =
|
const bool overlap_check =
|
||||||
std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) {
|
std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) {
|
||||||
auto& overlap = slot_images[overlap_id];
|
auto& overlap = slot_images[overlap_id];
|
||||||
return (overlap.frame_tick >= image->frame_tick) &&
|
return overlap.frame_tick >= image->frame_tick;
|
||||||
(overlap.modification_tick > image->modification_tick);
|
|
||||||
});
|
});
|
||||||
if (!overlap_check) {
|
if (!overlap_check) {
|
||||||
++deletion_iterator;
|
++deletion_iterator;
|
||||||
|
@ -420,23 +428,20 @@ void TextureCache<P>::TickFrame() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_bad_overlap && must_download) {
|
if (!is_bad_overlap && must_download) {
|
||||||
if (is_alias) {
|
const bool alias_check =
|
||||||
const bool alias_check =
|
std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) {
|
||||||
std::ranges::all_of(image->aliased_images, [&](const AliasedImage& alias) {
|
auto& alias_image = slot_images[alias.id];
|
||||||
auto& alias_image = slot_images[alias.id];
|
return (alias_image.frame_tick < image->frame_tick) ||
|
||||||
return (alias_image.frame_tick >= image->frame_tick) &&
|
(alias_image.modification_tick < image->modification_tick);
|
||||||
(alias_image.modification_tick > image->modification_tick);
|
});
|
||||||
});
|
|
||||||
if (!alias_check) {
|
if (alias_check) {
|
||||||
++deletion_iterator;
|
auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes);
|
||||||
continue;
|
const auto copies = FullDownloadCopies(image->info);
|
||||||
}
|
image->DownloadMemory(map, copies);
|
||||||
|
runtime.Finish();
|
||||||
|
SwizzleImage(gpu_memory, image->gpu_addr, image->info, copies, map.mapped_span);
|
||||||
}
|
}
|
||||||
auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes);
|
|
||||||
const auto copies = FullDownloadCopies(image->info);
|
|
||||||
image->DownloadMemory(map, copies);
|
|
||||||
runtime.Finish();
|
|
||||||
SwizzleImage(gpu_memory, image->gpu_addr, image->info, copies, map.mapped_span);
|
|
||||||
}
|
}
|
||||||
if (True(image->flags & ImageFlagBits::Tracked)) {
|
if (True(image->flags & ImageFlagBits::Tracked)) {
|
||||||
UntrackImage(*image);
|
UntrackImage(*image);
|
||||||
|
|
|
@ -817,6 +817,7 @@ void Config::ReadRendererValues() {
|
||||||
QStringLiteral("use_asynchronous_shaders"), false);
|
QStringLiteral("use_asynchronous_shaders"), false);
|
||||||
ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"),
|
ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"),
|
||||||
true);
|
true);
|
||||||
|
ReadSettingGlobal(Settings::values.use_caches_gc, QStringLiteral("use_caches_gc"), false);
|
||||||
ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0);
|
ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0);
|
||||||
ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0);
|
ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0);
|
||||||
ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"), 0.0);
|
ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"), 0.0);
|
||||||
|
@ -1401,6 +1402,7 @@ void Config::SaveRendererValues() {
|
||||||
Settings::values.use_asynchronous_shaders, false);
|
Settings::values.use_asynchronous_shaders, false);
|
||||||
WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time,
|
WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time,
|
||||||
true);
|
true);
|
||||||
|
WriteSettingGlobal(QStringLiteral("use_caches_gc"), Settings::values.use_caches_gc, false);
|
||||||
// Cast to double because Qt's written float values are not human-readable
|
// Cast to double because Qt's written float values are not human-readable
|
||||||
WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0);
|
WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0);
|
||||||
WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0);
|
WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0);
|
||||||
|
|
|
@ -30,6 +30,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
|
||||||
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
||||||
ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
|
ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
|
||||||
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
|
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
|
||||||
|
ui->use_caches_gc->setChecked(Settings::values.use_caches_gc.GetValue());
|
||||||
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
|
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
@ -62,6 +63,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
|
||||||
ui->use_asynchronous_shaders,
|
ui->use_asynchronous_shaders,
|
||||||
use_asynchronous_shaders);
|
use_asynchronous_shaders);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_caches_gc, ui->use_caches_gc,
|
||||||
|
use_caches_gc);
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
|
||||||
ui->use_fast_gpu_time, use_fast_gpu_time);
|
ui->use_fast_gpu_time, use_fast_gpu_time);
|
||||||
|
|
||||||
|
@ -101,6 +104,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||||
ui->use_asynchronous_shaders->setEnabled(
|
ui->use_asynchronous_shaders->setEnabled(
|
||||||
Settings::values.use_asynchronous_shaders.UsingGlobal());
|
Settings::values.use_asynchronous_shaders.UsingGlobal());
|
||||||
ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
|
ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
|
||||||
|
ui->use_caches_gc->setEnabled(Settings::values.use_caches_gc.UsingGlobal());
|
||||||
ui->anisotropic_filtering_combobox->setEnabled(
|
ui->anisotropic_filtering_combobox->setEnabled(
|
||||||
Settings::values.max_anisotropy.UsingGlobal());
|
Settings::values.max_anisotropy.UsingGlobal());
|
||||||
|
|
||||||
|
@ -115,6 +119,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||||
use_asynchronous_shaders);
|
use_asynchronous_shaders);
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time,
|
ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time,
|
||||||
Settings::values.use_fast_gpu_time, use_fast_gpu_time);
|
Settings::values.use_fast_gpu_time, use_fast_gpu_time);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->use_caches_gc, Settings::values.use_caches_gc,
|
||||||
|
use_caches_gc);
|
||||||
ConfigurationShared::SetColoredComboBox(
|
ConfigurationShared::SetColoredComboBox(
|
||||||
ui->gpu_accuracy, ui->label_gpu_accuracy,
|
ui->gpu_accuracy, ui->label_gpu_accuracy,
|
||||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
|
static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
|
||||||
|
|
|
@ -38,4 +38,5 @@ private:
|
||||||
ConfigurationShared::CheckState use_assembly_shaders;
|
ConfigurationShared::CheckState use_assembly_shaders;
|
||||||
ConfigurationShared::CheckState use_asynchronous_shaders;
|
ConfigurationShared::CheckState use_asynchronous_shaders;
|
||||||
ConfigurationShared::CheckState use_fast_gpu_time;
|
ConfigurationShared::CheckState use_fast_gpu_time;
|
||||||
|
ConfigurationShared::CheckState use_caches_gc;
|
||||||
};
|
};
|
||||||
|
|
|
@ -103,6 +103,16 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="use_caches_gc">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enables garbage collection for the GPU caches, this will try to keep VRAM within 3-4Gb and flush least used textures/buffers. This option may be unsafe on a few games</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable GPU caches garbage collection (unsafe)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="af_layout" native="true">
|
<widget class="QWidget" name="af_layout" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||||
|
|
|
@ -227,6 +227,10 @@ use_asynchronous_gpu_emulation =
|
||||||
# 0: Off, 1 (default): On
|
# 0: Off, 1 (default): On
|
||||||
use_vsync =
|
use_vsync =
|
||||||
|
|
||||||
|
# Whether to use garbage collection or not.
|
||||||
|
# 0 (default): Off, 1: On
|
||||||
|
use_caches_gc =
|
||||||
|
|
||||||
# The clear color for the renderer. What shows up on the sides of the bottom screen.
|
# The clear color for the renderer. What shows up on the sides of the bottom screen.
|
||||||
# Must be in range of 0.0-1.0. Defaults to 1.0 for all.
|
# Must be in range of 0.0-1.0. Defaults to 1.0 for all.
|
||||||
bg_red =
|
bg_red =
|
||||||
|
|
Reference in New Issue