diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 39a76a8608..4c599c6f44 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -30,6 +30,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"), ENABLE_BUFFER_HISTORY("enable_buffer_history"), USE_OPTIMIZED_VERTEX_BUFFERS("use_optimized_vertex_buffers"), + ENABLE_MULTI_RANGE_STORAGE("enable_multi_range_storage"), + ENABLE_SPARSE_BUFFER_BINDING("enable_sparse_buffer_binding"), ENABLE_GPU_BUFFER_READBACK("enable_gpu_buffer_readback"), SYNC_MEMORY_OPERATIONS("sync_memory_operations"), BUFFER_REORDER_DISABLE("disable_buffer_reorder"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 119d8ddf9e..c23504819e 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -927,6 +927,20 @@ abstract class SettingsItem( descriptionId = R.string.use_optimized_vertex_buffers_description ) ) + put( + SwitchSetting( + BooleanSetting.ENABLE_MULTI_RANGE_STORAGE, + titleId = R.string.enable_multi_range_storage, + descriptionId = R.string.enable_multi_range_storage_description + ) + ) + put( + SwitchSetting( + BooleanSetting.ENABLE_SPARSE_BUFFER_BINDING, + titleId = R.string.enable_sparse_buffer_binding, + descriptionId = R.string.enable_sparse_buffer_binding_description + ) + ) put( SwitchSetting( BooleanSetting.SYNC_MEMORY_OPERATIONS, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 2b5b966021..d6f7b7db14 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -338,6 +338,8 @@ class SettingsFragmentPresenter( add(BooleanSetting.ENABLE_BUFFER_HISTORY.key) add(BooleanSetting.ENABLE_GPU_BUFFER_READBACK.key) add(BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS.key) + add(BooleanSetting.ENABLE_MULTI_RANGE_STORAGE.key) + add(BooleanSetting.ENABLE_SPARSE_BUFFER_BINDING.key) add(HeaderSetting(R.string.hacks)) diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 55783f6e43..0e60042613 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -570,6 +570,10 @@ Preserves GPU-modified buffer data by reading it back before uploads. Some games require this to render certain effects properly. May cause issues if the hardware cannot handle the additional workload. Optimized Vertex Buffers Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers (25.3 and below). + Multi-Range Storage Buffers + toggle for test on multi-range. + Sparse Buffer Binding + toggle for test on sparse buffer binding. Hacks diff --git a/src/common/settings.h b/src/common/settings.h index 60cf874306..abbc119689 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -592,6 +592,22 @@ struct Values { true, true}; + SwitchableSetting enable_multi_range_storage{linkage, + false, + "enable_multi_range_storage", + Category::RendererAdvanced, + Specialization::Default, + true, + true}; + + SwitchableSetting enable_sparse_buffer_binding{linkage, + false, + "enable_sparse_buffer_binding", + Category::RendererAdvanced, + Specialization::Default, + true, + true}; + #ifdef __ANDROID__ SwitchableSetting use_optimized_vertex_buffers{linkage, false, diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index 7fd55ce038..8667d31ceb 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -267,6 +267,10 @@ std::unique_ptr InitializeTranslations(QObject* parent) { INSERT(Settings, enable_buffer_history, tr("Enable buffer history"), tr("Enables access to previous buffer states.\nThis option may improve rendering " "quality and performance consistency in some games.")); + INSERT(Settings, enable_multi_range_storage, tr("Multi-range storage buffers"), + tr("toggle for test on multi-range.")); + INSERT(Settings, enable_sparse_buffer_binding, tr("Sparse buffer binding"), + tr("toggle for test on sparse buffer binding.")); INSERT(Settings, fix_bloom_effects, tr("Fix bloom effects"), tr("Removes bloom in Burnout.")); INSERT(Settings, rescale_hack, tr("Enable Legacy Rescale Pass"), diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index e1689390c0..dd99a4facd 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -114,7 +114,12 @@ void BufferCache

::TickFrame() { template void BufferCache

::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t size) { - virtual_ranges.Unmap(as_id, gpu_addr, size); + if constexpr (requires { runtime.SupportsMultiRange(); }) { + if (!runtime.SupportsMultiRange()) { + return; + } + virtual_ranges.Unmap(as_id, gpu_addr, size); + } } template @@ -1009,6 +1014,9 @@ void BufferCache

::ResolveMultiRangeStorage(Binding& binding, bool is_written, binding.segment_first = 0; binding.segment_count = 0; if constexpr (requires { runtime.BindMultiRangeStorageBuffer(u64{}); }) { + if (!runtime.SupportsMultiRange()) { + return; + } if (binding.gpu_addr == 0 || binding.size == 0) { return; } diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index e9b162fb0f..203da3f43d 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -175,6 +175,10 @@ public: return multi_range_buffers.BlockSize(); } + [[nodiscard]] bool SupportsMultiRange() const noexcept { + return Settings::values.enable_multi_range_storage.GetValue(); + } + [[nodiscard]] bool PrefersSparseSources() const noexcept { return multi_range_buffers.UsesSparse(); } diff --git a/src/video_core/renderer_vulkan/vk_multi_range_buffer.cpp b/src/video_core/renderer_vulkan/vk_multi_range_buffer.cpp index 79086c4244..6386e2661a 100644 --- a/src/video_core/renderer_vulkan/vk_multi_range_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_multi_range_buffer.cpp @@ -94,7 +94,7 @@ u64 MultiRangeBufferCache::HashSources(std::span sources } bool MultiRangeBufferCache::CanBindSparse(std::span sources) const { - if (!use_sparse) { + if (!UsesSparse()) { return false; } for (const MultiRangeSource& source : sources) { diff --git a/src/video_core/renderer_vulkan/vk_multi_range_buffer.h b/src/video_core/renderer_vulkan/vk_multi_range_buffer.h index 6c9b738876..d64d1f2fa7 100644 --- a/src/video_core/renderer_vulkan/vk_multi_range_buffer.h +++ b/src/video_core/renderer_vulkan/vk_multi_range_buffer.h @@ -8,6 +8,7 @@ #include #include "common/common_types.h" +#include "common/settings.h" #include "video_core/vulkan_common/vulkan_memory_allocator.h" #include "video_core/vulkan_common/vulkan_wrapper.h" @@ -44,7 +45,7 @@ public: MultiRangeBufferCache& operator=(const MultiRangeBufferCache&) = delete; [[nodiscard]] bool UsesSparse() const noexcept { - return use_sparse; + return use_sparse && Settings::values.enable_sparse_buffer_binding.GetValue(); } [[nodiscard]] VkDeviceSize BlockSize() const noexcept {