From 0eacf547c0733f39e11515e7aedf300d0cd06e99 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Mon, 12 Jun 2023 15:59:44 +0200 Subject: [PATCH 01/12] video_core: Option to apply anisotropic filtering for all mipmap modes --- src/common/settings.cpp | 1 + src/common/settings.h | 2 ++ src/video_core/textures/texture.cpp | 3 ++- src/yuzu/configuration/config.cpp | 2 ++ .../configuration/configure_graphics_advanced.cpp | 11 +++++++++++ .../configuration/configure_graphics_advanced.h | 1 + .../configuration/configure_graphics_advanced.ui | 13 +++++++++++++ src/yuzu_cmd/config.cpp | 1 + src/yuzu_cmd/default_ini.h | 4 ++++ 9 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 9ff3edabb..da5cca589 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -236,6 +236,7 @@ void RestoreGlobalState(bool is_powered_on) { values.bg_blue.SetGlobal(true); values.enable_compute_pipelines.SetGlobal(true); values.use_video_framerate.SetGlobal(true); + values.use_aggressive_anisotropic_filtering.SetGlobal(true); // System values.language_index.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index 9682281b0..78ca73e42 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -483,6 +483,8 @@ struct Values { AstcRecompression::Uncompressed, AstcRecompression::Uncompressed, AstcRecompression::Bc3, "astc_recompression"}; SwitchableSetting use_video_framerate{false, "use_video_framerate"}; + SwitchableSetting use_aggressive_anisotropic_filtering{ + false, "use_aggressive_anisotropic_filtering"}; SwitchableSetting bg_red{0, "bg_red"}; SwitchableSetting bg_green{0, "bg_green"}; diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index 4a80a59f9..12372a004 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -62,7 +62,8 @@ std::array TSCEntry::BorderColor() const noexcept { } float TSCEntry::MaxAnisotropy() const noexcept { - if (max_anisotropy == 0 && mipmap_filter != TextureMipmapFilter::Linear) { + if (max_anisotropy == 0 && (mipmap_filter != TextureMipmapFilter::Linear && + !Settings::values.use_aggressive_anisotropic_filtering)) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index bac9dff90..27839daaa 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -761,6 +761,7 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); ReadGlobalSetting(Settings::values.enable_compute_pipelines); ReadGlobalSetting(Settings::values.use_video_framerate); + ReadGlobalSetting(Settings::values.use_aggressive_anisotropic_filtering); ReadGlobalSetting(Settings::values.bg_red); ReadGlobalSetting(Settings::values.bg_green); ReadGlobalSetting(Settings::values.bg_blue); @@ -1417,6 +1418,7 @@ void Config::SaveRendererValues() { WriteGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); WriteGlobalSetting(Settings::values.enable_compute_pipelines); WriteGlobalSetting(Settings::values.use_video_framerate); + WriteGlobalSetting(Settings::values.use_aggressive_anisotropic_filtering); WriteGlobalSetting(Settings::values.bg_red); WriteGlobalSetting(Settings::values.bg_green); WriteGlobalSetting(Settings::values.bg_blue); diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 0463ac8b9..3dce73968 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -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_aggressive_anisotropic_filtering->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()); @@ -43,6 +44,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { ui->enable_compute_pipelines_checkbox->setChecked( Settings::values.enable_compute_pipelines.GetValue()); ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue()); + ui->use_aggressive_anisotropic_filtering->setChecked( + Settings::values.use_aggressive_anisotropic_filtering.GetValue()); if (Settings::IsConfiguringGlobal()) { ui->gpu_accuracy->setCurrentIndex( @@ -94,6 +97,9 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { enable_compute_pipelines); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate, ui->use_video_framerate_checkbox, use_video_framerate); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_aggressive_anisotropic_filtering, + ui->use_aggressive_anisotropic_filtering, + use_aggressive_anisotropic_filtering); } void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { @@ -130,6 +136,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { Settings::values.enable_compute_pipelines.UsingGlobal()); ui->use_video_framerate_checkbox->setEnabled( Settings::values.use_video_framerate.UsingGlobal()); + ui->use_aggressive_anisotropic_filtering->setEnabled( + Settings::values.use_aggressive_anisotropic_filtering.UsingGlobal()); return; } @@ -157,6 +165,9 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox, Settings::values.use_video_framerate, use_video_framerate); + ConfigurationShared::SetColoredTristate(ui->use_aggressive_anisotropic_filtering, + Settings::values.use_aggressive_anisotropic_filtering, + use_aggressive_anisotropic_filtering); ConfigurationShared::SetColoredComboBox( ui->gpu_accuracy, ui->label_gpu_accuracy, static_cast(Settings::values.gpu_accuracy.GetValue(true))); diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index a4dc8ceb0..4b52e5d61 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h @@ -48,6 +48,7 @@ private: ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; ConfigurationShared::CheckState enable_compute_pipelines; ConfigurationShared::CheckState use_video_framerate; + ConfigurationShared::CheckState use_aggressive_anisotropic_filtering; const Core::System& system; }; diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index e7f0ef6be..06771c080 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui @@ -260,6 +260,19 @@ Compute pipelines are always enabled on all other drivers. + + + + Enable this option for a more aggressive approach to applying Anisotropic Filtering to textures. +By toggling this, Anisotropic Filtering is added to textures with both nearest and linear mipmapping modes. +This may result in improved visual quality for a wider range of textures, but can also introduce artifacts in +some titles. + + + Apply Anisotropic Filtering for all mipmap modes + + + diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index c5bc472ca..f5a5364da 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -321,6 +321,7 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.astc_recompression); ReadSetting("Renderer", Settings::values.use_fast_gpu_time); ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache); + ReadSetting("Renderer", Settings::values.use_aggressive_anisotropic_filtering); ReadSetting("Renderer", Settings::values.bg_red); ReadSetting("Renderer", Settings::values.bg_green); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 911d461e4..f12e2dfc9 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -325,6 +325,10 @@ aspect_ratio = # 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x max_anisotropy = +# Apply Anisotropic Filtering to all mipmap modes. +# 0 (default): Off, 1: On +use_aggressive_anisotropic_filtering = + # Whether to enable VSync or not. # OpenGL: Values other than 0 enable VSync # Vulkan: FIFO is selected if the requested mode is not supported by the driver. From b9bba3ac8941e4561ef150517cf44943a42b99e7 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Tue, 13 Jun 2023 18:07:08 +0200 Subject: [PATCH 02/12] video_core: Disable anisotropic filtering for samplers with depth compare --- src/video_core/textures/texture.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index 12372a004..083bfd8d3 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -62,8 +62,9 @@ std::array TSCEntry::BorderColor() const noexcept { } float TSCEntry::MaxAnisotropy() const noexcept { - if (max_anisotropy == 0 && (mipmap_filter != TextureMipmapFilter::Linear && - !Settings::values.use_aggressive_anisotropic_filtering)) { + if (max_anisotropy == 0 && (depth_compare_enabled.Value() || + (mipmap_filter != TextureMipmapFilter::Linear && + !Settings::values.use_aggressive_anisotropic_filtering))) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); From 44f616edb97520e9bc82b9f9c0658a8a35806b89 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Wed, 14 Jun 2023 03:57:39 +0200 Subject: [PATCH 03/12] video_core: Never apply AF to None mipmap mode Should fix some artifacts with the "apply anisotropic filtering for all mipmap modes" option --- src/video_core/textures/texture.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index 083bfd8d3..b46dce096 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -62,9 +62,10 @@ std::array TSCEntry::BorderColor() const noexcept { } float TSCEntry::MaxAnisotropy() const noexcept { - if (max_anisotropy == 0 && (depth_compare_enabled.Value() || - (mipmap_filter != TextureMipmapFilter::Linear && - !Settings::values.use_aggressive_anisotropic_filtering))) { + const bool suitable_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering + ? mipmap_filter != TextureMipmapFilter::None + : mipmap_filter != TextureMipmapFilter::Linear; + if (max_anisotropy == 0 && (depth_compare_enabled.Value() || !suitable_mipmap_filter)) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); From a9e4dddad582d61871076b4310f2c99009afe0db Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Wed, 14 Jun 2023 11:21:22 +0200 Subject: [PATCH 04/12] video_core: Fix default anisotropic heuristic --- src/video_core/textures/texture.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index b46dce096..1daa2d488 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -62,10 +62,10 @@ std::array TSCEntry::BorderColor() const noexcept { } float TSCEntry::MaxAnisotropy() const noexcept { - const bool suitable_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering - ? mipmap_filter != TextureMipmapFilter::None - : mipmap_filter != TextureMipmapFilter::Linear; - if (max_anisotropy == 0 && (depth_compare_enabled.Value() || !suitable_mipmap_filter)) { + const bool unsupported_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering + ? mipmap_filter == TextureMipmapFilter::None + : mipmap_filter != TextureMipmapFilter::Linear; + if (max_anisotropy == 0 && (depth_compare_enabled.Value() || unsupported_mipmap_filter)) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); From 0de6b9e3f56fb54e74f5ec1fdbecac31986a8054 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Wed, 14 Jun 2023 13:27:27 +0200 Subject: [PATCH 05/12] video_core: Apply AF only to samplers with normal LOD range [0, 1+x] --- src/video_core/textures/texture.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index 1daa2d488..560b3af8a 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -62,10 +62,12 @@ std::array TSCEntry::BorderColor() const noexcept { } float TSCEntry::MaxAnisotropy() const noexcept { - const bool unsupported_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering - ? mipmap_filter == TextureMipmapFilter::None - : mipmap_filter != TextureMipmapFilter::Linear; - if (max_anisotropy == 0 && (depth_compare_enabled.Value() || unsupported_mipmap_filter)) { + const bool is_unsupported_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering + ? mipmap_filter == TextureMipmapFilter::None + : mipmap_filter != TextureMipmapFilter::Linear; + const bool has_regular_lods = min_lod_clamp == 0 && max_lod_clamp >= 256; + if (max_anisotropy == 0 && + (depth_compare_enabled.Value() || !has_regular_lods || is_unsupported_mipmap_filter)) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); From 42c944b250d8d5c8147b24b3a453cba29968d46c Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Thu, 15 Jun 2023 18:19:32 +0200 Subject: [PATCH 06/12] video_core: Add per-image anisotropy heuristics (format & mip count) --- .../renderer_opengl/gl_graphics_pipeline.cpp | 25 +++++-- .../renderer_opengl/gl_texture_cache.cpp | 68 +++++++++++-------- .../renderer_opengl/gl_texture_cache.h | 11 ++- .../renderer_vulkan/pipeline_helper.h | 10 ++- .../renderer_vulkan/vk_compute_pipeline.cpp | 6 +- .../renderer_vulkan/vk_graphics_pipeline.cpp | 6 +- .../renderer_vulkan/vk_texture_cache.cpp | 49 +++++++------ .../renderer_vulkan/vk_texture_cache.h | 9 +++ .../texture_cache/image_view_base.cpp | 39 +++++++++++ .../texture_cache/image_view_base.h | 2 + src/video_core/textures/texture.cpp | 12 ++-- 11 files changed, 167 insertions(+), 70 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 89000d6e0..0fa0fc594 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp @@ -275,9 +275,9 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c template void GraphicsPipeline::ConfigureImpl(bool is_indexed) { std::array views; - std::array samplers; + std::array samplers; size_t views_index{}; - GLsizei sampler_binding{}; + size_t samplers_index{}; texture_cache.SynchronizeGraphicsDescriptors(); @@ -337,7 +337,6 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { for (u32 index = 0; index < desc.count; ++index) { const auto handle{read_handle(desc, index)}; views[views_index++] = {handle.first}; - samplers[sampler_binding++] = 0; } } } @@ -352,7 +351,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { views[views_index++] = {handle.first}; Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; - samplers[sampler_binding++] = sampler->Handle(); + samplers[samplers_index++] = sampler; } } if constexpr (Spec::has_images) { @@ -445,10 +444,13 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { program_manager.BindSourcePrograms(source_programs); } const VideoCommon::ImageViewInOut* views_it{views.data()}; + const Sampler** samplers_it{samplers.data()}; GLsizei texture_binding = 0; GLsizei image_binding = 0; + GLsizei sampler_binding{}; std::array textures; std::array images; + std::array gl_samplers; const auto prepare_stage{[&](size_t stage) { buffer_cache.runtime.SetImagePointers(&textures[texture_binding], &images[image_binding]); buffer_cache.BindHostStageBuffers(stage); @@ -465,6 +467,13 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { u32 stage_image_binding{}; const auto& info{stage_infos[stage]}; + if constexpr (Spec::has_texture_buffers) { + for (const auto& desc : info.texture_buffer_descriptors) { + for (u32 index = 0; index < desc.count; ++index) { + gl_samplers[sampler_binding++] = 0; + } + } + } for (const auto& desc : info.texture_descriptors) { for (u32 index = 0; index < desc.count; ++index) { ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; @@ -474,6 +483,12 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { } ++texture_binding; ++stage_texture_binding; + + const Sampler& sampler{**(samplers_it++)}; + const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && + !image_view.SupportsAnisotropy()}; + gl_samplers[sampler_binding++] = + use_fallback_sampler ? sampler.HandleWithoutAnisotropy() : sampler.Handle(); } } for (const auto& desc : info.image_descriptors) { @@ -534,7 +549,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { if (texture_binding != 0) { ASSERT(texture_binding == sampler_binding); glBindTextures(0, texture_binding, textures.data()); - glBindSamplers(0, sampler_binding, samplers.data()); + glBindSamplers(0, sampler_binding, gl_samplers.data()); } if (image_binding != 0) { glBindImageTextures(0, image_binding, images.data()); diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 1c5dbcdd8..ee5a0c723 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -1268,36 +1268,46 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) { UNIMPLEMENTED_IF(config.cubemap_anisotropy != 1); - sampler.Create(); - const GLuint handle = sampler.handle; - glSamplerParameteri(handle, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(config.wrap_u)); - glSamplerParameteri(handle, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(config.wrap_v)); - glSamplerParameteri(handle, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(config.wrap_p)); - glSamplerParameteri(handle, GL_TEXTURE_COMPARE_MODE, compare_mode); - glSamplerParameteri(handle, GL_TEXTURE_COMPARE_FUNC, compare_func); - glSamplerParameteri(handle, GL_TEXTURE_MAG_FILTER, mag); - glSamplerParameteri(handle, GL_TEXTURE_MIN_FILTER, min); - glSamplerParameterf(handle, GL_TEXTURE_LOD_BIAS, config.LodBias()); - glSamplerParameterf(handle, GL_TEXTURE_MIN_LOD, config.MinLod()); - glSamplerParameterf(handle, GL_TEXTURE_MAX_LOD, config.MaxLod()); - glSamplerParameterfv(handle, GL_TEXTURE_BORDER_COLOR, config.BorderColor().data()); + const f32 max_anisotropy = std::clamp(config.MaxAnisotropy(), 1.0f, 16.0f); - if (GLAD_GL_ARB_texture_filter_anisotropic || GLAD_GL_EXT_texture_filter_anisotropic) { - const f32 max_anisotropy = std::clamp(config.MaxAnisotropy(), 1.0f, 16.0f); - glSamplerParameterf(handle, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropy); - } else { - LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_anisotropic is required"); - } - if (GLAD_GL_ARB_texture_filter_minmax || GLAD_GL_EXT_texture_filter_minmax) { - glSamplerParameteri(handle, GL_TEXTURE_REDUCTION_MODE_ARB, reduction_filter); - } else if (reduction_filter != GL_WEIGHTED_AVERAGE_ARB) { - LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_minmax is required"); - } - if (GLAD_GL_ARB_seamless_cubemap_per_texture || GLAD_GL_AMD_seamless_cubemap_per_texture) { - glSamplerParameteri(handle, GL_TEXTURE_CUBE_MAP_SEAMLESS, seamless); - } else if (seamless == GL_FALSE) { - // We default to false because it's more common - LOG_WARNING(Render_OpenGL, "GL_ARB_seamless_cubemap_per_texture is required"); + const auto create_sampler = [&](const f32 max_anisotropy) { + OGLSampler sampler; + sampler.Create(); + const GLuint handle = sampler.handle; + glSamplerParameteri(handle, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(config.wrap_u)); + glSamplerParameteri(handle, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(config.wrap_v)); + glSamplerParameteri(handle, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(config.wrap_p)); + glSamplerParameteri(handle, GL_TEXTURE_COMPARE_MODE, compare_mode); + glSamplerParameteri(handle, GL_TEXTURE_COMPARE_FUNC, compare_func); + glSamplerParameteri(handle, GL_TEXTURE_MAG_FILTER, mag); + glSamplerParameteri(handle, GL_TEXTURE_MIN_FILTER, min); + glSamplerParameterf(handle, GL_TEXTURE_LOD_BIAS, config.LodBias()); + glSamplerParameterf(handle, GL_TEXTURE_MIN_LOD, config.MinLod()); + glSamplerParameterf(handle, GL_TEXTURE_MAX_LOD, config.MaxLod()); + glSamplerParameterfv(handle, GL_TEXTURE_BORDER_COLOR, config.BorderColor().data()); + + if (GLAD_GL_ARB_texture_filter_anisotropic || GLAD_GL_EXT_texture_filter_anisotropic) { + glSamplerParameterf(handle, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropy); + } else { + LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_anisotropic is required"); + } + if (GLAD_GL_ARB_texture_filter_minmax || GLAD_GL_EXT_texture_filter_minmax) { + glSamplerParameteri(handle, GL_TEXTURE_REDUCTION_MODE_ARB, reduction_filter); + } else if (reduction_filter != GL_WEIGHTED_AVERAGE_ARB) { + LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_minmax is required"); + } + if (GLAD_GL_ARB_seamless_cubemap_per_texture || GLAD_GL_AMD_seamless_cubemap_per_texture) { + glSamplerParameteri(handle, GL_TEXTURE_CUBE_MAP_SEAMLESS, seamless); + } else if (seamless == GL_FALSE) { + // We default to false because it's more common + LOG_WARNING(Render_OpenGL, "GL_ARB_seamless_cubemap_per_texture is required"); + } + return sampler; + }; + + sampler = create_sampler(max_anisotropy); + if (Settings::values.max_anisotropy.GetValue() > 0 && max_anisotropy > 1.0f) { + sampler_without_anisotropy = create_sampler(1.0f); } } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 1148b73d7..82756fca7 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -309,12 +309,21 @@ class Sampler { public: explicit Sampler(TextureCacheRuntime&, const Tegra::Texture::TSCEntry&); - GLuint Handle() const noexcept { + [[nodiscard]] GLuint Handle() const noexcept { return sampler.handle; } + [[nodiscard]] GLuint HandleWithoutAnisotropy() const noexcept { + return sampler_without_anisotropy.handle; + } + + [[nodiscard]] bool HasAddedAnisotropy() const noexcept { + return static_cast(sampler_without_anisotropy.handle); + } + private: OGLSampler sampler; + OGLSampler sampler_without_anisotropy; }; class Framebuffer { diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 983e1c2e1..1632a6f26 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -178,7 +178,7 @@ public: inline void PushImageDescriptors(TextureCache& texture_cache, GuestDescriptorQueue& guest_descriptor_queue, const Shader::Info& info, RescalingPushConstant& rescaling, - const VkSampler*& samplers, + const Sampler**& samplers, const VideoCommon::ImageViewInOut*& views) { const u32 num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors); const u32 num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors); @@ -187,10 +187,14 @@ inline void PushImageDescriptors(TextureCache& texture_cache, for (const auto& desc : info.texture_descriptors) { for (u32 index = 0; index < desc.count; ++index) { const VideoCommon::ImageViewId image_view_id{(views++)->id}; - const VkSampler sampler{*(samplers++)}; ImageView& image_view{texture_cache.GetImageView(image_view_id)}; const VkImageView vk_image_view{image_view.Handle(desc.type)}; - guest_descriptor_queue.AddSampledImage(vk_image_view, sampler); + const Sampler& sampler{**(samplers++)}; + const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && + !image_view.SupportsAnisotropy()}; + const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithoutAnisotropy() + : sampler.Handle()}; + guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); rescaling.PushTexture(texture_cache.IsRescaling(image_view)); } } diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 733e70d9d..eb292dc34 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -115,7 +115,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, static constexpr size_t max_elements = 64; boost::container::static_vector views; - boost::container::static_vector samplers; + boost::container::static_vector samplers; const auto& qmd{kepler_compute.launch_description}; const auto& cbufs{qmd.const_buffer_config}; @@ -161,7 +161,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, views.push_back({handle.first}); Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); - samplers.push_back(sampler->Handle()); + samplers.push_back(sampler); } } for (const auto& desc : info.image_descriptors) { @@ -192,7 +192,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, buffer_cache.BindHostComputeBuffers(); RescalingPushConstant rescaling; - const VkSampler* samplers_it{samplers.data()}; + const Sampler** samplers_it{samplers.data()}; const VideoCommon::ImageViewInOut* views_it{views.data()}; PushImageDescriptors(texture_cache, guest_descriptor_queue, info, rescaling, samplers_it, views_it); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 506b78f08..e6e004cb6 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -298,7 +298,7 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { template void GraphicsPipeline::ConfigureImpl(bool is_indexed) { std::array views; - std::array samplers; + std::array samplers; size_t sampler_index{}; size_t view_index{}; @@ -368,7 +368,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { views[view_index++] = {handle.first}; Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; - samplers[sampler_index++] = sampler->Handle(); + samplers[sampler_index++] = sampler; } } if constexpr (Spec::has_images) { @@ -453,7 +453,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { RescalingPushConstant rescaling; RenderAreaPushConstant render_area; - const VkSampler* samplers_it{samplers.data()}; + const Sampler** samplers_it{samplers.data()}; const VideoCommon::ImageViewInOut* views_it{views.data()}; const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { buffer_cache.BindHostStageBuffers(stage); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 8711e2a87..0e8f8a064 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1802,27 +1802,34 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t // Some games have samplers with garbage. Sanitize them here. const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f); - sampler = device.GetLogical().CreateSampler(VkSamplerCreateInfo{ - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .pNext = pnext, - .flags = 0, - .magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter), - .minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter), - .mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter), - .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter), - .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter), - .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter), - .mipLodBias = tsc.LodBias(), - .anisotropyEnable = static_cast(max_anisotropy > 1.0f ? VK_TRUE : VK_FALSE), - .maxAnisotropy = max_anisotropy, - .compareEnable = tsc.depth_compare_enabled, - .compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), - .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), - .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), - .borderColor = - arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color), - .unnormalizedCoordinates = VK_FALSE, - }); + const auto create_sampler = [&](const f32 max_anisotropy) { + return device.GetLogical().CreateSampler(VkSamplerCreateInfo{ + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = pnext, + .flags = 0, + .magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter), + .minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter), + .mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter), + .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter), + .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter), + .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter), + .mipLodBias = tsc.LodBias(), + .anisotropyEnable = static_cast(max_anisotropy > 1.0f ? VK_TRUE : VK_FALSE), + .maxAnisotropy = max_anisotropy, + .compareEnable = tsc.depth_compare_enabled, + .compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), + .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), + .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), + .borderColor = + arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color), + .unnormalizedCoordinates = VK_FALSE, + }); + }; + + sampler = create_sampler(max_anisotropy); + if (Settings::values.max_anisotropy.GetValue() > 0 && max_anisotropy > 1.0f) { + sampler_without_anisotropy = create_sampler(1.0f); + } } Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span color_buffers, diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 0f7a5ffd4..ee0d0480d 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -279,8 +279,17 @@ public: return *sampler; } + [[nodiscard]] VkSampler HandleWithoutAnisotropy() const noexcept { + return *sampler_without_anisotropy; + } + + [[nodiscard]] bool HasAddedAnisotropy() const noexcept { + return static_cast(sampler_without_anisotropy); + } + private: vk::Sampler sampler; + vk::Sampler sampler_without_anisotropy; }; class Framebuffer { diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index d134b6738..26fa6d63e 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -45,4 +45,43 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {} +bool ImageViewBase::SupportsAnisotropy() const noexcept { + using namespace VideoCommon; + switch (format) { + case PixelFormat::R8_UNORM: + case PixelFormat::R8_SNORM: + case PixelFormat::R8_SINT: + case PixelFormat::R8_UINT: + case PixelFormat::BC4_UNORM: + case PixelFormat::BC4_SNORM: + case PixelFormat::BC5_UNORM: + case PixelFormat::BC5_SNORM: + case PixelFormat::R32G32_FLOAT: + case PixelFormat::R32G32_SINT: + case PixelFormat::R32_FLOAT: + case PixelFormat::R16_FLOAT: + case PixelFormat::R16_UNORM: + case PixelFormat::R16_SNORM: + case PixelFormat::R16_UINT: + case PixelFormat::R16_SINT: + case PixelFormat::R16G16_UNORM: + case PixelFormat::R16G16_FLOAT: + case PixelFormat::R16G16_UINT: + case PixelFormat::R16G16_SINT: + case PixelFormat::R16G16_SNORM: + case PixelFormat::R8G8_UNORM: + case PixelFormat::R8G8_SNORM: + case PixelFormat::R8G8_SINT: + case PixelFormat::R8G8_UINT: + case PixelFormat::R32G32_UINT: + case PixelFormat::R32_UINT: + case PixelFormat::R32_SINT: + case PixelFormat::G4R4_UNORM: + return false; + default: + break; + } + return range.extent.levels > 1; +} + } // namespace VideoCommon diff --git a/src/video_core/texture_cache/image_view_base.h b/src/video_core/texture_cache/image_view_base.h index a25ae1d4a..87549ffff 100644 --- a/src/video_core/texture_cache/image_view_base.h +++ b/src/video_core/texture_cache/image_view_base.h @@ -33,6 +33,8 @@ struct ImageViewBase { return type == ImageViewType::Buffer; } + [[nodiscard]] bool SupportsAnisotropy() const noexcept; + ImageId image_id{}; GPUVAddr gpu_addr = 0; PixelFormat format{}; diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index 560b3af8a..cb24d0399 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -62,12 +62,14 @@ std::array TSCEntry::BorderColor() const noexcept { } float TSCEntry::MaxAnisotropy() const noexcept { - const bool is_unsupported_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering - ? mipmap_filter == TextureMipmapFilter::None - : mipmap_filter != TextureMipmapFilter::Linear; + const bool is_suitable_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering + ? mipmap_filter != TextureMipmapFilter::None + : mipmap_filter == TextureMipmapFilter::Linear; const bool has_regular_lods = min_lod_clamp == 0 && max_lod_clamp >= 256; - if (max_anisotropy == 0 && - (depth_compare_enabled.Value() || !has_regular_lods || is_unsupported_mipmap_filter)) { + const bool is_bilinear_filter = min_filter == TextureFilter::Linear && + reduction_filter == SamplerReduction::WeightedAverage; + if (max_anisotropy == 0 && (depth_compare_enabled.Value() || !has_regular_lods || + !is_bilinear_filter || !is_suitable_mipmap_filter)) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); From 3e8cd91d548433344d9c479bb7ad83a3bf1560c1 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Thu, 15 Jun 2023 18:46:40 +0200 Subject: [PATCH 07/12] video_core: Fixed compilation errors because of name shadowing --- src/video_core/renderer_opengl/gl_texture_cache.cpp | 12 ++++++------ src/video_core/renderer_vulkan/vk_texture_cache.cpp | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index ee5a0c723..7ff54003f 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -1270,10 +1270,10 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) { const f32 max_anisotropy = std::clamp(config.MaxAnisotropy(), 1.0f, 16.0f); - const auto create_sampler = [&](const f32 max_anisotropy) { - OGLSampler sampler; - sampler.Create(); - const GLuint handle = sampler.handle; + const auto create_sampler = [&](const f32 anisotropy) { + OGLSampler new_sampler; + new_sampler.Create(); + const GLuint handle = new_sampler.handle; glSamplerParameteri(handle, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(config.wrap_u)); glSamplerParameteri(handle, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(config.wrap_v)); glSamplerParameteri(handle, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(config.wrap_p)); @@ -1287,7 +1287,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) { glSamplerParameterfv(handle, GL_TEXTURE_BORDER_COLOR, config.BorderColor().data()); if (GLAD_GL_ARB_texture_filter_anisotropic || GLAD_GL_EXT_texture_filter_anisotropic) { - glSamplerParameterf(handle, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropy); + glSamplerParameterf(handle, GL_TEXTURE_MAX_ANISOTROPY, anisotropy); } else { LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_anisotropic is required"); } @@ -1302,7 +1302,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) { // We default to false because it's more common LOG_WARNING(Render_OpenGL, "GL_ARB_seamless_cubemap_per_texture is required"); } - return sampler; + return new_sampler; }; sampler = create_sampler(max_anisotropy); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 0e8f8a064..8ec181335 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1802,7 +1802,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t // Some games have samplers with garbage. Sanitize them here. const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f); - const auto create_sampler = [&](const f32 max_anisotropy) { + const auto create_sampler = [&](const f32 anisotropy) { return device.GetLogical().CreateSampler(VkSamplerCreateInfo{ .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, .pNext = pnext, @@ -1814,8 +1814,8 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter), .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter), .mipLodBias = tsc.LodBias(), - .anisotropyEnable = static_cast(max_anisotropy > 1.0f ? VK_TRUE : VK_FALSE), - .maxAnisotropy = max_anisotropy, + .anisotropyEnable = static_cast(anisotropy > 1.0f ? VK_TRUE : VK_FALSE), + .maxAnisotropy = anisotropy, .compareEnable = tsc.depth_compare_enabled, .compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), From 745d16132b9662de5b8317bfba37fe89c11cea45 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Thu, 15 Jun 2023 20:59:33 +0200 Subject: [PATCH 08/12] video_core: Disable AF for non-color image formats --- src/video_core/texture_cache/image_view_base.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 26fa6d63e..5ebe9b9bb 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -77,6 +77,15 @@ bool ImageViewBase::SupportsAnisotropy() const noexcept { case PixelFormat::R32_UINT: case PixelFormat::R32_SINT: case PixelFormat::G4R4_UNORM: + // Depth formats + case PixelFormat::D32_FLOAT: + case PixelFormat::D16_UNORM: + // Stencil formats + case PixelFormat::S8_UINT: + // DepthStencil formats + case PixelFormat::D24_UNORM_S8_UINT: + case PixelFormat::S8_UINT_D24_UNORM: + case PixelFormat::D32_FLOAT_S8_UINT: return false; default: break; From a3b7b5b22af8ef83fc765afac9d6f6b8dac7f62b Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Thu, 15 Jun 2023 23:16:26 +0200 Subject: [PATCH 09/12] video_core: Fallback to default anisotropy instead to 1x anisotropy --- src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | 2 +- src/video_core/renderer_opengl/gl_texture_cache.cpp | 6 ++++-- src/video_core/renderer_opengl/gl_texture_cache.h | 8 ++++---- src/video_core/renderer_vulkan/pipeline_helper.h | 2 +- src/video_core/renderer_vulkan/vk_texture_cache.cpp | 6 ++++-- src/video_core/renderer_vulkan/vk_texture_cache.h | 8 ++++---- src/video_core/textures/texture.cpp | 4 ++-- 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 0fa0fc594..58e4e1919 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp @@ -488,7 +488,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && !image_view.SupportsAnisotropy()}; gl_samplers[sampler_binding++] = - use_fallback_sampler ? sampler.HandleWithoutAnisotropy() : sampler.Handle(); + use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() : sampler.Handle(); } } for (const auto& desc : info.image_descriptors) { diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 7ff54003f..3b446be07 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -1306,8 +1306,10 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) { }; sampler = create_sampler(max_anisotropy); - if (Settings::values.max_anisotropy.GetValue() > 0 && max_anisotropy > 1.0f) { - sampler_without_anisotropy = create_sampler(1.0f); + + const f32 max_anisotropy_default = static_cast(1U << config.max_anisotropy); + if (max_anisotropy > max_anisotropy_default) { + sampler_default_anisotropy = create_sampler(max_anisotropy_default); } } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 82756fca7..3676eaaa9 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -313,17 +313,17 @@ public: return sampler.handle; } - [[nodiscard]] GLuint HandleWithoutAnisotropy() const noexcept { - return sampler_without_anisotropy.handle; + [[nodiscard]] GLuint HandleWithDefaultAnisotropy() const noexcept { + return sampler_default_anisotropy.handle; } [[nodiscard]] bool HasAddedAnisotropy() const noexcept { - return static_cast(sampler_without_anisotropy.handle); + return static_cast(sampler_default_anisotropy.handle); } private: OGLSampler sampler; - OGLSampler sampler_without_anisotropy; + OGLSampler sampler_default_anisotropy; }; class Framebuffer { diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 1632a6f26..0a9dce937 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -192,7 +192,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache, const Sampler& sampler{**(samplers++)}; const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && !image_view.SupportsAnisotropy()}; - const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithoutAnisotropy() + const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() : sampler.Handle()}; guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); rescaling.PushTexture(texture_cache.IsRescaling(image_view)); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 8ec181335..f025f618b 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1827,8 +1827,10 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t }; sampler = create_sampler(max_anisotropy); - if (Settings::values.max_anisotropy.GetValue() > 0 && max_anisotropy > 1.0f) { - sampler_without_anisotropy = create_sampler(1.0f); + + const f32 max_anisotropy_default = static_cast(1U << tsc.max_anisotropy); + if (max_anisotropy > max_anisotropy_default) { + sampler_default_anisotropy = create_sampler(max_anisotropy_default); } } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index ee0d0480d..f14525dcb 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -279,17 +279,17 @@ public: return *sampler; } - [[nodiscard]] VkSampler HandleWithoutAnisotropy() const noexcept { - return *sampler_without_anisotropy; + [[nodiscard]] VkSampler HandleWithDefaultAnisotropy() const noexcept { + return *sampler_default_anisotropy; } [[nodiscard]] bool HasAddedAnisotropy() const noexcept { - return static_cast(sampler_without_anisotropy); + return static_cast(sampler_default_anisotropy); } private: vk::Sampler sampler; - vk::Sampler sampler_without_anisotropy; + vk::Sampler sampler_default_anisotropy; }; class Framebuffer { diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index cb24d0399..63ebdfa82 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -68,8 +68,8 @@ float TSCEntry::MaxAnisotropy() const noexcept { const bool has_regular_lods = min_lod_clamp == 0 && max_lod_clamp >= 256; const bool is_bilinear_filter = min_filter == TextureFilter::Linear && reduction_filter == SamplerReduction::WeightedAverage; - if (max_anisotropy == 0 && (depth_compare_enabled.Value() || !has_regular_lods || - !is_bilinear_filter || !is_suitable_mipmap_filter)) { + if (max_anisotropy == 0 && (depth_compare_enabled || !has_regular_lods || !is_bilinear_filter || + !is_suitable_mipmap_filter)) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); From 2dc0ff79ece34286c7078922668fd9f0a19b47b7 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Fri, 16 Jun 2023 13:26:44 +0200 Subject: [PATCH 10/12] video_core: Use sampler IDs instead pointers in the pipeline config The previous approach of storing pointers returned by `GetGraphicsSampler`/`GetComputeSampler` caused UB, as these functions can cause reallocation of the sampler slot vector and therefore invalidate the pointers --- .../renderer_opengl/gl_compute_pipeline.cpp | 23 ++++++++++---- .../renderer_opengl/gl_graphics_pipeline.cpp | 8 ++--- .../renderer_vulkan/pipeline_helper.h | 5 ++-- .../renderer_vulkan/vk_compute_pipeline.cpp | 6 ++-- .../renderer_vulkan/vk_graphics_pipeline.cpp | 6 ++-- .../texture_cache/image_view_base.cpp | 1 - src/video_core/texture_cache/texture_cache.h | 30 +++++++++++++++---- .../texture_cache/texture_cache_base.h | 12 ++++++++ 8 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index 1a0cea9b7..3151c0db8 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp @@ -87,7 +87,8 @@ void ComputePipeline::Configure() { texture_cache.SynchronizeComputeDescriptors(); boost::container::static_vector views; - std::array samplers; + boost::container::static_vector samplers; + std::array gl_samplers; std::array textures; std::array images; GLsizei sampler_binding{}; @@ -131,7 +132,6 @@ void ComputePipeline::Configure() { for (u32 index = 0; index < desc.count; ++index) { const auto handle{read_handle(desc, index)}; views.push_back({handle.first}); - samplers[sampler_binding++] = 0; } } for (const auto& desc : info.image_buffer_descriptors) { @@ -142,8 +142,8 @@ void ComputePipeline::Configure() { const auto handle{read_handle(desc, index)}; views.push_back({handle.first}); - Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); - samplers[sampler_binding++] = sampler->Handle(); + VideoCommon::SamplerId sampler = texture_cache.GetComputeSamplerId(handle.second); + samplers.push_back(sampler); } } for (const auto& desc : info.image_descriptors) { @@ -186,10 +186,17 @@ void ComputePipeline::Configure() { const VideoCommon::ImageViewInOut* views_it{views.data() + num_texture_buffers + num_image_buffers}; + const VideoCommon::SamplerId* samplers_it{samplers.data()}; texture_binding += num_texture_buffers; image_binding += num_image_buffers; u32 texture_scaling_mask{}; + + for (const auto& desc : info.texture_buffer_descriptors) { + for (u32 index = 0; index < desc.count; ++index) { + gl_samplers[sampler_binding++] = 0; + } + } for (const auto& desc : info.texture_descriptors) { for (u32 index = 0; index < desc.count; ++index) { ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; @@ -198,6 +205,12 @@ void ComputePipeline::Configure() { texture_scaling_mask |= 1u << texture_binding; } ++texture_binding; + + const Sampler& sampler{texture_cache.GetSampler(*(samplers_it++))}; + const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && + !image_view.SupportsAnisotropy()}; + gl_samplers[sampler_binding++] = + use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() : sampler.Handle(); } } u32 image_scaling_mask{}; @@ -228,7 +241,7 @@ void ComputePipeline::Configure() { if (texture_binding != 0) { ASSERT(texture_binding == sampler_binding); glBindTextures(0, texture_binding, textures.data()); - glBindSamplers(0, sampler_binding, samplers.data()); + glBindSamplers(0, sampler_binding, gl_samplers.data()); } if (image_binding != 0) { glBindImageTextures(0, image_binding, images.data()); diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 58e4e1919..c58f760b8 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp @@ -275,7 +275,7 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c template void GraphicsPipeline::ConfigureImpl(bool is_indexed) { std::array views; - std::array samplers; + std::array samplers; size_t views_index{}; size_t samplers_index{}; @@ -350,7 +350,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { const auto handle{read_handle(desc, index)}; views[views_index++] = {handle.first}; - Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; + VideoCommon::SamplerId sampler{texture_cache.GetGraphicsSamplerId(handle.second)}; samplers[samplers_index++] = sampler; } } @@ -444,7 +444,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { program_manager.BindSourcePrograms(source_programs); } const VideoCommon::ImageViewInOut* views_it{views.data()}; - const Sampler** samplers_it{samplers.data()}; + const VideoCommon::SamplerId* samplers_it{samplers.data()}; GLsizei texture_binding = 0; GLsizei image_binding = 0; GLsizei sampler_binding{}; @@ -484,7 +484,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { ++texture_binding; ++stage_texture_binding; - const Sampler& sampler{**(samplers_it++)}; + const Sampler& sampler{texture_cache.GetSampler(*(samplers_it++))}; const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && !image_view.SupportsAnisotropy()}; gl_samplers[sampler_binding++] = diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 0a9dce937..71c783709 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -178,7 +178,7 @@ public: inline void PushImageDescriptors(TextureCache& texture_cache, GuestDescriptorQueue& guest_descriptor_queue, const Shader::Info& info, RescalingPushConstant& rescaling, - const Sampler**& samplers, + const VideoCommon::SamplerId*& samplers, const VideoCommon::ImageViewInOut*& views) { const u32 num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors); const u32 num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors); @@ -187,9 +187,10 @@ inline void PushImageDescriptors(TextureCache& texture_cache, for (const auto& desc : info.texture_descriptors) { for (u32 index = 0; index < desc.count; ++index) { const VideoCommon::ImageViewId image_view_id{(views++)->id}; + const VideoCommon::SamplerId sampler_id{*(samplers++)}; ImageView& image_view{texture_cache.GetImageView(image_view_id)}; const VkImageView vk_image_view{image_view.Handle(desc.type)}; - const Sampler& sampler{**(samplers++)}; + const Sampler& sampler{texture_cache.GetSampler(sampler_id)}; const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && !image_view.SupportsAnisotropy()}; const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index eb292dc34..73e585c2b 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -115,7 +115,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, static constexpr size_t max_elements = 64; boost::container::static_vector views; - boost::container::static_vector samplers; + boost::container::static_vector samplers; const auto& qmd{kepler_compute.launch_description}; const auto& cbufs{qmd.const_buffer_config}; @@ -160,7 +160,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, const auto handle{read_handle(desc, index)}; views.push_back({handle.first}); - Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); + VideoCommon::SamplerId sampler = texture_cache.GetComputeSamplerId(handle.second); samplers.push_back(sampler); } } @@ -192,7 +192,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, buffer_cache.BindHostComputeBuffers(); RescalingPushConstant rescaling; - const Sampler** samplers_it{samplers.data()}; + const VideoCommon::SamplerId* samplers_it{samplers.data()}; const VideoCommon::ImageViewInOut* views_it{views.data()}; PushImageDescriptors(texture_cache, guest_descriptor_queue, info, rescaling, samplers_it, views_it); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index e6e004cb6..c1595642e 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -298,7 +298,7 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { template void GraphicsPipeline::ConfigureImpl(bool is_indexed) { std::array views; - std::array samplers; + std::array samplers; size_t sampler_index{}; size_t view_index{}; @@ -367,7 +367,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { const auto handle{read_handle(desc, index)}; views[view_index++] = {handle.first}; - Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; + VideoCommon::SamplerId sampler{texture_cache.GetGraphicsSamplerId(handle.second)}; samplers[sampler_index++] = sampler; } } @@ -453,7 +453,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { RescalingPushConstant rescaling; RenderAreaPushConstant render_area; - const Sampler** samplers_it{samplers.data()}; + const VideoCommon::SamplerId* samplers_it{samplers.data()}; const VideoCommon::ImageViewInOut* views_it{views.data()}; const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { buffer_cache.BindHostStageBuffers(stage); diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 5ebe9b9bb..000eec869 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -46,7 +46,6 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {} bool ImageViewBase::SupportsAnisotropy() const noexcept { - using namespace VideoCommon; switch (format) { case PixelFormat::R8_UNORM: case PixelFormat::R8_SNORM: diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index c7f7448e9..4027d860b 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -222,30 +222,50 @@ void TextureCache

::CheckFeedbackLoop(std::span views) { template typename P::Sampler* TextureCache

::GetGraphicsSampler(u32 index) { + return &slot_samplers[GetGraphicsSamplerId(index)]; +} + +template +typename P::Sampler* TextureCache

::GetComputeSampler(u32 index) { + return &slot_samplers[GetComputeSamplerId(index)]; +} + +template +SamplerId TextureCache

::GetGraphicsSamplerId(u32 index) { if (index > channel_state->graphics_sampler_table.Limit()) { LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index); - return &slot_samplers[NULL_SAMPLER_ID]; + return NULL_SAMPLER_ID; } const auto [descriptor, is_new] = channel_state->graphics_sampler_table.Read(index); SamplerId& id = channel_state->graphics_sampler_ids[index]; if (is_new) { id = FindSampler(descriptor); } - return &slot_samplers[id]; + return id; } template -typename P::Sampler* TextureCache

::GetComputeSampler(u32 index) { +SamplerId TextureCache

::GetComputeSamplerId(u32 index) { if (index > channel_state->compute_sampler_table.Limit()) { LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index); - return &slot_samplers[NULL_SAMPLER_ID]; + return NULL_SAMPLER_ID; } const auto [descriptor, is_new] = channel_state->compute_sampler_table.Read(index); SamplerId& id = channel_state->compute_sampler_ids[index]; if (is_new) { id = FindSampler(descriptor); } - return &slot_samplers[id]; + return id; +} + +template +const typename P::Sampler& TextureCache

::GetSampler(SamplerId id) const noexcept { + return slot_samplers[id]; +} + +template +typename P::Sampler& TextureCache

::GetSampler(SamplerId id) noexcept { + return slot_samplers[id]; } template diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 3bfa92154..d96ddea9d 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -159,6 +159,18 @@ public: /// Get the sampler from the compute descriptor table in the specified index Sampler* GetComputeSampler(u32 index); + /// Get the sampler id from the graphics descriptor table in the specified index + SamplerId GetGraphicsSamplerId(u32 index); + + /// Get the sampler id from the compute descriptor table in the specified index + SamplerId GetComputeSamplerId(u32 index); + + /// Return a constant reference to the given sampler id + [[nodiscard]] const Sampler& GetSampler(SamplerId id) const noexcept; + + /// Return a reference to the given sampler id + [[nodiscard]] Sampler& GetSampler(SamplerId id) noexcept; + /// Refresh the state for graphics image view and sampler descriptors void SynchronizeGraphicsDescriptors(); From c309a1c69b933bd196412cae854acb4837243806 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Sat, 17 Jun 2023 11:19:39 +0200 Subject: [PATCH 11/12] video_core: Removed AF for all mip modes option as it's default now --- src/common/settings.cpp | 1 - src/common/settings.h | 2 -- src/video_core/textures/texture.cpp | 8 +++----- src/yuzu/configuration/config.cpp | 2 -- .../configuration/configure_graphics_advanced.cpp | 11 ----------- .../configuration/configure_graphics_advanced.h | 1 - .../configuration/configure_graphics_advanced.ui | 13 ------------- src/yuzu_cmd/config.cpp | 1 - src/yuzu_cmd/default_ini.h | 4 ---- 9 files changed, 3 insertions(+), 40 deletions(-) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index da5cca589..9ff3edabb 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -236,7 +236,6 @@ void RestoreGlobalState(bool is_powered_on) { values.bg_blue.SetGlobal(true); values.enable_compute_pipelines.SetGlobal(true); values.use_video_framerate.SetGlobal(true); - values.use_aggressive_anisotropic_filtering.SetGlobal(true); // System values.language_index.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index 78ca73e42..9682281b0 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -483,8 +483,6 @@ struct Values { AstcRecompression::Uncompressed, AstcRecompression::Uncompressed, AstcRecompression::Bc3, "astc_recompression"}; SwitchableSetting use_video_framerate{false, "use_video_framerate"}; - SwitchableSetting use_aggressive_anisotropic_filtering{ - false, "use_aggressive_anisotropic_filtering"}; SwitchableSetting bg_red{0, "bg_red"}; SwitchableSetting bg_green{0, "bg_green"}; diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index 63ebdfa82..d8b88d9bc 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp @@ -62,14 +62,12 @@ std::array TSCEntry::BorderColor() const noexcept { } float TSCEntry::MaxAnisotropy() const noexcept { - const bool is_suitable_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering - ? mipmap_filter != TextureMipmapFilter::None - : mipmap_filter == TextureMipmapFilter::Linear; + const bool is_suitable_mipmap_filter = mipmap_filter != TextureMipmapFilter::None; const bool has_regular_lods = min_lod_clamp == 0 && max_lod_clamp >= 256; const bool is_bilinear_filter = min_filter == TextureFilter::Linear && reduction_filter == SamplerReduction::WeightedAverage; - if (max_anisotropy == 0 && (depth_compare_enabled || !has_regular_lods || !is_bilinear_filter || - !is_suitable_mipmap_filter)) { + if (max_anisotropy == 0 && (!is_suitable_mipmap_filter || !has_regular_lods || + !is_bilinear_filter || depth_compare_enabled)) { return 1.0f; } const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 27839daaa..bac9dff90 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -761,7 +761,6 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); ReadGlobalSetting(Settings::values.enable_compute_pipelines); ReadGlobalSetting(Settings::values.use_video_framerate); - ReadGlobalSetting(Settings::values.use_aggressive_anisotropic_filtering); ReadGlobalSetting(Settings::values.bg_red); ReadGlobalSetting(Settings::values.bg_green); ReadGlobalSetting(Settings::values.bg_blue); @@ -1418,7 +1417,6 @@ void Config::SaveRendererValues() { WriteGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); WriteGlobalSetting(Settings::values.enable_compute_pipelines); WriteGlobalSetting(Settings::values.use_video_framerate); - WriteGlobalSetting(Settings::values.use_aggressive_anisotropic_filtering); WriteGlobalSetting(Settings::values.bg_red); WriteGlobalSetting(Settings::values.bg_green); WriteGlobalSetting(Settings::values.bg_blue); diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 3dce73968..0463ac8b9 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -31,7 +31,6 @@ 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_aggressive_anisotropic_filtering->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()); @@ -44,8 +43,6 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { ui->enable_compute_pipelines_checkbox->setChecked( Settings::values.enable_compute_pipelines.GetValue()); ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue()); - ui->use_aggressive_anisotropic_filtering->setChecked( - Settings::values.use_aggressive_anisotropic_filtering.GetValue()); if (Settings::IsConfiguringGlobal()) { ui->gpu_accuracy->setCurrentIndex( @@ -97,9 +94,6 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { enable_compute_pipelines); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate, ui->use_video_framerate_checkbox, use_video_framerate); - ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_aggressive_anisotropic_filtering, - ui->use_aggressive_anisotropic_filtering, - use_aggressive_anisotropic_filtering); } void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { @@ -136,8 +130,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { Settings::values.enable_compute_pipelines.UsingGlobal()); ui->use_video_framerate_checkbox->setEnabled( Settings::values.use_video_framerate.UsingGlobal()); - ui->use_aggressive_anisotropic_filtering->setEnabled( - Settings::values.use_aggressive_anisotropic_filtering.UsingGlobal()); return; } @@ -165,9 +157,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox, Settings::values.use_video_framerate, use_video_framerate); - ConfigurationShared::SetColoredTristate(ui->use_aggressive_anisotropic_filtering, - Settings::values.use_aggressive_anisotropic_filtering, - use_aggressive_anisotropic_filtering); ConfigurationShared::SetColoredComboBox( ui->gpu_accuracy, ui->label_gpu_accuracy, static_cast(Settings::values.gpu_accuracy.GetValue(true))); diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index 4b52e5d61..a4dc8ceb0 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h @@ -48,7 +48,6 @@ private: ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; ConfigurationShared::CheckState enable_compute_pipelines; ConfigurationShared::CheckState use_video_framerate; - ConfigurationShared::CheckState use_aggressive_anisotropic_filtering; const Core::System& system; }; diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index 06771c080..e7f0ef6be 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui @@ -260,19 +260,6 @@ Compute pipelines are always enabled on all other drivers. - - - - Enable this option for a more aggressive approach to applying Anisotropic Filtering to textures. -By toggling this, Anisotropic Filtering is added to textures with both nearest and linear mipmapping modes. -This may result in improved visual quality for a wider range of textures, but can also introduce artifacts in -some titles. - - - Apply Anisotropic Filtering for all mipmap modes - - - diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index f5a5364da..c5bc472ca 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -321,7 +321,6 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.astc_recompression); ReadSetting("Renderer", Settings::values.use_fast_gpu_time); ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache); - ReadSetting("Renderer", Settings::values.use_aggressive_anisotropic_filtering); ReadSetting("Renderer", Settings::values.bg_red); ReadSetting("Renderer", Settings::values.bg_green); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index f12e2dfc9..911d461e4 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -325,10 +325,6 @@ aspect_ratio = # 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x max_anisotropy = -# Apply Anisotropic Filtering to all mipmap modes. -# 0 (default): Off, 1: On -use_aggressive_anisotropic_filtering = - # Whether to enable VSync or not. # OpenGL: Values other than 0 enable VSync # Vulkan: FIFO is selected if the requested mode is not supported by the driver. From 3e47ebe2e90d0272ed516b09a0f527489daaf047 Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Sat, 17 Jun 2023 14:20:44 +0200 Subject: [PATCH 12/12] video_core: Only apply AF to 2D (array) image types --- src/video_core/texture_cache/image_view_base.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 000eec869..0c5f4450d 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -46,6 +46,12 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {} bool ImageViewBase::SupportsAnisotropy() const noexcept { + const bool has_mips = range.extent.levels > 1; + const bool is_2d = type == ImageViewType::e2D || type == ImageViewType::e2DArray; + if (!has_mips || !is_2d) { + return false; + } + switch (format) { case PixelFormat::R8_UNORM: case PixelFormat::R8_SNORM: @@ -87,9 +93,8 @@ bool ImageViewBase::SupportsAnisotropy() const noexcept { case PixelFormat::D32_FLOAT_S8_UINT: return false; default: - break; + return true; } - return range.extent.levels > 1; } } // namespace VideoCommon