mirror of
				https://github.com/RetroDECK/Duckstation.git
				synced 2025-04-10 19:15:14 +00:00 
			
		
		
		
	GPU: Add downsample scale option
This commit is contained in:
		
							parent
							
								
									c0af478dfd
								
							
						
					
					
						commit
						585cf25ac4
					
				|  | @ -3907,6 +3907,17 @@ void FullscreenUI::DrawDisplaySettingsPage() | |||
|                   "GPU", "DownsampleMode", Settings::DEFAULT_GPU_DOWNSAMPLE_MODE, &Settings::ParseDownsampleModeName, | ||||
|                   &Settings::GetDownsampleModeName, &Settings::GetDownsampleModeDisplayName, GPUDownsampleMode::Count, | ||||
|                   (renderer != GPURenderer::Software)); | ||||
|   if (Settings::ParseDownsampleModeName( | ||||
|         GetEffectiveStringSetting(bsi, "GPU", "DownsampleMode", | ||||
|                                   Settings::GetDownsampleModeName(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE)) | ||||
|           .c_str()) | ||||
|         .value_or(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE) == GPUDownsampleMode::Box) | ||||
|   { | ||||
|     DrawIntRangeSetting(bsi, FSUI_CSTR("Downsampling Display Scale"), | ||||
|                         FSUI_CSTR("Selects the resolution scale that will be applied to the final image. 1x will " | ||||
|                                   "downsample to the original console resolution."), | ||||
|                         "GPU", "DownsampleScale", 1, 1, GPU::MAX_RESOLUTION_SCALE, "%dx"); | ||||
|   } | ||||
| 
 | ||||
|   DrawEnumSetting( | ||||
|     bsi, FSUI_CSTR("Scaling"), | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| #include "common/scoped_guard.h" | ||||
| #include "common/string_util.h" | ||||
| 
 | ||||
| #include "IconsFontAwesome5.h" | ||||
| #include "imgui.h" | ||||
| 
 | ||||
| #include <cmath> | ||||
|  | @ -50,6 +51,14 @@ ALWAYS_INLINE static u32 GetMaxResolutionScale() | |||
|   return g_gpu_device->GetMaxTextureSize() / VRAM_WIDTH; | ||||
| } | ||||
| 
 | ||||
| ALWAYS_INLINE_RELEASE static u32 GetBoxDownsampleScale() | ||||
| { | ||||
|   u32 scale = std::min<u32>(g_settings.gpu_resolution_scale, g_settings.gpu_downsample_scale); | ||||
|   while ((g_settings.gpu_resolution_scale % scale) != 0) | ||||
|     scale--; | ||||
|   return scale; | ||||
| } | ||||
| 
 | ||||
| ALWAYS_INLINE static bool ShouldUseUVLimits() | ||||
| { | ||||
|   // We only need UV limits if PGXP is enabled, or texture filtering is enabled.
 | ||||
|  | @ -166,38 +175,7 @@ bool GPU_HW::Initialize() | |||
|   m_wireframe_mode = g_settings.gpu_wireframe_mode; | ||||
|   m_disable_color_perspective = features.noperspective_interpolation && ShouldDisableColorPerspective(); | ||||
| 
 | ||||
|   if (m_multisamples != g_settings.gpu_multisamples) | ||||
|   { | ||||
|     Host::AddFormattedOSDMessage(Host::OSD_CRITICAL_ERROR_DURATION, | ||||
|                                  TRANSLATE("OSDMessage", "%ux MSAA is not supported, using %ux instead."), | ||||
|                                  g_settings.gpu_multisamples, m_multisamples); | ||||
|   } | ||||
|   if (!m_per_sample_shading && g_settings.gpu_per_sample_shading) | ||||
|   { | ||||
|     Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "SSAA is not supported, using MSAA instead."), 20.0f); | ||||
|   } | ||||
|   if (!features.dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering)) | ||||
|   { | ||||
|     Host::AddFormattedOSDMessage( | ||||
|       Host::OSD_CRITICAL_ERROR_DURATION, | ||||
|       TRANSLATE("OSDMessage", "Texture filter '%s' is not supported with the current renderer."), | ||||
|       Settings::GetTextureFilterDisplayName(m_texture_filtering)); | ||||
|     m_texture_filtering = GPUTextureFilter::Nearest; | ||||
|   } | ||||
| 
 | ||||
