Compare commits

...

7 Commits

Author SHA1 Message Date
Martin Felke
a68ed43fdb picky format fix 2023-06-05 00:34:47 +02:00
Martin Felke
d194ca58c4 some more formatting fixes and proper rename 2023-06-05 00:28:03 +02:00
Martin Felke
69f5df40f9 compile fixes after function renaming 2023-06-05 00:16:24 +02:00
Martin Felke
b250b52511 formatting fixes 2023-06-04 23:43:19 +02:00
Martin Felke
de5f61f8c7 fixed calculation, ui look and behavior, and compile errors 2023-06-04 22:40:13 +02:00
Martin Felke
418709c80a Merge branch 'master' into vram_percentage 2023-06-04 17:42:42 +02:00
Martin Felke
de1cbf6edc Configurable RAM to VRAM percentage setting for integrated devices
This shall allow to specify a certain percentage of RAM to use as VRAM on integrated / shared devices.
Ideally this can help tuning the garbage collector to prevent out of memory crashes.
On the other hand a too aggressive memory limitation may indeed affect rendering negatively
I did experience this on the steam deck for example. Graphical glitches may be caused in low memory
situations.
2023-06-04 17:35:47 +02:00
11 changed files with 124 additions and 11 deletions

View File

@@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/fs/path_util.h"
#include "common/logging/log.h"
#include "common/memory_detect.h"
#include "common/settings.h"
namespace Settings {
@@ -67,6 +68,8 @@ void LogSettings() {
log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
log_setting("Renderer_UseVRAMPercentage", values.use_vram_percentage.GetValue());
log_setting("Renderer_VRAMPercentage", values.vram_percentage.GetValue());
log_setting("Audio_OutputEngine", values.sink_id.GetValue());
log_setting("Audio_OutputDevice", values.audio_output_device_id.GetValue());
log_setting("Audio_InputDevice", values.audio_input_device_id.GetValue());
@@ -235,6 +238,8 @@ void RestoreGlobalState(bool is_powered_on) {
values.bg_green.SetGlobal(true);
values.bg_blue.SetGlobal(true);
values.enable_compute_pipelines.SetGlobal(true);
values.use_vram_percentage.SetGlobal(true);
values.vram_percentage.SetGlobal(true);
// System
values.language_index.SetGlobal(true);
@@ -250,4 +255,23 @@ void RestoreGlobalState(bool is_powered_on) {
values.motion_enabled.SetGlobal(true);
}
// this function only makes sense with integrated devices
u64 RamPercentageToBytes(u8 percent) {
// total RAM in bytes
u64 total_ram = Common::GetMemInfo().TotalPhysicalMemory;
// clamp percentage between 10 and 90, so we dont run out of either RAM or VRAM
if (percent < 10) {
percent = 10;
}
if (percent > 90) {
percent = 90;
}
// percentage of total RAM in byte
return (total_ram * percent) / 100;
}
} // namespace Settings

View File

@@ -487,6 +487,9 @@ struct Values {
SwitchableSetting<u8> bg_green{0, "bg_green"};
SwitchableSetting<u8> bg_blue{0, "bg_blue"};
SwitchableSetting<bool> use_vram_percentage{true, "use_vram_percentage"};
SwitchableSetting<u8, true> vram_percentage{25, 10, 90, "vram_percentage"};
// System
SwitchableSetting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
Setting<std::string> device_name{"Yuzu", "device_name"};
@@ -612,4 +615,6 @@ void UpdateRescalingInfo();
// Restore the global state of all applicable settings in the Values struct
void RestoreGlobalState(bool is_powered_on);
u64 RamPercentageToBytes(u8 percent);
} // namespace Settings

View File

@@ -134,7 +134,7 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_)
device_access_memory = [this]() -> u64 {
if (device.CanReportMemoryUsage()) {
return device.GetCurrentDedicatedVideoMemory() + 512_MiB;
return device.GetTotalDedicatedVideoMemory();
}
return 2_GiB; // Return minimum requirements
}();
@@ -142,7 +142,7 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_)
u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
if (device.CanReportMemoryUsage()) {
return device_access_memory - device.GetCurrentDedicatedVideoMemory();
return device.GetTotalDedicatedVideoMemory() - device.GetCurrentDedicatedVideoMemory();
}
return 2_GiB;
}

View File

@@ -284,9 +284,26 @@ void main() {
})");
}
u64 Device::GetTotalDedicatedVideoMemory() const {
GLint tot_avail_mem_kb = 0;
// this should report the correct size of the VRAM, on integrated devices it shows the size of
// the UMA Framebuffer
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &tot_avail_mem_kb);
if (Settings::values.use_vram_percentage.GetValue()) {
u8 percent = Settings::values.vram_percentage.GetValue();
return Settings::RamPercentageToBytes(percent);
} else {
// this is according to both former settings in the gl_buffer_cache
// and gl_texture_cache, regarding device_access_memory
return static_cast<u64>(tot_avail_mem_kb) * 1_KiB + 512_MiB;
}
}
u64 Device::GetCurrentDedicatedVideoMemory() const {
GLint cur_avail_mem_kb = 0;
glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &cur_avail_mem_kb);
// this should report the currently available video memory
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &cur_avail_mem_kb);
return static_cast<u64>(cur_avail_mem_kb) * 1_KiB;
}

View File

