From 93eea7cb1382cee1a265f330b824dcf1ca65294c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 29 Jul 2021 17:43:35 -0700 Subject: [PATCH] VideoCommon: Add option to use old behavior (Fast Texture Sampling) Co-authored-by: JosJuice --- .../features/settings/model/BooleanSetting.java | 2 ++ .../settings/ui/SettingsFragmentPresenter.java | 2 ++ .../Android/app/src/main/res/values/strings.xml | 2 ++ Source/Core/Core/Config/GraphicsSettings.cpp | 2 ++ Source/Core/Core/Config/GraphicsSettings.h | 1 + .../DolphinQt/Config/Graphics/HacksWidget.cpp | 15 +++++++++++++++ .../Core/DolphinQt/Config/Graphics/HacksWidget.h | 3 ++- Source/Core/VideoCommon/PixelShaderGen.cpp | 16 ++++++++++++++++ Source/Core/VideoCommon/ShaderGenCommon.cpp | 1 + Source/Core/VideoCommon/ShaderGenCommon.h | 1 + Source/Core/VideoCommon/VideoConfig.cpp | 1 + Source/Core/VideoCommon/VideoConfig.h | 1 + 12 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java index ac3f86eb8a2..7b488719a66 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java @@ -198,6 +198,8 @@ public enum BooleanSetting implements AbstractBooleanSetting GFX_HACK_EFB_EMULATE_FORMAT_CHANGES(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "EFBEmulateFormatChanges", false), GFX_HACK_VERTEX_ROUDING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "VertexRounding", false), + GFX_HACK_FAST_TEXTURE_SAMPLING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, + "FastTextureSampling", false), LOGGER_WRITE_TO_FILE(Settings.FILE_LOGGER, Settings.SECTION_LOGGER_OPTIONS, "WriteToFile", false), diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java index bc23b2042ab..3eb95efa689 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java @@ -719,6 +719,8 @@ public final class SettingsFragmentPresenter R.string.vertex_rounding, R.string.vertex_rounding_description)); sl.add(new CheckBoxSetting(mContext, BooleanSetting.GFX_SAVE_TEXTURE_CACHE_TO_STATE, R.string.texture_cache_to_state, R.string.texture_cache_to_state_description)); + sl.add(new CheckBoxSetting(mContext, BooleanSetting.GFX_HACK_FAST_TEXTURE_SAMPLING, + R.string.fast_texture_sampling, R.string.fast_texture_sampling_description)); } private void addAdvancedGraphicsSettings(ArrayList sl) diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index efcdf82bd42..664e9e83437 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -277,6 +277,8 @@ Rounds 2D vertices to whole pixels. Fixes graphical problems in some games at higher internal resolutions. This setting has no effect when native internal resolution is used. If unsure, leave this unchecked. Save Texture Cache to State Includes the contents of the embedded frame buffer (EFB) and upscaled EFB copies in save states. Fixes missing and/or non-upscaled textures/objects when loading states at the cost of additional save/load time. + Fast Texture Sampling + Use the video backend\'s built-in texture sampling functionality instead of a manual implementation. Aspect Ratio Select what aspect ratio to use when rendering Shader Compilation Mode diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index d1c7b21cf99..d859cab1506 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -150,6 +150,8 @@ const Info GFX_HACK_EFB_EMULATE_FORMAT_CHANGES{ const Info GFX_HACK_VERTEX_ROUDING{{System::GFX, "Hacks", "VertexRounding"}, false}; const Info GFX_HACK_MISSING_COLOR_VALUE{{System::GFX, "Hacks", "MissingColorValue"}, 0xFFFFFFFF}; +const Info GFX_HACK_FAST_TEXTURE_SAMPLING{{System::GFX, "Hacks", "FastTextureSampling"}, + false}; // Graphics.GameSpecific diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index cc112722ba6..3936b65cd9f 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -123,6 +123,7 @@ extern const Info GFX_HACK_COPY_EFB_SCALED; extern const Info GFX_HACK_EFB_EMULATE_FORMAT_CHANGES; extern const Info GFX_HACK_VERTEX_ROUDING; extern const Info GFX_HACK_MISSING_COLOR_VALUE; +extern const Info GFX_HACK_FAST_TEXTURE_SAMPLING; // Graphics.GameSpecific diff --git a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp index 2765e2e2fdd..4dc302ce1ee 100644 --- a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp @@ -106,11 +106,14 @@ void HacksWidget::CreateWidgets() m_vertex_rounding = new GraphicsBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUDING); m_save_texture_cache_state = new GraphicsBool(tr("Save Texture Cache to State"), Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE); + m_fast_texture_sampling = + new GraphicsBool(tr("Fast Texture Sampling"), Config::GFX_HACK_FAST_TEXTURE_SAMPLING); other_layout->addWidget(m_fast_depth_calculation, 0, 0); other_layout->addWidget(m_disable_bounding_box, 0, 1); other_layout->addWidget(m_vertex_rounding, 1, 0); other_layout->addWidget(m_save_texture_cache_state, 1, 1); + other_layout->addWidget(m_fast_texture_sampling, 2, 0); main_layout->addWidget(efb_box); main_layout->addWidget(texture_cache_box); @@ -276,6 +279,17 @@ void HacksWidget::AddDescriptions() "higher internal resolutions. This setting has no effect when native internal " "resolution is used.

If unsure, leave this " "unchecked."); + static const char TR_FAST_TEXTURE_SAMPLING_DESCRIPTION[] = QT_TR_NOOP( + "Use the video backend's built-in texture sampling functionality instead of a manual " + "implementation.