|   if (!features.noperspective_interpolation && !ShouldDisableColorPerspective()) | ||||
|     Log_WarningPrint("Disable color perspective not supported, but should be used."); | ||||
| 
 | ||||
|   if (!features.geometry_shaders && m_wireframe_mode != GPUWireframeMode::Disabled) | ||||
|   { | ||||
|     Host::AddOSDMessage( | ||||
|       TRANSLATE("OSDMessage", | ||||
|                 "Geometry shaders are not supported by your GPU, and are required for wireframe rendering."), | ||||
|       Host::OSD_CRITICAL_ERROR_DURATION); | ||||
|     m_wireframe_mode = GPUWireframeMode::Disabled; | ||||
|   } | ||||
| 
 | ||||
|   m_pgxp_depth_buffer = g_settings.UsingPGXPDepthBuffer(); | ||||
|   CheckSettings(); | ||||
| 
 | ||||
|   UpdateSoftwareRenderer(false); | ||||
| 
 | ||||
|  | @ -316,14 +294,18 @@ void GPU_HW::UpdateSettings(const Settings& old_settings) | |||
| 
 | ||||
|   // TODO: Use old_settings
 | ||||
|   const bool framebuffer_changed = | ||||
|     (m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode); | ||||
|     (m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode || | ||||
|      (m_downsample_mode == GPUDownsampleMode::Box && | ||||
|       g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale)); | ||||
|   const bool shaders_changed = | ||||
|     (m_resolution_scale != resolution_scale || m_multisamples != multisamples || | ||||
|      m_true_color != g_settings.gpu_true_color || m_per_sample_shading != per_sample_shading || | ||||
|      m_scaled_dithering != g_settings.gpu_scaled_dithering || m_texture_filtering != g_settings.gpu_texture_filter || | ||||
|      m_using_uv_limits != use_uv_limits || m_chroma_smoothing != g_settings.gpu_24bit_chroma_smoothing || | ||||
|      m_downsample_mode != downsample_mode || m_wireframe_mode != wireframe_mode || | ||||
|      m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer() || | ||||
|      m_downsample_mode != downsample_mode || | ||||
|      (m_downsample_mode == GPUDownsampleMode::Box && | ||||
|       g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale) || | ||||
|      m_wireframe_mode != wireframe_mode || m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer() || | ||||
|      m_disable_color_perspective != disable_color_perspective); | ||||
| 
 | ||||
|   if (m_resolution_scale != resolution_scale) | ||||
|  | @ -369,8 +351,7 @@ void GPU_HW::UpdateSettings(const Settings& old_settings) | |||
|   m_wireframe_mode = wireframe_mode; | ||||
|   m_disable_color_perspective = disable_color_perspective; | ||||
| 
 | ||||
|   if (!m_supports_dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering)) | ||||
|     m_texture_filtering = GPUTextureFilter::Nearest; | ||||
|   CheckSettings(); | ||||
| 
 | ||||
