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.
This commit is contained in:
parent
e931bb8c44
commit
de1cbf6edc
9 changed files with 88 additions and 4 deletions
|
@ -7,6 +7,7 @@
|
|||
#include "common/fs/path_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/memory_detect.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(true);
|
||||
values.vram_percentage(25);
|
||||
|
||||
// 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 RAM_Percent_to_Byte(u8 percent) {
|
||||
// total RAM in byte
|
||||
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
|
||||
|
|
|
@ -487,6 +487,9 @@ struct Values {
|
|||
SwitchableSetting<u8> bg_green{0, "bg_green"};
|
||||
SwitchableSetting<u8> bg_blue{0, "bg_blue"};
|
||||
|
||||
SwitchableSetting<bool, true> 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"};
|
||||
|
|
|
@ -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
|
||||
}();
|
||||
|
|
|
@ -284,9 +284,23 @@ 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);
|
||||
// LOG_INFO(Render_OpenGL, "total VRAM: {} GB", tot_avail_mem_kb / f64{1_MiB});
|
||||
f64 percent = Settings::values.vram_percentage.GetValue();
|
||||
u64 vram = Settings::RAM_Percent_to_Byte(percent);
|
||||
return static_cast<u64>(tot_avail_mem_kb) * 1_KiB + vram;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
// LOG_INFO(Render_OpenGL, "current VRAM: {} GB", cur_avail_mem_kb / f64{1_MiB});
|
||||
return static_cast<u64>(cur_avail_mem_kb) * 1_KiB;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}();
|
||||
|
|
|
@ -1039,9 +1039,10 @@ 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);
|
||||
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, Settings::RAM_Percent_to_Byte(percent)));
|
||||
}
|
||||
|
||||
void Device::CollectToolingInfo() {
|
||||
|
|
|
@ -42,6 +42,9 @@ 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());
|
||||
ui->vram_percentage->setVisible(Settings::values.use_vram_percentage.GetValue());
|
||||
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->gpu_accuracy->setCurrentIndex(
|
||||
|
@ -91,6 +94,12 @@ 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);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.vram_percentage,
|
||||
ui->vram_percentage,
|
||||
vram_percentage);
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
|
||||
|
@ -158,6 +167,12 @@ 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);
|
||||
ConfigurationShared::SetColoredTristate(ui->vram_percentage,
|
||||
Settings::values.vram_percentage,
|
||||
vram_percentage);
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::ExposeComputeOption() {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -247,6 +247,32 @@ Compute pipelines are always enabled on all other drivers.</string>
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_vram_percentage">
|
||||
<property name="toolTip">
|
||||
<string>Assign the given percentage of the total shared RAM as VRAM</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Assign RAM percentage 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>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Add table
Reference in a new issue