" + "This setting can cause potentially improve performance, especially at higher internal " + "resolutions; additionally, Anisotropic Filtering currently only works with Fast Texture " + "Sampling.

" + "This comes at the cost of graphical issues in some games on certain GPUs, most commonly " + "vertical lines on FMVs, as well as lack of emulation of texture wrapping special cases " + "(though this also only works at 1x IR or when scaled EFB is disabled, and with custom " + "textures disabled) and worse emulation of Level of Detail calculation.

" + "If unsure, leave this unchecked."); m_skip_efb_cpu->SetDescription(tr(TR_SKIP_EFB_CPU_ACCESS_DESCRIPTION)); m_ignore_format_changes->SetDescription(tr(TR_IGNORE_FORMAT_CHANGE_DESCRIPTION)); @@ -291,6 +305,7 @@ void HacksWidget::AddDescriptions() m_disable_bounding_box->SetDescription(tr(TR_DISABLE_BOUNDINGBOX_DESCRIPTION)); m_save_texture_cache_state->SetDescription(tr(TR_SAVE_TEXTURE_CACHE_TO_STATE_DESCRIPTION)); m_vertex_rounding->SetDescription(tr(TR_VERTEX_ROUNDING_DESCRIPTION)); + m_fast_texture_sampling->SetDescription(tr(TR_FAST_TEXTURE_SAMPLING_DESCRIPTION)); } void HacksWidget::UpdateDeferEFBCopiesEnabled() diff --git a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h index 2af4a12fea2..c34cd27ff8e 100644 --- a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h +++ b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h @@ -26,6 +26,7 @@ private: GraphicsBool* m_skip_efb_cpu; GraphicsBool* m_ignore_format_changes; GraphicsBool* m_store_efb_copies; + GraphicsBool* m_defer_efb_copies; // Texture Cache QLabel* m_accuracy_label; @@ -42,7 +43,7 @@ private: GraphicsBool* m_disable_bounding_box; GraphicsBool* m_vertex_rounding; GraphicsBool* m_save_texture_cache_state; - GraphicsBool* m_defer_efb_copies; + GraphicsBool* m_fast_texture_sampling; void CreateWidgets(); void ConnectWidgets(); diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index bff76d42464..fd9933c2ae0 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -537,6 +537,7 @@ void UpdateBoundingBox(float2 rawpos) {{ fmt::arg("efb_height", EFB_HEIGHT), fmt::arg("efb_scale", I_EFBSCALE)); } + if (host_config.manual_texture_sampling) { if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) { @@ -596,6 +597,21 @@ uint WrapCoord(int coord, uint wrap, int size) {{ "int2 uv, int layer) {{\n"); } + if (!host_config.manual_texture_sampling) + { + out.Write(" float size_s = float(" I_TEXDIMS "[texmap].x * 128);\n" + " float size_t = float(" I_TEXDIMS "[texmap].y * 128);\n" + " float3 coords = float3(float(uv.x) / size_s, float(uv.y) / size_t, layer);\n"); + if (api_type == APIType::OpenGL || api_type == APIType::Vulkan) + { + out.Write(" return iround(255.0 * texture(tex, coords));\n}}\n"); + } + else if (api_type == APIType::D3D) + { + out.Write(" return iround(255.0 * tex.Sample(tex_samp, coords));\n}}\n"); + } + } + else { out.Write(R"( uint texmode0 = samp_texmode0(texmap); diff --git a/Source/Core/VideoCommon/ShaderGenCommon.cpp b/Source/Core/VideoCommon/ShaderGenCommon.cpp index 72a7e0d14fe..49fd1c9783c 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.cpp +++ b/Source/Core/VideoCommon/ShaderGenCommon.cpp @@ -39,6 +39,7 @@ ShaderHostConfig ShaderHostConfig::GetCurrent() bits.backend_logic_op = g_ActiveConfig.backend_info.bSupportsLogicOp; bits.backend_palette_conversion = g_ActiveConfig.backend_info.bSupportsPaletteConversion; bits.enable_validation_layer = g_ActiveConfig.bEnableValidationLayer; + bits.manual_texture_sampling = !g_ActiveConfig.bFastTextureSampling; return bits; } diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index ebdcda262ba..46d34e18c64 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -169,6 +169,7 @@ union ShaderHostConfig BitField<21, 1, bool, u32> backend_logic_op; BitField<22, 1, bool, u32> backend_palette_conversion; BitField<23, 1, bool, u32> enable_validation_layer; + BitField<24, 1, bool, u32> manual_texture_sampling; static ShaderHostConfig GetCurrent(); }; diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 255e1722b9c..88ec126c7cb 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -135,6 +135,7 @@ void VideoConfig::Refresh() bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUDING); iEFBAccessTileSize = Config::Get(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE); iMissingColorValue = Config::Get(Config::GFX_HACK_MISSING_COLOR_VALUE); + bFastTextureSampling = Config::Get(Config::GFX_HACK_FAST_TEXTURE_SAMPLING); bPerfQueriesEnable = Config::Get(Config::GFX_PERF_QUERIES_ENABLE); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index d4307c479aa..40922b3ecfc 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -135,6 +135,7 @@ struct VideoConfig final int iLog = 0; // CONF_ bits int iSaveTargetId = 0; // TODO: Should be dropped u32 iMissingColorValue = 0; + bool bFastTextureSampling = false; // Stereoscopy StereoMode stereo_mode{};