@@ -22,6 +22,8 @@ public:
[[nodiscard]] std::string GetVendorName() const;
u64 GetTotalDedicatedVideoMemory() const;
u64 GetCurrentDedicatedVideoMemory() const;
u32 GetMaxUniformBuffers(Shader::Stage stage) const noexcept {

View File

@@ -546,7 +546,7 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager&
device_access_memory = [this]() -> u64 {
if (device.CanReportMemoryUsage()) {
return device.GetCurrentDedicatedVideoMemory() + 512_MiB;
return device.GetTotalDedicatedVideoMemory();
}
return 2_GiB; // Return minimum requirements
}();
@@ -568,7 +568,7 @@ ImageBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size) {
u64 TextureCacheRuntime::GetDeviceMemoryUsage() const {
if (device.CanReportMemoryUsage()) {
return device_access_memory - device.GetCurrentDedicatedVideoMemory();
return device.GetTotalDedicatedVideoMemory() - device.GetCurrentDedicatedVideoMemory();
}
return 2_GiB;
}

View File

@@ -1039,9 +1039,13 @@ void Device::CollectPhysicalMemoryInfo() {
device_access_memory = std::min<u64>(device_access_memory, normal_memory + scaler_memory);
return;
}
const u8 percent = Settings::values.vram_percentage.GetValue();
const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage);
const s64 limit = Settings::values.use_vram_percentage.GetValue()
? Settings::RamPercentageToBytes(percent)
: 4_GiB;
device_access_memory = static_cast<u64>(std::max<s64>(
std::min<s64>(available_memory - 8_GiB, 4_GiB), std::min<s64>(local_memory, 4_GiB)));
std::min<s64>(available_memory - 8_GiB, 4_GiB), std::min<s64>(local_memory, limit)));
}
void Device::CollectToolingInfo() {

View File

@@ -757,6 +757,8 @@ void Config::ReadRendererValues() {
ReadGlobalSetting(Settings::values.bg_red);
ReadGlobalSetting(Settings::values.bg_green);
ReadGlobalSetting(Settings::values.bg_blue);
ReadGlobalSetting(Settings::values.use_vram_percentage);
ReadGlobalSetting(Settings::values.vram_percentage);
if (global) {
Settings::values.vsync_mode.SetValue(static_cast<Settings::VSyncMode>(
@@ -1412,6 +1414,8 @@ void Config::SaveRendererValues() {
WriteGlobalSetting(Settings::values.bg_red);
WriteGlobalSetting(Settings::values.bg_green);
WriteGlobalSetting(Settings::values.bg_blue);
WriteGlobalSetting(Settings::values.use_vram_percentage);
WriteGlobalSetting(Settings::values.vram_percentage);
if (global) {
WriteSetting(QString::fromStdString(Settings::values.vsync_mode.GetLabel()),

View File

@@ -31,6 +31,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
ui->use_asynchronous_shaders->setEnabled(runtime_lock);
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
ui->enable_compute_pipelines_checkbox->setEnabled(runtime_lock);
ui->use_vram_percentage->setEnabled(runtime_lock);
ui->async_present->setChecked(Settings::values.async_presentation.GetValue());
ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
@@ -42,6 +43,18 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
Settings::values.use_vulkan_driver_pipeline_cache.GetValue());
ui->enable_compute_pipelines_checkbox->setChecked(
Settings::values.enable_compute_pipelines.GetValue());
ui->use_vram_percentage->setChecked(Settings::values.use_vram_percentage.GetValue());
if (Settings::IsConfiguringGlobal()) {
ui->vram_percentage->setEnabled(Settings::values.use_vram_percentage.GetValue() &&
runtime_lock);
} else {
ui->vram_percentage->setEnabled(
Settings::values.use_vram_percentage.GetValue() &&
use_vram_percentage != ConfigurationShared::CheckState::Global && runtime_lock);
}
ui->vram_percentage->setValue(Settings::values.vram_percentage.GetValue());
if (Settings::IsConfiguringGlobal()) {
ui->gpu_accuracy->setCurrentIndex(
@@ -62,6 +75,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
!Settings::values.max_anisotropy.UsingGlobal());
ConfigurationShared::SetHighlight(ui->label_astc_recompression,
!Settings::values.astc_recompression.UsingGlobal());
ConfigurationShared::SetHighlight(ui->vram_percentage,
!Settings::values.vram_percentage.UsingGlobal());
}
}
@@ -91,6 +106,9 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_compute_pipelines,
ui->enable_compute_pipelines_checkbox,
enable_compute_pipelines);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vram_percentage,
ui->use_vram_percentage, use_vram_percentage);
Settings::values.vram_percentage.SetValue(ui->vram_percentage->value());
}
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
@@ -158,6 +176,14 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
ConfigurationShared::SetColoredComboBox(
ui->astc_recompression_combobox, ui->label_astc_recompression,
static_cast<int>(Settings::values.astc_recompression.GetValue(true)));
ConfigurationShared::SetColoredTristate(
ui->use_vram_percentage, Settings::values.use_vram_percentage, use_vram_percentage);
connect(ui->use_vram_percentage, &QCheckBox::clicked, ui->vram_percentage, [this]() {
ui->vram_percentage->setEnabled(
ui->use_vram_percentage->isChecked() &&
(use_vram_percentage != ConfigurationShared::CheckState::Global));
});
}
void ConfigureGraphicsAdvanced::ExposeComputeOption() {

View File

@@ -47,6 +47,7 @@ private:
ConfigurationShared::CheckState use_fast_gpu_time;
ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache;
ConfigurationShared::CheckState enable_compute_pipelines;
ConfigurationShared::CheckState use_vram_percentage;
const Core::System& system;
};

View File

@@ -250,11 +250,41 @@ Compute pipelines are always enabled on all other drivers.</string>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_vram">
<item>
<widget class="QCheckBox" name="use_vram_percentage">
<property name="toolTip">
<string>Assign the given % of the total shared RAM as VRAM</string>
</property>
<property name="text">
<string>Assign % of RAM as VRAM (Integrated devices only)</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="vram_percentage">
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>90</number>
</property>
<property name="value">
<number>25</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">