|   if (m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer()) | ||||
|   { | ||||
|  | @ -404,6 +385,72 @@ void GPU_HW::UpdateSettings(const Settings& old_settings) | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void GPU_HW::CheckSettings() | ||||
| { | ||||
|   const GPUDevice::Features features = g_gpu_device->GetFeatures(); | ||||
| 
 | ||||
|   if (m_multisamples != g_settings.gpu_multisamples) | ||||
|   { | ||||
|     Host::AddIconOSDMessage("MSAAUnsupported", ICON_FA_PAINT_BRUSH, | ||||
|                             fmt::format(TRANSLATE_FS("OSDMessage", "{}x MSAA is not supported, using {}x instead."), | ||||
|                                         g_settings.gpu_multisamples, m_multisamples), | ||||
|                             Host::OSD_CRITICAL_ERROR_DURATION); | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     Host::RemoveKeyedOSDMessage("MSAAUnsupported"); | ||||
|   } | ||||
| 
 | ||||
|   if (!m_per_sample_shading && g_settings.gpu_per_sample_shading) | ||||
|   { | ||||
|     Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "SSAA is not supported, using MSAA instead."), 20.0f); | ||||
|   } | ||||
|   if (!features.dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering)) | ||||
|   { | ||||
|     Host::AddFormattedOSDMessage( | ||||
|       Host::OSD_CRITICAL_ERROR_DURATION, | ||||
|       TRANSLATE("OSDMessage", "Texture filter '%s' is not supported with the current renderer."), | ||||
|       Settings::GetTextureFilterDisplayName(m_texture_filtering)); | ||||
|     m_texture_filtering = GPUTextureFilter::Nearest; | ||||
|   } | ||||
| 
 | ||||
|   if (!features.noperspective_interpolation && !ShouldDisableColorPerspective()) | ||||
|     Log_WarningPrint("Disable color perspective not supported, but should be used."); | ||||
| 
 | ||||
|   if (!features.geometry_shaders && m_wireframe_mode != GPUWireframeMode::Disabled) | ||||
|   { | ||||
|     Host::AddOSDMessage( | ||||
|       TRANSLATE("OSDMessage", | ||||
|                 "Geometry shaders are not supported by your GPU, and are required for wireframe rendering."), | ||||
|       Host::OSD_CRITICAL_ERROR_DURATION); | ||||
|     m_wireframe_mode = GPUWireframeMode::Disabled; | ||||
|   } | ||||
| 
 | ||||
|   if (m_downsample_mode == GPUDownsampleMode::Box) | ||||
|   { | ||||
|     const u32 scale = GetBoxDownsampleScale(); | ||||
|     if (scale != g_settings.gpu_downsample_scale || scale == g_settings.gpu_resolution_scale) | ||||
|     { | ||||
|       Host::AddIconOSDMessage( | ||||
|         "BoxDownsampleUnsupported", ICON_FA_PAINT_BRUSH, | ||||
|         fmt::format( | ||||
|           TRANSLATE_FS("OSDMessage", | ||||
|                        "Resolution scale {0}x is not divisible by downsample scale {1}x, using {2}x instead."), | ||||
|           g_settings.gpu_resolution_scale, g_settings.gpu_downsample_scale, scale), | ||||
|         Host::OSD_ERROR_DURATION); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       Host::RemoveKeyedOSDMessage("BoxDownsampleUnsupported"); | ||||
|     } | ||||
| 
 | ||||
|     if (scale == g_settings.gpu_resolution_scale) | ||||
|       m_downsample_mode = GPUDownsampleMode::Disabled; | ||||
|   } | ||||
| 
 | ||||
|   m_pgxp_depth_buffer = g_settings.UsingPGXPDepthBuffer(); | ||||
| } | ||||
| 
 | ||||
