diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/settings.cpp | 2 | ||||
| -rw-r--r-- | src/common/settings.h | 1 | ||||
| -rw-r--r-- | src/core/memory.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 9 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_view_base.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics_advanced.cpp | 7 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics_advanced.h | 1 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics_advanced.ui | 10 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu_cmd/default_ini.h | 4 |
11 files changed, 38 insertions, 5 deletions
diff --git a/src/common/settings.cpp b/src/common/settings.cpp index f1ee42ab2..db1774c71 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp | |||
| @@ -62,6 +62,7 @@ void LogSettings() { | |||
| 62 | log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue()); | 62 | log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue()); |
| 63 | log_setting("Renderer_AsyncASTC", values.async_astc.GetValue()); | 63 | log_setting("Renderer_AsyncASTC", values.async_astc.GetValue()); |
| 64 | log_setting("Renderer_UseVsync", values.vsync_mode.GetValue()); | 64 | log_setting("Renderer_UseVsync", values.vsync_mode.GetValue()); |
| 65 | log_setting("Renderer_UseReactiveFlushing", values.use_reactive_flushing.GetValue()); | ||
| 65 | log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); | 66 | log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); |
| 66 | log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); | 67 | log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); |
| 67 | log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); | 68 | log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); |
| @@ -223,6 +224,7 @@ void RestoreGlobalState(bool is_powered_on) { | |||
| 223 | values.nvdec_emulation.SetGlobal(true); | 224 | values.nvdec_emulation.SetGlobal(true); |
| 224 | values.accelerate_astc.SetGlobal(true); | 225 | values.accelerate_astc.SetGlobal(true); |
| 225 | values.async_astc.SetGlobal(true); | 226 | values.async_astc.SetGlobal(true); |
| 227 | values.use_reactive_flushing.SetGlobal(true); | ||
| 226 | values.shader_backend.SetGlobal(true); | 228 | values.shader_backend.SetGlobal(true); |
| 227 | values.use_asynchronous_shaders.SetGlobal(true); | 229 | values.use_asynchronous_shaders.SetGlobal(true); |
| 228 | values.use_fast_gpu_time.SetGlobal(true); | 230 | values.use_fast_gpu_time.SetGlobal(true); |
diff --git a/src/common/settings.h b/src/common/settings.h index 2bf191cef..f4eb4e3cd 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -465,6 +465,7 @@ struct Values { | |||
| 465 | SwitchableSetting<bool> async_astc{false, "async_astc"}; | 465 | SwitchableSetting<bool> async_astc{false, "async_astc"}; |
| 466 | Setting<VSyncMode, true> vsync_mode{VSyncMode::FIFO, VSyncMode::Immediate, | 466 | Setting<VSyncMode, true> vsync_mode{VSyncMode::FIFO, VSyncMode::Immediate, |
| 467 | VSyncMode::FIFORelaxed, "use_vsync"}; | 467 | VSyncMode::FIFORelaxed, "use_vsync"}; |
| 468 | SwitchableSetting<bool> use_reactive_flushing{true, "use_reactive_flushing"}; | ||
| 468 | SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL, | 469 | SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL, |
| 469 | ShaderBackend::SPIRV, "shader_backend"}; | 470 | ShaderBackend::SPIRV, "shader_backend"}; |
| 470 | SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; | 471 | SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 7b79cb8bc..549b64ac4 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -465,7 +465,8 @@ struct Memory::Impl { | |||
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | if (Settings::IsFastmemEnabled()) { | 467 | if (Settings::IsFastmemEnabled()) { |
| 468 | system.DeviceMemory().buffer.Protect(vaddr, size, !cached, !cached); | 468 | const bool is_read_enable = !Settings::values.use_reactive_flushing.GetValue() || !cached; |
| 469 | system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached); | ||
| 469 | } | 470 | } |
| 470 | 471 | ||
| 471 | // Iterate over a contiguous CPU address space, which corresponds to the specified GPU | 472 | // Iterate over a contiguous CPU address space, which corresponds to the specified GPU |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 479a1a508..474822354 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -126,7 +126,8 @@ std::optional<VideoCore::RasterizerDownloadArea> BufferCache<P>::GetFlushArea(VA | |||
| 126 | area->preemtive = true; | 126 | area->preemtive = true; |
| 127 | return area; | 127 | return area; |
| 128 | }; | 128 | }; |
| 129 | memory_tracker.MarkRegionAsPreflushable(cpu_addr_start_aligned, cpu_addr_end_aligned - cpu_addr_start_aligned); | 129 | memory_tracker.MarkRegionAsPreflushable(cpu_addr_start_aligned, |
| 130 | cpu_addr_end_aligned - cpu_addr_start_aligned); | ||
| 130 | area->preemtive = !IsRegionGpuModified(cpu_addr, size); | 131 | area->preemtive = !IsRegionGpuModified(cpu_addr, size); |
| 131 | return area; | 132 | return area; |
| 132 | } | 133 | } |
| @@ -206,7 +207,8 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am | |||
| 206 | const VAddr new_base_address = *cpu_dest_address + diff; | 207 | const VAddr new_base_address = *cpu_dest_address + diff; |
| 207 | const IntervalType add_interval{new_base_address, new_base_address + size}; | 208 | const IntervalType add_interval{new_base_address, new_base_address + size}; |
| 208 | tmp_intervals.push_back(add_interval); | 209 | tmp_intervals.push_back(add_interval); |
| 209 | if (memory_tracker.IsRegionPreflushable(new_base_address, new_base_address + size)) { | 210 | if (!Settings::values.use_reactive_flushing.GetValue() || |
| 211 | memory_tracker.IsRegionPreflushable(new_base_address, new_base_address + size)) { | ||
| 210 | uncommitted_ranges.add(add_interval); | 212 | uncommitted_ranges.add(add_interval); |
| 211 | pending_ranges.add(add_interval); | 213 | pending_ranges.add(add_interval); |
| 212 | } | 214 | } |
| @@ -1236,7 +1238,8 @@ void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s | |||
| 1236 | 1238 | ||
| 1237 | const IntervalType base_interval{cpu_addr, cpu_addr + size}; | 1239 | const IntervalType base_interval{cpu_addr, cpu_addr + size}; |
| 1238 | common_ranges.add(base_interval); | 1240 | common_ranges.add(base_interval); |
| 1239 | if (!memory_tracker.IsRegionPreflushable(cpu_addr, cpu_addr + size)) { | 1241 | if (Settings::values.use_reactive_flushing.GetValue() && |
| 1242 | !memory_tracker.IsRegionPreflushable(cpu_addr, cpu_addr + size)) { | ||
| 1240 | return; | 1243 | return; |
| 1241 | } | 1244 | } |
| 1242 | uncommitted_ranges.add(base_interval); | 1245 | uncommitted_ranges.add(base_interval); |
diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 8f28342d5..30a7c11f5 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp | |||
| @@ -26,7 +26,8 @@ ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_i | |||
| 26 | ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false, true), | 26 | ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false, true), |
| 27 | "Image view format {} is incompatible with image format {}", info.format, | 27 | "Image view format {} is incompatible with image format {}", info.format, |
| 28 | image_info.format); | 28 | image_info.format); |
| 29 | if (image_info.forced_flushed) { | 29 | const bool preemptive = !Settings::values.use_reactive_flushing.GetValue() && image_info.type == ImageType::Linear; |
| 30 | if (image_info.forced_flushed || preemptive) { | ||
| 30 | flags |= ImageViewFlagBits::PreemtiveDownload; | 31 | flags |= ImageViewFlagBits::PreemtiveDownload; |
| 31 | } | 32 | } |
| 32 | if (image_info.type == ImageType::e3D && info.type != ImageViewType::e3D) { | 33 | if (image_info.type == ImageType::e3D && info.type != ImageViewType::e3D) { |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index a85eb4687..a49d12266 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -710,6 +710,7 @@ void Config::ReadRendererValues() { | |||
| 710 | ReadGlobalSetting(Settings::values.nvdec_emulation); | 710 | ReadGlobalSetting(Settings::values.nvdec_emulation); |
| 711 | ReadGlobalSetting(Settings::values.accelerate_astc); | 711 | ReadGlobalSetting(Settings::values.accelerate_astc); |
| 712 | ReadGlobalSetting(Settings::values.async_astc); | 712 | ReadGlobalSetting(Settings::values.async_astc); |
| 713 | ReadGlobalSetting(Settings::values.use_reactive_flushing); | ||
| 713 | ReadGlobalSetting(Settings::values.shader_backend); | 714 | ReadGlobalSetting(Settings::values.shader_backend); |
| 714 | ReadGlobalSetting(Settings::values.use_asynchronous_shaders); | 715 | ReadGlobalSetting(Settings::values.use_asynchronous_shaders); |
| 715 | ReadGlobalSetting(Settings::values.use_fast_gpu_time); | 716 | ReadGlobalSetting(Settings::values.use_fast_gpu_time); |
| @@ -1355,6 +1356,7 @@ void Config::SaveRendererValues() { | |||
| 1355 | Settings::values.nvdec_emulation.UsingGlobal()); | 1356 | Settings::values.nvdec_emulation.UsingGlobal()); |
| 1356 | WriteGlobalSetting(Settings::values.accelerate_astc); | 1357 | WriteGlobalSetting(Settings::values.accelerate_astc); |
| 1357 | WriteGlobalSetting(Settings::values.async_astc); | 1358 | WriteGlobalSetting(Settings::values.async_astc); |
| 1359 | WriteGlobalSetting(Settings::values.use_reactive_flushing); | ||
| 1358 | WriteSetting(QString::fromStdString(Settings::values.shader_backend.GetLabel()), | 1360 | WriteSetting(QString::fromStdString(Settings::values.shader_backend.GetLabel()), |
| 1359 | static_cast<u32>(Settings::values.shader_backend.GetValue(global)), | 1361 | static_cast<u32>(Settings::values.shader_backend.GetValue(global)), |
| 1360 | static_cast<u32>(Settings::values.shader_backend.GetDefault()), | 1362 | static_cast<u32>(Settings::values.shader_backend.GetDefault()), |
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 005b022ca..627ed8b17 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp | |||
| @@ -21,6 +21,7 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; | |||
| 21 | 21 | ||
| 22 | void ConfigureGraphicsAdvanced::SetConfiguration() { | 22 | void ConfigureGraphicsAdvanced::SetConfiguration() { |
| 23 | const bool runtime_lock = !system.IsPoweredOn(); | 23 | const bool runtime_lock = !system.IsPoweredOn(); |
| 24 | ui->use_reactive_flushing->setEnabled(runtime_lock); | ||
| 24 | ui->async_present->setEnabled(runtime_lock); | 25 | ui->async_present->setEnabled(runtime_lock); |
| 25 | ui->renderer_force_max_clock->setEnabled(runtime_lock); | 26 | ui->renderer_force_max_clock->setEnabled(runtime_lock); |
| 26 | ui->async_astc->setEnabled(runtime_lock); | 27 | ui->async_astc->setEnabled(runtime_lock); |
| @@ -29,6 +30,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { | |||
| 29 | 30 | ||
| 30 | ui->async_present->setChecked(Settings::values.async_presentation.GetValue()); | 31 | ui->async_present->setChecked(Settings::values.async_presentation.GetValue()); |
| 31 | ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue()); | 32 | ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue()); |
| 33 | ui->use_reactive_flushing->setChecked(Settings::values.use_reactive_flushing.GetValue()); | ||
| 32 | ui->async_astc->setChecked(Settings::values.async_astc.GetValue()); | 34 | ui->async_astc->setChecked(Settings::values.async_astc.GetValue()); |
| 33 | ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue()); | 35 | ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue()); |
| 34 | ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); | 36 | ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); |
| @@ -60,6 +62,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { | |||
| 60 | renderer_force_max_clock); | 62 | renderer_force_max_clock); |
| 61 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, | 63 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, |
| 62 | ui->anisotropic_filtering_combobox); | 64 | ui->anisotropic_filtering_combobox); |
| 65 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_reactive_flushing, | ||
| 66 | ui->use_reactive_flushing, use_reactive_flushing); | ||
| 63 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_astc, ui->async_astc, | 67 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_astc, ui->async_astc, |
| 64 | async_astc); | 68 | async_astc); |
| 65 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders, | 69 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders, |
| @@ -91,6 +95,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { | |||
| 91 | ui->async_present->setEnabled(Settings::values.async_presentation.UsingGlobal()); | 95 | ui->async_present->setEnabled(Settings::values.async_presentation.UsingGlobal()); |
| 92 | ui->renderer_force_max_clock->setEnabled( | 96 | ui->renderer_force_max_clock->setEnabled( |
| 93 | Settings::values.renderer_force_max_clock.UsingGlobal()); | 97 | Settings::values.renderer_force_max_clock.UsingGlobal()); |
| 98 | ui->use_reactive_flushing->setEnabled(Settings::values.use_reactive_flushing.UsingGlobal()); | ||
| 94 | ui->async_astc->setEnabled(Settings::values.async_astc.UsingGlobal()); | 99 | ui->async_astc->setEnabled(Settings::values.async_astc.UsingGlobal()); |
| 95 | ui->use_asynchronous_shaders->setEnabled( | 100 | ui->use_asynchronous_shaders->setEnabled( |
| 96 | Settings::values.use_asynchronous_shaders.UsingGlobal()); | 101 | Settings::values.use_asynchronous_shaders.UsingGlobal()); |
| @@ -108,6 +113,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { | |||
| 108 | ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock, | 113 | ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock, |
| 109 | Settings::values.renderer_force_max_clock, | 114 | Settings::values.renderer_force_max_clock, |
| 110 | renderer_force_max_clock); | 115 | renderer_force_max_clock); |
| 116 | ConfigurationShared::SetColoredTristate( | ||
| 117 | ui->use_reactive_flushing, Settings::values.use_reactive_flushing, use_reactive_flushing); | ||
| 111 | ConfigurationShared::SetColoredTristate(ui->async_astc, Settings::values.async_astc, | 118 | ConfigurationShared::SetColoredTristate(ui->async_astc, Settings::values.async_astc, |
| 112 | async_astc); | 119 | async_astc); |
| 113 | ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders, | 120 | ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders, |
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index ff5060957..ae3c10946 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h | |||
| @@ -40,6 +40,7 @@ private: | |||
| 40 | ConfigurationShared::CheckState renderer_force_max_clock; | 40 | ConfigurationShared::CheckState renderer_force_max_clock; |
| 41 | ConfigurationShared::CheckState use_vsync; | 41 | ConfigurationShared::CheckState use_vsync; |
| 42 | ConfigurationShared::CheckState async_astc; | 42 | ConfigurationShared::CheckState async_astc; |
| 43 | ConfigurationShared::CheckState use_reactive_flushing; | ||
| 43 | ConfigurationShared::CheckState use_asynchronous_shaders; | 44 | ConfigurationShared::CheckState use_asynchronous_shaders; |
| 44 | ConfigurationShared::CheckState use_fast_gpu_time; | 45 | ConfigurationShared::CheckState use_fast_gpu_time; |
| 45 | ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; | 46 | ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; |
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index d073fe9b1..9d8cbea09 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui | |||
| @@ -97,6 +97,16 @@ | |||
| 97 | </widget> | 97 | </widget> |
| 98 | </item> | 98 | </item> |
| 99 | <item> | 99 | <item> |
| 100 | <widget class="QCheckBox" name="use_reactive_flushing"> | ||
| 101 | <property name="toolTip"> | ||
| 102 | <string>Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory.</string> | ||
| 103 | </property> | ||
| 104 | <property name="text"> | ||
| 105 | <string>Enable Reactive Flushing</string> | ||
| 106 | </property> | ||
| 107 | </widget> | ||
| 108 | </item> | ||
| 109 | <item> | ||
| 100 | <widget class="QCheckBox" name="use_asynchronous_shaders"> | 110 | <widget class="QCheckBox" name="use_asynchronous_shaders"> |
| 101 | <property name="toolTip"> | 111 | <property name="toolTip"> |
| 102 | <string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string> | 112 | <string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string> |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index a6418e693..abe7092fc 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -312,6 +312,7 @@ void Config::ReadValues() { | |||
| 312 | ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation); | 312 | ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation); |
| 313 | ReadSetting("Renderer", Settings::values.vsync_mode); | 313 | ReadSetting("Renderer", Settings::values.vsync_mode); |
| 314 | ReadSetting("Renderer", Settings::values.shader_backend); | 314 | ReadSetting("Renderer", Settings::values.shader_backend); |
| 315 | ReadSetting("Renderer", Settings::values.use_reactive_flushing); | ||
| 315 | ReadSetting("Renderer", Settings::values.use_asynchronous_shaders); | 316 | ReadSetting("Renderer", Settings::values.use_asynchronous_shaders); |
| 316 | ReadSetting("Renderer", Settings::values.nvdec_emulation); | 317 | ReadSetting("Renderer", Settings::values.nvdec_emulation); |
| 317 | ReadSetting("Renderer", Settings::values.accelerate_astc); | 318 | ReadSetting("Renderer", Settings::values.accelerate_astc); |
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 086ed4cfa..5e7c3ac04 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h | |||
| @@ -340,6 +340,10 @@ use_vsync = | |||
| 340 | # 0: GLSL, 1 (default): GLASM, 2: SPIR-V | 340 | # 0: GLSL, 1 (default): GLASM, 2: SPIR-V |
| 341 | shader_backend = | 341 | shader_backend = |
| 342 | 342 | ||
| 343 | # Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory. | ||
| 344 | # 0: Off, 1 (default): On | ||
| 345 | use_reactive_flushing = | ||
| 346 | |||
| 343 | # Whether to allow asynchronous shader building. | 347 | # Whether to allow asynchronous shader building. |
| 344 | # 0 (default): Off, 1: On | 348 | # 0 (default): Off, 1: On |
| 345 | use_asynchronous_shaders = | 349 | use_asynchronous_shaders = |