diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2023-08-18 20:33:09 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-18 20:33:09 +0200 |
| commit | 3441fe6efc8aaba0135ca623d113e127cc5fc7b4 (patch) | |
| tree | 19ca343609f56ac4850e0921416bfa8f72778129 /Source/Core | |
| parent | a9ec2a6e41ef43189ccdae5926b39169a9693ef1 (diff) | |
| parent | 80b453082dff9545e7b040fbe546055dac310b5c (diff) | |
Merge pull request #11999 from Filoppi/post_process_fixes
Video: implement output resampling (upscaling/downscaling) methods
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/Config/GraphicsSettings.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/Core/Config/GraphicsSettings.h | 2 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp | 68 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h | 1 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/PostProcessing.cpp | 103 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/PostProcessing.h | 3 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VideoConfig.cpp | 1 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VideoConfig.h | 12 |
8 files changed, 156 insertions, 36 deletions
diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index 9a0dfbcd26..ad0059ca6d 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -118,6 +118,8 @@ const Info<std::string> GFX_DRIVER_LIB_NAME{{System::GFX, "Settings", "DriverLib const Info<TextureFilteringMode> GFX_ENHANCE_FORCE_TEXTURE_FILTERING{ {System::GFX, "Enhancements", "ForceTextureFiltering"}, TextureFilteringMode::Default}; const Info<int> GFX_ENHANCE_MAX_ANISOTROPY{{System::GFX, "Enhancements", "MaxAnisotropy"}, 0}; +const Info<OutputResamplingMode> GFX_ENHANCE_OUTPUT_RESAMPLING{ + {System::GFX, "Enhancements", "OutputResampling"}, OutputResamplingMode::Default}; const Info<std::string> GFX_ENHANCE_POST_SHADER{ {System::GFX, "Enhancements", "PostProcessingShader"}, ""}; const Info<bool> GFX_ENHANCE_FORCE_TRUE_COLOR{{System::GFX, "Enhancements", "ForceTrueColor"}, diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index 009b219136..165114e419 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -11,6 +11,7 @@ enum class AspectMode : int; enum class ShaderCompilationMode : int; enum class StereoMode : int; enum class TextureFilteringMode : int; +enum class OutputResamplingMode : int; enum class ColorCorrectionRegion : int; enum class TriState : int; @@ -101,6 +102,7 @@ extern const Info<bool> GFX_MODS_ENABLE; extern const Info<TextureFilteringMode> GFX_ENHANCE_FORCE_TEXTURE_FILTERING; extern const Info<int> GFX_ENHANCE_MAX_ANISOTROPY; // NOTE - this is x in (1 << x) +extern const Info<OutputResamplingMode> GFX_ENHANCE_OUTPUT_RESAMPLING; extern const Info<std::string> GFX_ENHANCE_POST_SHADER; extern const Info<bool> GFX_ENHANCE_FORCE_TRUE_COLOR; extern const Info<bool> GFX_ENHANCE_DISABLE_COPY_FILTER; diff --git a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp index 47e22ade53..f181780749 100644 --- a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp @@ -105,6 +105,22 @@ void EnhancementsWidget::CreateWidgets() m_texture_filtering_combo->addItem(tr("Force Linear and 16x Anisotropic"), TEXTURE_FILTERING_FORCE_LINEAR_ANISO_16X); + m_output_resampling_combo = new ToolTipComboBox(); + m_output_resampling_combo->addItem(tr("Default"), + static_cast<int>(OutputResamplingMode::Default)); + m_output_resampling_combo->addItem(tr("Bilinear"), + static_cast<int>(OutputResamplingMode::Bilinear)); + m_output_resampling_combo->addItem(tr("Bicubic: B-Spline"), + static_cast<int>(OutputResamplingMode::BSpline)); + m_output_resampling_combo->addItem(tr("Bicubic: Mitchell-Netravali"), + static_cast<int>(OutputResamplingMode::MitchellNetravali)); + m_output_resampling_combo->addItem(tr("Bicubic: Catmull-Rom"), + static_cast<int>(OutputResamplingMode::CatmullRom)); + m_output_resampling_combo->addItem(tr("Sharp Bilinear"), + static_cast<int>(OutputResamplingMode::SharpBilinear)); + m_output_resampling_combo->addItem(tr("Area Sampling"), + static_cast<int>(OutputResamplingMode::AreaSampling)); + m_configure_color_correction = new ToolTipPushButton(tr("Configure")); m_pp_effect = new ToolTipComboBox(); @@ -136,6 +152,10 @@ void EnhancementsWidget::CreateWidgets() enhancements_layout->addWidget(m_texture_filtering_combo, row, 1, 1, -1); ++row; + enhancements_layout->addWidget(new QLabel(tr("Output Resampling:")), row, 0); + enhancements_layout->addWidget(m_output_resampling_combo, row, 1, 1, -1); + ++row; + enhancements_layout->addWidget(new QLabel(tr("Color Correction:")), row, 0); enhancements_layout->addWidget(m_configure_color_correction, row, 1, 1, -1); ++row; @@ -195,6 +215,8 @@ void EnhancementsWidget::ConnectWidgets() [this](int) { SaveSettings(); }); connect(m_texture_filtering_combo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { SaveSettings(); }); + connect(m_output_resampling_combo, qOverload<int>(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); connect(m_pp_effect, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { SaveSettings(); }); connect(m_3d_mode, qOverload<int>(&QComboBox::currentIndexChanged), [this] { @@ -325,6 +347,14 @@ void EnhancementsWidget::LoadSettings() break; } + // Resampling + const OutputResamplingMode output_resampling_mode = + Config::Get(Config::GFX_ENHANCE_OUTPUT_RESAMPLING); + m_output_resampling_combo->setCurrentIndex(static_cast<int>(output_resampling_mode)); + + m_output_resampling_combo->setEnabled(g_Config.backend_info.bSupportsPostProcessing); + + // Color Correction m_configure_color_correction->setEnabled(g_Config.backend_info.bSupportsPostProcessing); // Post Processing Shader @@ -413,6 +443,10 @@ void EnhancementsWidget::SaveSettings() break; } + const int output_resampling_selection = m_output_resampling_combo->currentData().toInt(); + Config::SetBaseOrCurrent(Config::GFX_ENHANCE_OUTPUT_RESAMPLING, + static_cast<OutputResamplingMode>(output_resampling_selection)); + const bool anaglyph = g_Config.stereo_mode == StereoMode::Anaglyph; const bool passive = g_Config.stereo_mode == StereoMode::Passive; Config::SetBaseOrCurrent(Config::GFX_ENHANCE_POST_SHADER, @@ -455,6 +489,37 @@ void EnhancementsWidget::AddDescriptions() "scaling filter selected by the game.<br><br>Any option except 'Default' will alter the look " "of the game's textures and might cause issues in a small number of " "games.<br><br><dolphin_emphasis>If unsure, select 'Default'.</dolphin_emphasis>"); + static const char TR_OUTPUT_RESAMPLING_DESCRIPTION[] = + QT_TR_NOOP("Affects how the game output is scaled to the window resolution." + "<br>The performance mostly depends on the number of samples each method uses." + "<br>Compared to SSAA, resampling is useful in case the output window" + "<br>resolution isn't a multiplier of the native emulation resolution." + + "<br><br><b>Default</b> - [fastest]" + "<br>Internal GPU bilinear sampler which is not gamma corrected." + "<br>This setting might be ignored if gamma correction is forced on." + + "<br><br><b>Bilinear</b> - [4 samples]" + "<br>Gamma corrected linear interpolation between pixels." + + "<br><br><b>Bicubic</b> - [16 samples]" + "<br>Gamma corrected cubic interpolation between pixels." + "<br>Good when rescaling between close resolutions. i.e 1080p and 1440p." + "<br>Comes in various flavors:" + "<br><b>B-Spline</b>: Blurry, but avoids all lobing artifacts" + "<br><b>Mitchell-Netravali</b>: Good middle ground between blurry and lobing" + "<br><b>Catmull-Rom</b>: Sharper, but can cause lobing artifacts" + + "<br><br><b>Sharp Bilinear</b> - [1-4 samples]" + "<br>Similarly to \"Nearest Neighbor\", it maintains a sharp look," + "<br>but also does some blending to avoid shimmering." + "<br>Works best with 2D games at low resolutions." + + "<br><br><b>Area Sampling</b> - [up to 324 samples]" + "<br>Weights pixels by the percentage of area they occupy. Gamma corrected." + "<br>Best for down scaling by more than 2x." + + "<br><br><dolphin_emphasis>If unsure, select 'Default'.</dolphin_emphasis>"); static const char TR_COLOR_CORRECTION_DESCRIPTION[] = QT_TR_NOOP("A group of features to make the colors more accurate, matching the color space " "Wii and GC games were meant for."); @@ -537,6 +602,9 @@ void EnhancementsWidget::AddDescriptions() m_texture_filtering_combo->SetTitle(tr("Texture Filtering")); m_texture_filtering_combo->SetDescription(tr(TR_FORCE_TEXTURE_FILTERING_DESCRIPTION)); + m_output_resampling_combo->SetTitle(tr("Output Resampling")); + m_output_resampling_combo->SetDescription(tr(TR_OUTPUT_RESAMPLING_DESCRIPTION)); + m_configure_color_correction->SetTitle(tr("Color Correction")); m_configure_color_correction->SetDescription(tr(TR_COLOR_CORRECTION_DESCRIPTION)); diff --git a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h index 4d2cdcd5b5..34879d17b7 100644 --- a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h +++ b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h @@ -39,6 +39,7 @@ private: ConfigChoice* m_ir_combo; ToolTipComboBox* m_aa_combo; ToolTipComboBox* m_texture_filtering_combo; + ToolTipComboBox* m_output_resampling_combo; ToolTipComboBox* m_pp_effect; ToolTipPushButton* m_configure_color_correction; QPushButton* m_configure_pp_effect; diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index c3a245629f..49b05e6762 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -419,9 +419,9 @@ std::vector<std::string> PostProcessing::GetPassiveShaderList() bool PostProcessing::Initialize(AbstractTextureFormat format) { m_framebuffer_format = format; - // CompilePixelShader must be run first if configuration options are used. + // CompilePixelShader() must be run first if configuration options are used. // Otherwise the UBO has a different member list between vertex and pixel - // shaders, which is a link error. + // shaders, which is a link error on some backends. if (!CompilePixelShader() || !CompileVertexShader() || !CompilePipeline()) return false; @@ -486,23 +486,29 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst, MathUtil::Rectangle<int> src_rect = src; g_gfx->SetSamplerState(0, RenderState::GetLinearSamplerState()); + g_gfx->SetSamplerState(1, RenderState::GetPointSamplerState()); g_gfx->SetTexture(0, src_tex); + g_gfx->SetTexture(1, src_tex); - const bool is_color_correction_active = IsColorCorrectionActive(); + const bool needs_color_correction = IsColorCorrectionActive(); + // Rely on the default (bi)linear sampler with the default mode + // (it might not be gamma corrected). + const bool needs_resampling = + g_ActiveConfig.output_resampling_mode > OutputResamplingMode::Default; const bool needs_intermediary_buffer = NeedsIntermediaryBuffer(); + const bool needs_default_pipeline = needs_color_correction || needs_resampling; const AbstractPipeline* final_pipeline = m_pipeline.get(); std::vector<u8>* uniform_staging_buffer = &m_default_uniform_staging_buffer; bool default_uniform_staging_buffer = true; + const MathUtil::Rectangle<int> present_rect = g_presenter->GetTargetRectangle(); // Intermediary pass. - // We draw to a high quality intermediary texture for two reasons: + // We draw to a high quality intermediary texture for a couple reasons: + // -Consistently do high quality gamma corrected resampling (upscaling/downscaling) // -Keep quality for gamma and gamut conversions, and HDR output // (low bit depths lose too much quality with gamma conversions) - // -We make a texture of the exact same res as the source one, - // because all the post process shaders we already had assume that - // the source texture size (EFB) is different from the swap chain - // texture size (which matches the window size). - if (m_default_pipeline && is_color_correction_active && needs_intermediary_buffer) + // -Keep the post process phase in linear space, to better operate with colors + if (m_default_pipeline && needs_default_pipeline && needs_intermediary_buffer) { AbstractFramebuffer* const previous_framebuffer = g_gfx->GetCurrentFramebuffer(); @@ -512,13 +518,18 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst, // so it would be a waste to allocate two layers (see "bUsesExplictQuadBuffering"). const u32 target_layers = copy_all_layers ? src_tex->GetLayers() : 1; + const u32 target_width = + needs_resampling ? present_rect.GetWidth() : static_cast<u32>(src_rect.GetWidth()); + const u32 target_height = + needs_resampling ? present_rect.GetHeight() : static_cast<u32>(src_rect.GetHeight()); + if (!m_intermediary_frame_buffer || !m_intermediary_color_texture || - m_intermediary_color_texture.get()->GetWidth() != static_cast<u32>(src_rect.GetWidth()) || - m_intermediary_color_texture.get()->GetHeight() != static_cast<u32>(src_rect.GetHeight()) || + m_intermediary_color_texture.get()->GetWidth() != target_width || + m_intermediary_color_texture.get()->GetHeight() != target_height || m_intermediary_color_texture.get()->GetLayers() != target_layers) { const TextureConfig intermediary_color_texture_config( - src_rect.GetWidth(), src_rect.GetHeight(), 1, target_layers, src_tex->GetSamples(), + target_width, target_height, 1, target_layers, src_tex->GetSamples(), s_intermediary_buffer_format, AbstractTextureFlag_RenderTarget); m_intermediary_color_texture = g_gfx->CreateTexture(intermediary_color_texture_config, "Intermediary post process texture"); @@ -530,8 +541,8 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst, g_gfx->SetFramebuffer(m_intermediary_frame_buffer.get()); FillUniformBuffer(src_rect, src_tex, src_layer, g_gfx->GetCurrentFramebuffer()->GetRect(), - g_presenter->GetTargetRectangle(), uniform_staging_buffer->data(), - !default_uniform_staging_buffer); + present_rect, uniform_staging_buffer->data(), !default_uniform_staging_buffer, + true); g_vertex_manager->UploadUtilityUniforms(uniform_staging_buffer->data(), static_cast<u32>(uniform_staging_buffer->size())); @@ -544,6 +555,7 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst, src_rect = m_intermediary_color_texture->GetRect(); src_tex = m_intermediary_color_texture.get(); g_gfx->SetTexture(0, src_tex); + g_gfx->SetTexture(1, src_tex); // The "m_intermediary_color_texture" has already copied // from the specified source layer onto its first one. // If we query for a layer that the source texture doesn't have, @@ -557,7 +569,7 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst, // If we have no custom user shader selected, and color correction // is active, directly run the fixed pipeline shader instead of // doing two passes, with the second one doing nothing useful. - if (m_default_pipeline && is_color_correction_active) + if (m_default_pipeline && needs_default_pipeline) { final_pipeline = m_default_pipeline.get(); } @@ -580,8 +592,8 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst, if (final_pipeline) { FillUniformBuffer(src_rect, src_tex, src_layer, g_gfx->GetCurrentFramebuffer()->GetRect(), - g_presenter->GetTargetRectangle(), uniform_staging_buffer->data(), - !default_uniform_staging_buffer); + present_rect, uniform_staging_buffer->data(), !default_uniform_staging_buffer, + false); g_vertex_manager->UploadUtilityUniforms(uniform_staging_buffer->data(), static_cast<u32>(uniform_staging_buffer->size())); @@ -609,7 +621,11 @@ std::string PostProcessing::GetUniformBufferHeader(bool user_post_process) const // The first (but not necessarily only) source layer we target ss << " int src_layer;\n"; ss << " uint time;\n"; + ss << " int graphics_api;\n"; + // If true, it's an intermediary buffer (including the first), if false, it's the final one + ss << " int intermediary_buffer;\n"; + ss << " int resampling_method;\n"; ss << " int correct_color_space;\n"; ss << " int game_color_space;\n"; ss << " int correct_gamma;\n"; @@ -742,6 +758,7 @@ void SetOutput(float4 color) #define GetOption(x) (x) #define OptionEnabled(x) ((x) != 0) +#define OptionDisabled(x) ((x) == 0) )"; return ss.str(); @@ -752,13 +769,9 @@ std::string PostProcessing::GetFooter() const return {}; } -bool PostProcessing::CompileVertexShader() +std::string GetVertexShaderBody() { std::ostringstream ss; - // We never need the user selected post process custom uniforms in the vertex shader - const bool user_post_process = false; - ss << GetUniformBufferHeader(user_post_process); - if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { ss << "VARYING_LOCATION(0) out VertexData {\n"; @@ -779,21 +792,34 @@ bool PostProcessing::CompileVertexShader() // Vulkan Y needs to be inverted on every pass if (g_ActiveConfig.backend_info.api_type == APIType::Vulkan) + { ss << " opos.y = -opos.y;\n"; - - std::string s2 = ss.str(); - s2 += "}\n"; - m_default_vertex_shader = g_gfx->CreateShaderFromSource(ShaderStage::Vertex, s2, - "Default post-processing vertex shader"); - - // OpenGL Y needs to be inverted once only (in the last pass) - if (g_ActiveConfig.backend_info.api_type == APIType::OpenGL) - ss << " opos.y = -opos.y;\n"; + } + // OpenGL Y needs to be inverted in all passes except the last one + else if (g_ActiveConfig.backend_info.api_type == APIType::OpenGL) + { + ss << " if (intermediary_buffer != 0)\n"; + ss << " opos.y = -opos.y;\n"; + } ss << "}\n"; + return ss.str(); +} +bool PostProcessing::CompileVertexShader() +{ + std::ostringstream ss_default; + ss_default << GetUniformBufferHeader(false); + ss_default << GetVertexShaderBody(); + m_default_vertex_shader = g_gfx->CreateShaderFromSource(ShaderStage::Vertex, ss_default.str(), + "Default post-processing vertex shader"); + + std::ostringstream ss; + ss << GetUniformBufferHeader(true); + ss << GetVertexShaderBody(); m_vertex_shader = g_gfx->CreateShaderFromSource(ShaderStage::Vertex, ss.str(), "Post-processing vertex shader"); + if (!m_default_vertex_shader || !m_vertex_shader) { PanicAlertFmt("Failed to compile post-processing vertex shader"); @@ -816,6 +842,9 @@ struct BuiltinUniforms std::array<float, 4> src_rect; s32 src_layer; u32 time; + s32 graphics_api; + s32 intermediary_buffer; + s32 resampling_method; s32 correct_color_space; s32 game_color_space; s32 correct_gamma; @@ -839,7 +868,7 @@ void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src, const AbstractTexture* src_tex, int src_layer, const MathUtil::Rectangle<int>& dst, const MathUtil::Rectangle<int>& wnd, u8* buffer, - bool user_post_process) + bool user_post_process, bool intermediary_buffer) { const float rcp_src_width = 1.0f / src_tex->GetWidth(); const float rcp_src_height = 1.0f / src_tex->GetHeight(); @@ -860,7 +889,10 @@ void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src, static_cast<float>(src.GetHeight()) * rcp_src_height}; builtin_uniforms.src_layer = static_cast<s32>(src_layer); builtin_uniforms.time = static_cast<u32>(m_timer.ElapsedMs()); + builtin_uniforms.graphics_api = static_cast<s32>(g_ActiveConfig.backend_info.api_type); + builtin_uniforms.intermediary_buffer = static_cast<s32>(intermediary_buffer); + builtin_uniforms.resampling_method = static_cast<s32>(g_ActiveConfig.output_resampling_mode); // Color correction related uniforms. // These are mainly used by the "m_default_pixel_shader", // but should also be accessible to all other shaders. @@ -883,6 +915,8 @@ void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src, std::memcpy(buffer, &builtin_uniforms, sizeof(builtin_uniforms)); buffer += sizeof(builtin_uniforms); + // Don't include the custom pp shader options if they are not necessary, + // having mismatching uniforms between different shaders can cause issues on some backends if (!user_post_process) return; @@ -1000,8 +1034,7 @@ bool PostProcessing::CompilePipeline() const bool needs_intermediary_buffer = NeedsIntermediaryBuffer(); AbstractPipelineConfig config = {}; - config.vertex_shader = - needs_intermediary_buffer ? m_vertex_shader.get() : m_default_vertex_shader.get(); + config.vertex_shader = m_default_vertex_shader.get(); // This geometry shader will take care of reading both layer 0 and 1 on the source texture, // and writing to both layer 0 and 1 on the render target. config.geometry_shader = UseGeometryShaderForPostProcess(needs_intermediary_buffer) ? @@ -1018,7 +1051,7 @@ bool PostProcessing::CompilePipeline() if (config.pixel_shader) m_default_pipeline = g_gfx->CreatePipeline(config); - config.vertex_shader = m_default_vertex_shader.get(); + config.vertex_shader = m_vertex_shader.get(); config.geometry_shader = UseGeometryShaderForPostProcess(false) ? g_shader_cache->GetTexcoordGeometryShader() : nullptr; diff --git a/Source/Core/VideoCommon/PostProcessing.h b/Source/Core/VideoCommon/PostProcessing.h index b8b648d2d0..b636f3b133 100644 --- a/Source/Core/VideoCommon/PostProcessing.h +++ b/Source/Core/VideoCommon/PostProcessing.h @@ -124,7 +124,8 @@ protected: size_t CalculateUniformsSize(bool user_post_process) const; void FillUniformBuffer(const MathUtil::Rectangle<int>& src, const AbstractTexture* src_tex, int src_layer, const MathUtil::Rectangle<int>& dst, - const MathUtil::Rectangle<int>& wnd, u8* buffer, bool user_post_process); + const MathUtil::Rectangle<int>& wnd, u8* buffer, bool user_post_process, + bool intermediary_buffer); // Timer for determining our time value Common::Timer m_timer; diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 42bf178047..83dc5eb53e 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -133,6 +133,7 @@ void VideoConfig::Refresh() texture_filtering_mode = Config::Get(Config::GFX_ENHANCE_FORCE_TEXTURE_FILTERING); iMaxAnisotropy = Config::Get(Config::GFX_ENHANCE_MAX_ANISOTROPY); + output_resampling_mode = Config::Get(Config::GFX_ENHANCE_OUTPUT_RESAMPLING); sPostProcessingShader = Config::Get(Config::GFX_ENHANCE_POST_SHADER); bForceTrueColor = Config::Get(Config::GFX_ENHANCE_FORCE_TRUE_COLOR); bDisableCopyFilter = Config::Get(Config::GFX_ENHANCE_DISABLE_COPY_FILTER); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 20f4aa8a28..6e34a43934 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -52,6 +52,17 @@ enum class TextureFilteringMode : int Linear, }; +enum class OutputResamplingMode : int +{ + Default, + Bilinear, + BSpline, + MitchellNetravali, + CatmullRom, + SharpBilinear, + AreaSampling, +}; + enum class ColorCorrectionRegion : int { SMPTE_NTSCM, @@ -103,6 +114,7 @@ struct VideoConfig final bool bSSAA = false; int iEFBScale = 0; TextureFilteringMode texture_filtering_mode = TextureFilteringMode::Default; + OutputResamplingMode output_resampling_mode = OutputResamplingMode::Default; int iMaxAnisotropy = 0; std::string sPostProcessingShader; bool bForceTrueColor = false; |