| u32 GPU_HW::CalculateResolutionScale() const | ||||
| { | ||||
|   const u32 max_resolution_scale = GetMaxResolutionScale(); | ||||
|  | @ -580,8 +627,10 @@ bool GPU_HW::CreateBuffers() | |||
|   } | ||||
|   else if (m_downsample_mode == GPUDownsampleMode::Box) | ||||
|   { | ||||
|     if (!(m_downsample_render_texture = g_gpu_device->CreateTexture(VRAM_WIDTH, VRAM_HEIGHT, 1, 1, 1, | ||||
|                                                                     GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) || | ||||
|     const u32 downsample_scale = GetBoxDownsampleScale(); | ||||
|     if (!(m_downsample_render_texture = | ||||
|             g_gpu_device->CreateTexture(VRAM_WIDTH * downsample_scale, VRAM_HEIGHT * downsample_scale, 1, 1, 1, | ||||
|                                         GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) || | ||||
|         !(m_downsample_framebuffer = g_gpu_device->CreateFramebuffer(m_downsample_render_texture.get()))) | ||||
|     { | ||||
|       return false; | ||||
|  | @ -1056,8 +1105,9 @@ bool GPU_HW::CompilePipelines() | |||
|   } | ||||
|   else if (m_downsample_mode == GPUDownsampleMode::Box) | ||||
|   { | ||||
|     std::unique_ptr<GPUShader> fs = | ||||
|       g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GenerateBoxSampleDownsampleFragmentShader()); | ||||
|     std::unique_ptr<GPUShader> fs = g_gpu_device->CreateShader( | ||||
|       GPUShaderStage::Fragment, | ||||
|       shadergen.GenerateBoxSampleDownsampleFragmentShader(m_resolution_scale / GetBoxDownsampleScale())); | ||||
|     if (!fs) | ||||
|       return false; | ||||
| 
 | ||||
|  | @ -2642,10 +2692,11 @@ void GPU_HW::DownsampleFramebufferAdaptive(GPUTexture* source, u32 left, u32 top | |||
| 
 | ||||
| void GPU_HW::DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 top, u32 width, u32 height) | ||||
| { | ||||
|   const u32 ds_left = left / m_resolution_scale; | ||||
|   const u32 ds_top = top / m_resolution_scale; | ||||
|   const u32 ds_width = width / m_resolution_scale; | ||||
|   const u32 ds_height = height / m_resolution_scale; | ||||
|   const u32 factor = m_resolution_scale / GetBoxDownsampleScale(); | ||||
|   const u32 ds_left = left / factor; | ||||
|   const u32 ds_top = top / factor; | ||||
|   const u32 ds_width = width / factor; | ||||
|   const u32 ds_height = height / factor; | ||||
| 
 | ||||
|   source->MakeReadyForSampling(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -347,4 +347,5 @@ private: | |||
|   } | ||||
| 
 | ||||
|   void PrintSettingsToLog(); | ||||
|   void CheckSettings(); | ||||
| }; | ||||
|  |  | |||
|  | @ -1558,24 +1558,26 @@ std::string GPU_HW_ShaderGen::GenerateAdaptiveDownsampleCompositeFragmentShader( | |||
|   return ss.str(); | ||||
| } | ||||
| 
 | ||||
| std::string GPU_HW_ShaderGen::GenerateBoxSampleDownsampleFragmentShader() | ||||
| std::string GPU_HW_ShaderGen::GenerateBoxSampleDownsampleFragmentShader(u32 factor) | ||||
| { | ||||
|   std::stringstream ss; | ||||
|   WriteHeader(ss); | ||||
|   WriteCommonFunctions(ss); | ||||
|   DeclareTexture(ss, "samp0", 0, false); | ||||
| 
 | ||||
|   ss << "#define FACTOR " << factor << "\n"; | ||||
| 
 | ||||
|   DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, false, false, false, false); | ||||
|   ss << R"( | ||||
| { | ||||
|   float3 color = float3(0.0, 0.0, 0.0); | ||||
|   uint2 base_coords = uint2(v_pos.xy) * uint2(RESOLUTION_SCALE, RESOLUTION_SCALE); | ||||
|   for (uint offset_x = 0u; offset_x < RESOLUTION_SCALE; offset_x++) | ||||
|   uint2 base_coords = uint2(v_pos.xy) * uint2(FACTOR, FACTOR); | ||||
|   for (uint offset_x = 0u; offset_x < FACTOR; offset_x++) | ||||
|   { | ||||
|     for (uint offset_y = 0u; offset_y < RESOLUTION_SCALE; offset_y++) | ||||
|     for (uint offset_y = 0u; offset_y < FACTOR; offset_y++) | ||||
|       color += LOAD_TEXTURE(samp0, int2(base_coords + uint2(offset_x, offset_y)), 0).rgb; | ||||
|   } | ||||
|   color /= float(RESOLUTION_SCALE * RESOLUTION_SCALE); | ||||
|   color /= float(FACTOR * FACTOR); | ||||
|   o_col0 = float4(color, 1.0); | ||||
| } | ||||
| )"; | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ public: | |||
|   std::string GenerateAdaptiveDownsampleMipFragmentShader(bool first_pass); | ||||
|   std::string GenerateAdaptiveDownsampleBlurFragmentShader(); | ||||
|   std::string GenerateAdaptiveDownsampleCompositeFragmentShader(); | ||||
|   std::string GenerateBoxSampleDownsampleFragmentShader(); | ||||
|   std::string GenerateBoxSampleDownsampleFragmentShader(u32 factor); | ||||
| 
 | ||||
| private: | ||||
|   ALWAYS_INLINE bool UsingMSAA() const { return m_multisamples > 1; } | ||||
|  |  | |||
|  | @ -225,6 +225,7 @@ void Settings::Load(SettingsInterface& si) | |||
|     ParseDownsampleModeName( | ||||
|       si.GetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(DEFAULT_GPU_DOWNSAMPLE_MODE)).c_str()) | ||||
|       .value_or(DEFAULT_GPU_DOWNSAMPLE_MODE); | ||||
|   gpu_downsample_scale = static_cast<u8>(si.GetUIntValue("GPU", "DownsampleScale", 1)); | ||||
|   gpu_wireframe_mode = | ||||
|     ParseGPUWireframeMode( | ||||
|       si.GetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(DEFAULT_GPU_WIREFRAME_MODE)).c_str()) | ||||
|  | @ -466,6 +467,7 @@ void Settings::Save(SettingsInterface& si) const | |||
|   si.SetBoolValue("GPU", "ScaledDithering", gpu_scaled_dithering); | ||||
|   si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter)); | ||||
|   si.SetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(gpu_downsample_mode)); | ||||
|   si.SetUIntValue("GPU", "DownsampleScale", gpu_downsample_scale); | ||||
|   si.SetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(gpu_wireframe_mode)); | ||||
|   si.SetBoolValue("GPU", "DisableInterlacing", gpu_disable_interlacing); | ||||
|   si.SetBoolValue("GPU", "ForceNTSCTimings", gpu_force_ntsc_timings); | ||||
|  |  | |||
|  | @ -106,6 +106,7 @@ struct Settings | |||
|   bool gpu_scaled_dithering = true; | ||||
|   GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER; | ||||
|   GPUDownsampleMode gpu_downsample_mode = DEFAULT_GPU_DOWNSAMPLE_MODE; | ||||
|   u8 gpu_downsample_scale = 1; | ||||
|   GPUWireframeMode gpu_wireframe_mode = DEFAULT_GPU_WIREFRAME_MODE; | ||||
|   bool gpu_disable_interlacing = true; | ||||
|   bool gpu_force_ntsc_timings = false; | ||||
|  |  | |||
|  | @ -3590,6 +3590,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings) | |||
|         g_settings.gpu_force_ntsc_timings != old_settings.gpu_force_ntsc_timings || | ||||
|         g_settings.gpu_24bit_chroma_smoothing != old_settings.gpu_24bit_chroma_smoothing || | ||||
|         g_settings.gpu_downsample_mode != old_settings.gpu_downsample_mode || | ||||
|         g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale || | ||||
|         g_settings.gpu_wireframe_mode != old_settings.gpu_wireframe_mode || | ||||
|         g_settings.display_crop_mode != old_settings.display_crop_mode || | ||||
|         g_settings.display_aspect_ratio != old_settings.display_aspect_ratio || | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi | |||
|   SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode", | ||||
|                                                &Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName, | ||||
|                                                Settings::DEFAULT_GPU_DOWNSAMPLE_MODE); | ||||
|   SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1); | ||||
|   SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false); | ||||
|   SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false); | ||||
|   SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true); | ||||
|  | @ -43,7 +44,10 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi | |||
| 
 | ||||
|   connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this, | ||||
|           &EnhancementSettingsWidget::updateScaledDitheringEnabled); | ||||
|   connect(m_ui.gpuDownsampleMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, | ||||
|           &EnhancementSettingsWidget::updateDownsampleScaleVisible); | ||||
|   connect(m_ui.trueColor, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updateScaledDitheringEnabled); | ||||
|   updateDownsampleScaleVisible(); | ||||
|   updateScaledDitheringEnabled(); | ||||
| 
 | ||||
|   connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled); | ||||
|  | @ -55,6 +59,9 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi | |||
|     m_ui.gpuDownsampleMode, tr("Downsampling"), tr("Disabled"), | ||||
|     tr("Downsamples the rendered image prior to displaying it. Can improve overall image quality in mixed 2D/3D games, " | ||||
|        "but should be disabled for pure 3D games. Only applies to the hardware renderers.")); | ||||
|   dialog->registerWidgetHelp(m_ui.gpuDownsampleScale, tr("Downsampling Display Scale"), tr("1x"), | ||||
|                              tr("Selects the resolution scale that will be applied to the final image. 1x will " | ||||
|                                 "downsample to the original console resolution.")); | ||||
|   dialog->registerWidgetHelp( | ||||
|     m_ui.disableInterlacing, tr("Disable Interlacing (force progressive render/scan)"), tr("Unchecked"), | ||||
|     tr( | ||||
|  | @ -141,6 +148,29 @@ void EnhancementSettingsWidget::updateScaledDitheringEnabled() | |||
|   m_ui.scaledDithering->setEnabled(allow_scaled_dithering); | ||||
| } | ||||
| 
 | ||||
| void EnhancementSettingsWidget::updateDownsampleScaleVisible() | ||||
| { | ||||
|   const GPUDownsampleMode mode = | ||||
|     Settings::ParseDownsampleModeName( | ||||
|       m_dialog | ||||
|         ->getEffectiveStringValue("GPU", "DownsampleMode", | ||||
|                                   Settings::GetDownsampleModeName(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE)) | ||||
|         .c_str()) | ||||
|       .value_or(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE); | ||||
| 
 | ||||
|   const bool visible = (mode == GPUDownsampleMode::Box); | ||||
|   if (visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) < 0) | ||||
|   { | ||||
|     m_ui.gpuDownsampleScale->setVisible(true); | ||||
|     m_ui.gpuDownsampleLayout->addWidget(m_ui.gpuDownsampleScale, 0); | ||||
|   } | ||||
|   else if (!visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) >= 0) | ||||
|   { | ||||
|     m_ui.gpuDownsampleScale->setVisible(false); | ||||
|     m_ui.gpuDownsampleLayout->removeWidget(m_ui.gpuDownsampleScale); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void EnhancementSettingsWidget::setupAdditionalUi() | ||||
| { | ||||
|   QtUtils::FillComboBoxWithResolutionScales(m_ui.resolutionScale); | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ public: | |||
| 
 | ||||
| private Q_SLOTS: | ||||
|   void updateScaledDitheringEnabled(); | ||||
|   void updateDownsampleScaleVisible(); | ||||
|   void updatePGXPSettingsEnabled(); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -88,7 +88,24 @@ | |||
|        </widget> | ||||
|       </item> | ||||
|       <item row="3" column="1"> | ||||
|        <widget class="QComboBox" name="gpuDownsampleMode"/> | ||||
|        <layout class="QHBoxLayout" name="gpuDownsampleLayout" stretch="1,0"> | ||||
|         <item> | ||||
|          <widget class="QComboBox" name="gpuDownsampleMode"/> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QSpinBox" name="gpuDownsampleScale"> | ||||
|           <property name="suffix"> | ||||
|            <string>x</string> | ||||
|           </property> | ||||
|           <property name="minimum"> | ||||
|            <number>1</number> | ||||
|           </property> | ||||
|           <property name="maximum"> | ||||
|            <number>16</number> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </widget> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Stenzek
						Stenzek