graphicssettingswidget.cpp (67771B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #include "graphicssettingswidget.h" 5 #include "qtutils.h" 6 #include "settingswindow.h" 7 #include "settingwidgetbinder.h" 8 9 #include "core/game_database.h" 10 #include "core/gpu.h" 11 #include "core/settings.h" 12 13 #include "util/media_capture.h" 14 15 #include <algorithm> 16 17 static QVariant GetMSAAModeValue(uint multisamples, bool ssaa) 18 { 19 const uint userdata = (multisamples & 0x7FFFFFFFu) | (static_cast<uint>(ssaa) << 31); 20 return QVariant(userdata); 21 } 22 23 static void DecodeMSAAModeValue(const QVariant& userdata, uint* multisamples, bool* ssaa) 24 { 25 bool ok; 26 const uint value = userdata.toUInt(&ok); 27 if (!ok || value == 0) 28 { 29 *multisamples = 1; 30 *ssaa = false; 31 return; 32 } 33 34 *multisamples = value & 0x7FFFFFFFu; 35 *ssaa = (value & (1u << 31)) != 0u; 36 } 37 38 GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* parent) 39 : QWidget(parent), m_dialog(dialog) 40 { 41 SettingsInterface* sif = dialog->getSettingsInterface(); 42 43 m_ui.setupUi(this); 44 setupAdditionalUi(); 45 removePlatformSpecificUi(); 46 47 // Rendering Tab 48 49 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.renderer, "GPU", "Renderer", &Settings::ParseRendererName, 50 &Settings::GetRendererName, Settings::DEFAULT_GPU_RENDERER); 51 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.textureFiltering, "GPU", "TextureFilter", 52 &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, 53 Settings::DEFAULT_GPU_TEXTURE_FILTER); 54 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.spriteTextureFiltering, "GPU", "SpriteTextureFilter", 55 &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, 56 Settings::DEFAULT_GPU_TEXTURE_FILTER); 57 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode", 58 &Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName, 59 Settings::DEFAULT_GPU_DOWNSAMPLE_MODE); 60 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayAspectRatio, "Display", "AspectRatio", 61 &Settings::ParseDisplayAspectRatio, &Settings::GetDisplayAspectRatioName, 62 Settings::DEFAULT_DISPLAY_ASPECT_RATIO); 63 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.customAspectRatioNumerator, "Display", 64 "CustomAspectRatioNumerator", 1); 65 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.customAspectRatioDenominator, "Display", 66 "CustomAspectRatioDenominator", 1); 67 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.widescreenHack, "GPU", "WidescreenHack", false); 68 SettingWidgetBinder::BindWidgetToEnumSetting( 69 sif, m_ui.displayDeinterlacing, "Display", "DeinterlacingMode", &Settings::ParseDisplayDeinterlacingMode, 70 &Settings::GetDisplayDeinterlacingModeName, Settings::DEFAULT_DISPLAY_DEINTERLACING_MODE); 71 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayCropMode, "Display", "CropMode", 72 &Settings::ParseDisplayCropMode, &Settings::GetDisplayCropModeName, 73 Settings::DEFAULT_DISPLAY_CROP_MODE); 74 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayScaling, "Display", "Scaling", 75 &Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName, 76 Settings::DEFAULT_DISPLAY_SCALING); 77 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1); 78 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false); 79 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true); 80 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpEnable, "GPU", "PGXPEnable", false); 81 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false); 82 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false); 83 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit", false); 84 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", false); 85 86 connect(m_ui.renderer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 87 &GraphicsSettingsWidget::updateRendererDependentOptions); 88 connect(m_ui.textureFiltering, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 89 &GraphicsSettingsWidget::updateResolutionDependentOptions); 90 connect(m_ui.displayAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 91 &GraphicsSettingsWidget::onAspectRatioChanged); 92 connect(m_ui.gpuDownsampleMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 93 &GraphicsSettingsWidget::onDownsampleModeChanged); 94 connect(m_ui.trueColor, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::onTrueColorChanged); 95 connect(m_ui.pgxpEnable, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::updatePGXPSettingsEnabled); 96 97 SettingWidgetBinder::SetAvailability(m_ui.renderer, 98 !m_dialog->hasGameTrait(GameDatabase::Trait::ForceSoftwareRenderer)); 99 SettingWidgetBinder::SetAvailability(m_ui.resolutionScale, 100 !m_dialog->hasGameTrait(GameDatabase::Trait::DisableUpscaling)); 101 SettingWidgetBinder::SetAvailability(m_ui.textureFiltering, 102 !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTextureFiltering)); 103 SettingWidgetBinder::SetAvailability(m_ui.trueColor, !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTrueColor)); 104 SettingWidgetBinder::SetAvailability(m_ui.pgxpEnable, !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXP)); 105 SettingWidgetBinder::SetAvailability(m_ui.disableInterlacing, 106 !m_dialog->hasGameTrait(GameDatabase::Trait::ForceInterlacing)); 107 SettingWidgetBinder::SetAvailability(m_ui.widescreenHack, 108 !m_dialog->hasGameTrait(GameDatabase::Trait::DisableWidescreen)); 109 SettingWidgetBinder::SetAvailability(m_ui.forceNTSCTimings, 110 !m_dialog->hasGameTrait(GameDatabase::Trait::DisableForceNTSCTimings)); 111 112 // Advanced Tab 113 114 SettingWidgetBinder::BindWidgetToEnumSetting( 115 sif, m_ui.exclusiveFullscreenControl, "Display", "ExclusiveFullscreenControl", 116 &Settings::ParseDisplayExclusiveFullscreenControl, &Settings::GetDisplayExclusiveFullscreenControlName, 117 Settings::DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL); 118 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayAlignment, "Display", "Alignment", 119 &Settings::ParseDisplayAlignment, &Settings::GetDisplayAlignmentName, 120 Settings::DEFAULT_DISPLAY_ALIGNMENT); 121 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayRotation, "Display", "Rotation", 122 &Settings::ParseDisplayRotation, &Settings::GetDisplayRotationName, 123 Settings::DEFAULT_DISPLAY_ROTATION); 124 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.gpuThread, "GPU", "UseThread", true); 125 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.threadedPresentation, "GPU", "ThreadedPresentation", 126 Settings::DEFAULT_THREADED_PRESENTATION); 127 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableMailboxPresentation, "Display", 128 "DisableMailboxPresentation", false); 129 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.stretchDisplayVertically, "Display", "StretchVertically", 130 false); 131 #ifdef _WIN32 132 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.blitSwapChain, "Display", "UseBlitSwapChain", false); 133 #endif 134 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuLineDetectMode, "GPU", "LineDetectMode", 135 &Settings::ParseLineDetectModeName, &Settings::GetLineDetectModeName, 136 Settings::DEFAULT_GPU_LINE_DETECT_MODE); 137 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuWireframeMode, "GPU", "WireframeMode", 138 Settings::ParseGPUWireframeMode, Settings::GetGPUWireframeModeName, 139 Settings::DEFAULT_GPU_WIREFRAME_MODE); 140 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.debanding, "GPU", "Debanding", false); 141 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false); 142 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU", 143 "UseSoftwareRendererForReadbacks", false); 144 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceRoundedTexcoords, "GPU", "ForceRoundTextureCoordinates", 145 false); 146 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.accurateBlending, "GPU", "AccurateBlending", false); 147 148 SettingWidgetBinder::SetAvailability(m_ui.scaledDithering, 149 !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledDithering)); 150 151 // PGXP Tab 152 153 SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.pgxpGeometryTolerance, "GPU", "PGXPTolerance", -1.0f); 154 SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.pgxpDepthClearThreshold, "GPU", "PGXPDepthClearThreshold", 155 Settings::DEFAULT_GPU_PGXP_DEPTH_THRESHOLD); 156 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpTextureCorrection, "GPU", "PGXPTextureCorrection", true); 157 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpColorCorrection, "GPU", "PGXPColorCorrection", false); 158 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCulling, "GPU", "PGXPCulling", true); 159 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", "PGXPPreserveProjFP", false); 160 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false); 161 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpVertexCache, "GPU", "PGXPVertexCache", false); 162 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDisableOn2DPolygons, "GPU", "PGXPDisableOn2DPolygons", 163 false); 164 165 connect(m_ui.pgxpTextureCorrection, &QCheckBox::checkStateChanged, this, 166 &GraphicsSettingsWidget::updatePGXPSettingsEnabled); 167 connect(m_ui.pgxpDepthBuffer, &QCheckBox::checkStateChanged, this, 168 &GraphicsSettingsWidget::updatePGXPSettingsEnabled); 169 170 SettingWidgetBinder::SetAvailability(m_ui.pgxpTextureCorrection, 171 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPTextureCorrection)); 172 SettingWidgetBinder::SetAvailability(m_ui.pgxpColorCorrection, 173 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPColorCorrection)); 174 SettingWidgetBinder::SetAvailability(m_ui.pgxpCulling, 175 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPCulling)); 176 SettingWidgetBinder::SetAvailability(m_ui.pgxpPreserveProjPrecision, 177 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPPreserveProjFP)); 178 179 // OSD Tab 180 181 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.osdScale, "Display", "OSDScale", 100); 182 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showOSDMessages, "Display", "ShowOSDMessages", true); 183 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showFPS, "Display", "ShowFPS", false); 184 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showSpeed, "Display", "ShowSpeed", false); 185 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showResolution, "Display", "ShowResolution", false); 186 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showCPU, "Display", "ShowCPU", false); 187 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showGPU, "Display", "ShowGPU", false); 188 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showInput, "Display", "ShowInputs", false); 189 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showGPUStatistics, "Display", "ShowGPUStatistics", false); 190 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showLatencyStatistics, "Display", "ShowLatencyStatistics", 191 false); 192 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showStatusIndicators, "Display", "ShowStatusIndicators", true); 193 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showFrameTimes, "Display", "ShowFrameTimes", false); 194 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showSettings, "Display", "ShowEnhancements", false); 195 196 // Capture Tab 197 198 SettingWidgetBinder::BindWidgetToEnumSetting( 199 sif, m_ui.screenshotSize, "Display", "ScreenshotMode", &Settings::ParseDisplayScreenshotMode, 200 &Settings::GetDisplayScreenshotModeName, Settings::DEFAULT_DISPLAY_SCREENSHOT_MODE); 201 SettingWidgetBinder::BindWidgetToEnumSetting( 202 sif, m_ui.screenshotFormat, "Display", "ScreenshotFormat", &Settings::ParseDisplayScreenshotFormat, 203 &Settings::GetDisplayScreenshotFormatName, Settings::DEFAULT_DISPLAY_SCREENSHOT_FORMAT); 204 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.screenshotQuality, "Display", "ScreenshotQuality", 205 Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY); 206 207 SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.mediaCaptureBackend, "MediaCapture", "Backend", 208 &MediaCapture::ParseBackendName, &MediaCapture::GetBackendName, 209 Settings::DEFAULT_MEDIA_CAPTURE_BACKEND); 210 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCapture, "MediaCapture", "VideoCapture", true); 211 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureWidth, "MediaCapture", "VideoWidth", 212 Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH); 213 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureHeight, "MediaCapture", "VideoHeight", 214 Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT); 215 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.videoCaptureResolutionAuto, "MediaCapture", "VideoAutoSize", 216 false); 217 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureBitrate, "MediaCapture", "VideoBitrate", 218 Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_BITRATE); 219 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCaptureArguments, "MediaCapture", 220 "VideoCodecUseArgs", false); 221 SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.videoCaptureArguments, "MediaCapture", "AudioCodecArgs"); 222 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableAudioCapture, "MediaCapture", "AudioCapture", true); 223 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.audioCaptureBitrate, "MediaCapture", "AudioBitrate", 224 Settings::DEFAULT_MEDIA_CAPTURE_AUDIO_BITRATE); 225 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCaptureArguments, "MediaCapture", 226 "VideoCodecUseArgs", false); 227 SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.audioCaptureArguments, "MediaCapture", "AudioCodecArgs"); 228 229 connect(m_ui.mediaCaptureBackend, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 230 &GraphicsSettingsWidget::onMediaCaptureBackendChanged); 231 connect(m_ui.enableVideoCapture, &QCheckBox::checkStateChanged, this, 232 &GraphicsSettingsWidget::onMediaCaptureVideoEnabledChanged); 233 connect(m_ui.videoCaptureResolutionAuto, &QCheckBox::checkStateChanged, this, 234 &GraphicsSettingsWidget::onMediaCaptureVideoAutoResolutionChanged); 235 connect(m_ui.enableAudioCapture, &QCheckBox::checkStateChanged, this, 236 &GraphicsSettingsWidget::onMediaCaptureAudioEnabledChanged); 237 238 // Texture Replacements Tab 239 240 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vramWriteReplacement, "TextureReplacements", 241 "EnableVRAMWriteReplacements", false); 242 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preloadTextureReplacements, "TextureReplacements", 243 "PreloadTextures", false); 244 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useOldMDECRoutines, "Hacks", "UseOldMDECRoutines", false); 245 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vramWriteDumping, "TextureReplacements", "DumpVRAMWrites", 246 false); 247 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.setVRAMWriteAlphaChannel, "TextureReplacements", 248 "DumpVRAMWriteForceAlphaChannel", true); 249 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.minDumpedVRAMWriteWidth, "TextureReplacements", 250 "DumpVRAMWriteWidthThreshold", 251 Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD); 252 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.minDumpedVRAMWriteHeight, "TextureReplacements", 253 "DumpVRAMWriteHeightThreshold", 254 Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD); 255 256 connect(m_ui.vramWriteReplacement, &QCheckBox::checkStateChanged, this, 257 &GraphicsSettingsWidget::onEnableAnyTextureReplacementsChanged); 258 connect(m_ui.vramWriteDumping, &QCheckBox::checkStateChanged, this, 259 &GraphicsSettingsWidget::onEnableVRAMWriteDumpingChanged); 260 261 // Debugging Tab 262 263 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useDebugDevice, "GPU", "UseDebugDevice", false); 264 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableShaderCache, "GPU", "DisableShaderCache", false); 265 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "GPU", "DisableDualSourceBlend", false); 266 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "GPU", "DisableFramebufferFetch", 267 false); 268 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableTextureBuffers, "GPU", "DisableTextureBuffers", false); 269 SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableTextureCopyToSelf, "GPU", "DisableTextureCopyToSelf", 270 false); 271 272 // Init all dependent options. 273 updateRendererDependentOptions(); 274 onAspectRatioChanged(); 275 onDownsampleModeChanged(); 276 updateResolutionDependentOptions(); 277 onMediaCaptureBackendChanged(); 278 onMediaCaptureAudioEnabledChanged(); 279 onMediaCaptureVideoEnabledChanged(); 280 onEnableAnyTextureReplacementsChanged(); 281 onEnableVRAMWriteDumpingChanged(); 282 onShowDebugSettingsChanged(QtHost::ShouldShowDebugOptions()); 283 284 // Rendering Tab 285 286 dialog->registerWidgetHelp( 287 m_ui.renderer, tr("Renderer"), QString::fromUtf8(Settings::GetRendererDisplayName(Settings::DEFAULT_GPU_RENDERER)), 288 tr("Chooses the backend to use for rendering the console/game visuals. <br>Depending on your system and hardware, " 289 "Direct3D 11 and OpenGL hardware backends may be available. <br>The software renderer offers the best " 290 "compatibility, but is the slowest and does not offer any enhancements.")); 291 dialog->registerWidgetHelp( 292 m_ui.adapter, tr("Adapter"), tr("(Default)"), 293 tr("If your system contains multiple GPUs or adapters, you can select which GPU you wish to use for the hardware " 294 "renderers. <br>This option is only supported in Direct3D and Vulkan. OpenGL will always use the default " 295 "device.")); 296 dialog->registerWidgetHelp( 297 m_ui.resolutionScale, tr("Internal Resolution"), "1x", 298 tr("Setting this beyond 1x will enhance the resolution of rendered 3D polygons and lines. Only applies " 299 "to the hardware backends. <br>This option is usually safe, with most games looking fine at " 300 "higher resolutions. Higher resolutions require a more powerful GPU.")); 301 dialog->registerWidgetHelp( 302 m_ui.gpuDownsampleMode, tr("Down-Sampling"), tr("Disabled"), 303 tr("Downsamples the rendered image prior to displaying it. Can improve overall image quality in mixed 2D/3D games, " 304 "but should be disabled for pure 3D games.")); 305 dialog->registerWidgetHelp(m_ui.gpuDownsampleScale, tr("Down-Sampling Display Scale"), tr("1x"), 306 tr("Selects the resolution scale that will be applied to the final image. 1x will " 307 "downsample to the original console resolution.")); 308 dialog->registerWidgetHelp( 309 m_ui.textureFiltering, tr("Texture Filtering"), 310 QString::fromUtf8(Settings::GetTextureFilterDisplayName(Settings::DEFAULT_GPU_TEXTURE_FILTER)), 311 tr("Smooths out the blockiness of magnified textures on 3D objects by using filtering. <br>Will have a " 312 "greater effect on higher resolution scales. <br>The JINC2 and especially xBR filtering modes are very " 313 "demanding, and may not be worth the speed penalty.")); 314 dialog->registerWidgetHelp( 315 m_ui.spriteTextureFiltering, tr("Sprite Texture Filtering"), 316 QString::fromUtf8(Settings::GetTextureFilterDisplayName(Settings::DEFAULT_GPU_TEXTURE_FILTER)), 317 tr("Smooths out the blockiness of magnified textures on 2D objects by using filtering. This filter only applies to " 318 "sprites and other 2D elements, such as the HUD.")); 319 dialog->registerWidgetHelp( 320 m_ui.displayAspectRatio, tr("Aspect Ratio"), 321 QString::fromUtf8(Settings::GetDisplayAspectRatioDisplayName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)), 322 tr("Changes the aspect ratio used to display the console's output to the screen. The default is Auto (Game Native) " 323 "which automatically adjusts the aspect ratio to match how a game would be shown on a typical TV of the era.")); 324 dialog->registerWidgetHelp( 325 m_ui.displayDeinterlacing, tr("Deinterlacing"), 326 QString::fromUtf8(Settings::GetDisplayDeinterlacingModeName(Settings::DEFAULT_DISPLAY_DEINTERLACING_MODE)), 327 tr("Determines which algorithm is used to convert interlaced frames to progressive for display on your system. " 328 "Generally, the \"Disable Interlacing\" enhancement provides better quality output, but some games require " 329 "interlaced rendering.")); 330 dialog->registerWidgetHelp( 331 m_ui.displayCropMode, tr("Crop"), 332 QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(Settings::DEFAULT_DISPLAY_CROP_MODE)), 333 tr("Determines how much of the area typically not visible on a consumer TV set to crop/hide. Some games display " 334 "content in the overscan area, or use it for screen effects. May not display correctly with the \"All Borders\" " 335 "setting. \"Only Overscan\" offers a good compromise between stability and hiding black borders.")); 336 dialog->registerWidgetHelp( 337 m_ui.displayScaling, tr("Scaling"), tr("Bilinear (Smooth)"), 338 tr("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution.")); 339 dialog->registerWidgetHelp( 340 m_ui.trueColor, tr("True Color Rendering"), tr("Checked"), 341 tr("Forces the precision of colours output to the console's framebuffer to use the full 8 bits of precision per " 342 "channel. This produces nicer looking gradients at the cost of making some colours look slightly different. " 343 "Disabling the option also enables dithering, which makes the transition between colours less sharp by applying " 344 "a pattern around those pixels. Most games are compatible with this option, but there is a number which aren't " 345 "and will have broken effects with it enabled.")); 346 dialog->registerWidgetHelp( 347 m_ui.widescreenHack, tr("Widescreen Rendering"), tr("Unchecked"), 348 tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially " 349 "increasing the field of view from 4:3 to the chosen display aspect ratio in 3D games. <b><u>May not be " 350 "compatible with all games.</u></b>")); 351 dialog->registerWidgetHelp(m_ui.pgxpEnable, tr("PGXP Geometry Correction"), tr("Unchecked"), 352 tr("Reduces \"wobbly\" polygons and \"warping\" textures that are common in PS1 games. " 353 "<strong>May not be compatible with all games.</strong>")); 354 dialog->registerWidgetHelp( 355 m_ui.pgxpDepthBuffer, tr("PGXP Depth Buffer"), tr("Unchecked"), 356 tr("Attempts to reduce polygon Z-fighting by testing pixels against the depth values from PGXP. Low compatibility, " 357 "but can work well in some games. Other games may need a threshold adjustment.")); 358 dialog->registerWidgetHelp( 359 m_ui.force43For24Bit, tr("Force 4:3 For FMVs"), tr("Unchecked"), 360 tr("Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs.")); 361 dialog->registerWidgetHelp(m_ui.chromaSmoothingFor24Bit, tr("FMV Chroma Smoothing"), tr("Unchecked"), 362 tr("Smooths out blockyness between colour transitions in 24-bit content, usually FMVs.")); 363 dialog->registerWidgetHelp( 364 m_ui.disableInterlacing, tr("Disable Interlacing"), tr("Checked"), 365 tr( 366 "Forces the rendering and display of frames to progressive mode. <br>This removes the \"combing\" effect seen in " 367 "480i games by rendering them in 480p. Usually safe to enable.<br><b><u>May not be compatible with all " 368 "games.</u></b>")); 369 dialog->registerWidgetHelp( 370 m_ui.forceNTSCTimings, tr("Force NTSC Timings"), tr("Unchecked"), 371 tr("Uses NTSC frame timings when the console is in PAL mode, forcing PAL games to run at 60hz. <br>For most games " 372 "which have a speed tied to the framerate, this will result in the game running approximately 17% faster. " 373 "<br>For variable frame rate games, it may not affect the speed.")); 374 375 // Advanced Tab 376 377 dialog->registerWidgetHelp(m_ui.fullscreenMode, tr("Fullscreen Mode"), tr("Borderless Fullscreen"), 378 tr("Chooses the fullscreen resolution and frequency.")); 379 dialog->registerWidgetHelp(m_ui.exclusiveFullscreenControl, tr("Exclusive Fullscreen Control"), tr("Automatic"), 380 tr("Controls whether exclusive fullscreen can be utilized by Vulkan drivers.")); 381 dialog->registerWidgetHelp( 382 m_ui.displayAlignment, tr("Position"), 383 QString::fromUtf8(Settings::GetDisplayAlignmentDisplayName(Settings::DEFAULT_DISPLAY_ALIGNMENT)), 384 tr("Determines the position on the screen when black borders must be added.")); 385 dialog->registerWidgetHelp(m_ui.gpuThread, tr("Threaded Rendering"), tr("Checked"), 386 tr("Uses a second thread for drawing graphics. Currently only available for the software " 387 "renderer, but can provide a significant speed improvement, and is safe to use.")); 388 dialog->registerWidgetHelp(m_ui.threadedPresentation, tr("Threaded Presentation"), tr("Checked"), 389 tr("Presents frames on a background thread when fast forwarding or vsync is disabled. " 390 "This can measurably improve performance in the Vulkan renderer.")); 391 dialog->registerWidgetHelp( 392 m_ui.disableMailboxPresentation, tr("Disable Mailbox Presentation"), tr("Unchecked"), 393 tr("Forces the use of FIFO over Mailbox presentation, i.e. double buffering instead of triple buffering. " 394 "Usually results in worse frame pacing.")); 395 dialog->registerWidgetHelp( 396 m_ui.stretchDisplayVertically, tr("Stretch Vertically"), tr("Unchecked"), 397 tr("Prefers stretching the display vertically instead of horizontally, when applying the display aspect ratio.")); 398 #ifdef _WIN32 399 dialog->registerWidgetHelp(m_ui.blitSwapChain, tr("Use Blit Swap Chain"), tr("Unchecked"), 400 tr("Uses a blit presentation model instead of flipping when using the Direct3D 11 " 401 "renderer. This usually results in slower performance, but may be required for some " 402 "streaming applications, or to uncap framerates on some systems.")); 403 #endif 404 405 dialog->registerWidgetHelp(m_ui.gpuLineDetectMode, tr("Line Detection"), 406 QString::fromUtf8(Settings::GetLineDetectModeName(Settings::DEFAULT_GPU_LINE_DETECT_MODE)), 407 tr("Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization " 408 "behavior, filling in gaps introduced by upscaling.")); 409 dialog->registerWidgetHelp( 410 m_ui.msaaMode, tr("Multi-Sampling"), tr("Disabled"), 411 tr("Uses multi-sampled anti-aliasing when rendering 3D polygons. Can improve visuals with a lower performance " 412 "requirement compared to upscaling, <strong>but often introduces rendering errors.</strong>")); 413 dialog->registerWidgetHelp( 414 m_ui.debanding, tr("True Color Debanding"), tr("Unchecked"), 415 tr("Applies modern dithering techniques to further smooth out gradients when true color is enabled. " 416 "This debanding is performed during rendering (as opposed to a post-processing step), which allows it to be " 417 "fast while preserving detail. " 418 "Debanding increases the file size of screenshots due to the subtle dithering pattern present in screenshots.")); 419 dialog->registerWidgetHelp( 420 m_ui.scaledDithering, tr("Scaled Dithering"), tr("Checked"), 421 tr("Scales the dither pattern to the resolution scale of the emulated GPU. This makes the dither pattern much less " 422 "obvious at higher resolutions. Usually safe to enable.")); 423 dialog->registerWidgetHelp( 424 m_ui.useSoftwareRendererForReadbacks, tr("Software Renderer Readbacks"), tr("Unchecked"), 425 tr("Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater " 426 "performance when using graphical enhancements with the hardware renderer.")); 427 dialog->registerWidgetHelp( 428 m_ui.forceRoundedTexcoords, tr("Round Upscaled Texture Coordinates"), tr("Unchecked"), 429 tr("Rounds texture coordinates instead of flooring when upscaling. Can fix misaligned textures in some games, but " 430 "break others, and is incompatible with texture filtering.")); 431 dialog->registerWidgetHelp( 432 m_ui.accurateBlending, tr("Accurate Blending"), tr("Unchecked"), 433 tr("Forces blending to be done in the shader at 16-bit precision, when not using true color. Very few games " 434 "actually require this, and there is a <strong>non-trivial</strong> performance cost.")); 435 436 // PGXP Tab 437 438 dialog->registerWidgetHelp( 439 m_ui.pgxpGeometryTolerance, tr("Geometry Tolerance"), tr("-1.00px (Disabled)"), 440 tr("Discards precise geometry when it is found to be offset past the specified threshold. This can help with games " 441 "that have vertices significantly moved by PGXP, but is still a hack/workaround.")); 442 dialog->registerWidgetHelp(m_ui.pgxpDepthClearThreshold, tr("Depth Clear Threshold"), 443 QStringLiteral("%1").arg(Settings::DEFAULT_GPU_PGXP_DEPTH_THRESHOLD), 444 tr("Determines the increase in depth that will result in the depth buffer being cleared. " 445 "Can help with depth issues in some games, but is still a hack/workaround.")); 446 dialog->registerWidgetHelp(m_ui.pgxpTextureCorrection, tr("Perspective Correct Textures"), tr("Checked"), 447 tr("Uses perspective-correct interpolation for texture coordinates, straightening out " 448 "warped textures. Requires geometry correction enabled.")); 449 dialog->registerWidgetHelp( 450 m_ui.pgxpColorCorrection, tr("Perspective Correct Colors"), tr("Unchecked"), 451 tr("Uses perspective-correct interpolation for vertex colors, which can improve visuals in some games, but cause " 452 "rendering errors in others. Requires geometry correction enabled.")); 453 dialog->registerWidgetHelp(m_ui.pgxpCulling, tr("Culling Correction"), tr("Checked"), 454 tr("Increases the precision of polygon culling, reducing the number of holes in geometry. " 455 "Requires geometry correction enabled.")); 456 dialog->registerWidgetHelp( 457 m_ui.pgxpPreserveProjPrecision, tr("Preserve Projection Precision"), tr("Unchecked"), 458 tr("Adds additional precision to PGXP data post-projection. May improve visuals in some games.")); 459 dialog->registerWidgetHelp(m_ui.pgxpCPU, tr("CPU Mode"), tr("Unchecked"), 460 tr("Uses PGXP for all instructions, not just memory operations. Required for PGXP to " 461 "correct wobble in some games, but has a high performance cost.")); 462 dialog->registerWidgetHelp( 463 m_ui.pgxpVertexCache, tr("Vertex Cache"), tr("Unchecked"), 464 tr("Uses screen-space vertex positions to obtain precise positions, instead of tracking memory accesses. Can " 465 "provide PGXP compatibility for some games, but <strong>generally provides no benefit.</strong>")); 466 dialog->registerWidgetHelp(m_ui.pgxpDisableOn2DPolygons, tr("Disable on 2D Polygons"), tr("Unchecked"), 467 tr("Uses native resolution coordinates for 2D polygons, instead of precise coordinates. " 468 "Can fix misaligned UI in some games, but otherwise should be left disabled. The game " 469 "database will enable this automatically when needed.")); 470 471 // OSD Tab 472 473 dialog->registerWidgetHelp( 474 m_ui.osdScale, tr("OSD Scale"), tr("100%"), 475 tr("Changes the size at which on-screen elements, including status and messages are displayed.")); 476 dialog->registerWidgetHelp(m_ui.showOSDMessages, tr("Show OSD Messages"), tr("Checked"), 477 tr("Shows on-screen-display messages when events occur such as save states being " 478 "created/loaded, screenshots being taken, etc.")); 479 dialog->registerWidgetHelp(m_ui.showResolution, tr("Show Resolution"), tr("Unchecked"), 480 tr("Shows the resolution of the game in the top-right corner of the display.")); 481 dialog->registerWidgetHelp( 482 m_ui.showSpeed, tr("Show Emulation Speed"), tr("Unchecked"), 483 tr("Shows the current emulation speed of the system in the top-right corner of the display as a percentage.")); 484 dialog->registerWidgetHelp(m_ui.showFPS, tr("Show FPS"), tr("Unchecked"), 485 tr("Shows the internal frame rate of the game in the top-right corner of the display.")); 486 dialog->registerWidgetHelp( 487 m_ui.showCPU, tr("Show CPU Usage"), tr("Unchecked"), 488 tr("Shows the host's CPU usage based on threads in the top-right corner of the display. This does not display the " 489 "emulated system CPU's usage. If a value close to 100% is being displayed, this means your host's CPU is likely " 490 "the bottleneck. In this case, you should reduce enhancement-related settings such as overclocking.")); 491 dialog->registerWidgetHelp(m_ui.showGPU, tr("Show GPU Usage"), tr("Unchecked"), 492 tr("Shows the host's GPU usage in the top-right corner of the display.")); 493 dialog->registerWidgetHelp(m_ui.showGPUStatistics, tr("Show GPU Statistics"), tr("Unchecked"), 494 tr("Shows information about the emulated GPU in the top-right corner of the display.")); 495 dialog->registerWidgetHelp( 496 m_ui.showLatencyStatistics, tr("Show Latency Statistics"), tr("Unchecked"), 497 tr("Shows information about input and audio latency in the top-right corner of the display.")); 498 dialog->registerWidgetHelp( 499 m_ui.showFrameTimes, tr("Show Frame Times"), tr("Unchecked"), 500 tr("Shows the history of frame rendering times as a graph in the top-right corner of the display.")); 501 dialog->registerWidgetHelp( 502 m_ui.showInput, tr("Show Controller Input"), tr("Unchecked"), 503 tr("Shows the current controller state of the system in the bottom-left corner of the display.")); 504 dialog->registerWidgetHelp(m_ui.showSettings, tr("Show Settings"), tr("Unchecked"), 505 tr("Shows a summary of current settings in the bottom-right corner of the display.")); 506 dialog->registerWidgetHelp(m_ui.showStatusIndicators, tr("Show Status Indicators"), tr("Checked"), 507 tr("Shows indicators on screen when the system is not running in its \"normal\" state. " 508 "For example, fast forwarding, or being paused.")); 509 510 // Capture Tab 511 512 dialog->registerWidgetHelp(m_ui.screenshotSize, tr("Screenshot Size"), tr("Screen Resolution"), 513 tr("Determines the resolution at which screenshots will be saved. Internal resolutions " 514 "preserve more detail at the cost of file size.")); 515 dialog->registerWidgetHelp( 516 m_ui.screenshotFormat, tr("Screenshot Format"), tr("PNG"), 517 tr("Selects the format which will be used to save screenshots. JPEG produces smaller files, but loses detail.")); 518 dialog->registerWidgetHelp(m_ui.screenshotQuality, tr("Screenshot Quality"), 519 QStringLiteral("%1%").arg(Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY), 520 tr("Selects the quality at which screenshots will be compressed. Higher values preserve " 521 "more detail for JPEG, and reduce file size for PNG.")); 522 dialog->registerWidgetHelp( 523 m_ui.mediaCaptureBackend, tr("Backend"), 524 QString::fromUtf8(MediaCapture::GetBackendDisplayName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND)), 525 tr("Selects the framework that is used to encode video/audio.")); 526 dialog->registerWidgetHelp(m_ui.captureContainer, tr("Container"), tr("MP4"), 527 tr("Determines the file format used to contain the captured audio/video")); 528 dialog->registerWidgetHelp( 529 m_ui.videoCaptureCodec, tr("Video Codec"), tr("Default"), 530 tr("Selects which Video Codec to be used for Video Capture. <b>If unsure, leave it on default.<b>")); 531 dialog->registerWidgetHelp(m_ui.videoCaptureBitrate, tr("Video Bitrate"), tr("6000 kbps"), 532 tr("Sets the video bitrate to be used. Larger bitrate generally yields better video " 533 "quality at the cost of larger resulting file size.")); 534 dialog->registerWidgetHelp( 535 m_ui.videoCaptureResolutionAuto, tr("Automatic Resolution"), tr("Unchecked"), 536 tr("When checked, the video capture resolution will follows the internal resolution of the running " 537 "game. <b>Be careful when using this setting especially when you are upscaling, as higher internal " 538 "resolutions (above 4x) can cause system slowdown.</b>")); 539 dialog->registerWidgetHelp(m_ui.enableVideoCaptureArguments, tr("Enable Extra Video Arguments"), tr("Unchecked"), 540 tr("Allows you to pass arguments to the selected video codec.")); 541 dialog->registerWidgetHelp( 542 m_ui.videoCaptureArguments, tr("Extra Video Arguments"), tr("Empty"), 543 tr("Parameters passed to the selected video codec.<br><b>You must use '=' to separate key from value and ':' to " 544 "separate two pairs from each other.</b><br>For example: \"crf = 21 : preset = veryfast\"")); 545 dialog->registerWidgetHelp( 546 m_ui.audioCaptureCodec, tr("Audio Codec"), tr("Default"), 547 tr("Selects which Audio Codec to be used for Video Capture. <b>If unsure, leave it on default.<b>")); 548 dialog->registerWidgetHelp(m_ui.audioCaptureBitrate, tr("Audio Bitrate"), tr("160 kbps"), 549 tr("Sets the audio bitrate to be used.")); 550 dialog->registerWidgetHelp(m_ui.enableAudioCaptureArguments, tr("Enable Extra Audio Arguments"), tr("Unchecked"), 551 tr("Allows you to pass arguments to the selected audio codec.")); 552 dialog->registerWidgetHelp( 553 m_ui.audioCaptureArguments, tr("Extra Audio Arguments"), tr("Empty"), 554 tr("Parameters passed to the selected audio codec.<br><b>You must use '=' to separate key from value and ':' to " 555 "separate two pairs from each other.</b><br>For example: \"compression_level = 4 : joint_stereo = 1\"")); 556 557 // Texture Replacements Tab 558 559 dialog->registerWidgetHelp(m_ui.vramWriteReplacement, tr("Enable VRAM Write Replacement"), tr("Unchecked"), 560 tr("Enables the replacement of background textures in supported games. <strong>This is " 561 "not general texture replacement.</strong>")); 562 dialog->registerWidgetHelp(m_ui.preloadTextureReplacements, tr("Preload Texture Replacements"), tr("Unchecked"), 563 tr("Loads all replacement texture to RAM, reducing stuttering at runtime.")); 564 dialog->registerWidgetHelp(m_ui.useOldMDECRoutines, tr("Use Old MDEC Routines"), tr("Unchecked"), 565 tr("Enables the older, less accurate MDEC decoding routines. May be required for old " 566 "replacement backgrounds to match/load.")); 567 dialog->registerWidgetHelp(m_ui.setVRAMWriteAlphaChannel, tr("Set Alpha Channel"), tr("Checked"), 568 tr("Clears the mask/transparency bit in VRAM write dumps.")); 569 dialog->registerWidgetHelp(m_ui.vramWriteDumping, tr("Enable VRAM Write Dumping"), tr("Unchecked"), 570 tr("Writes backgrounds that can be replaced to the dump directory.")); 571 dialog->registerWidgetHelp(m_ui.minDumpedVRAMWriteWidth, tr("Dump Size Threshold"), tr("128px"), 572 tr("Determines the threshold that triggers a VRAM write to be dumped.")); 573 dialog->registerWidgetHelp(m_ui.minDumpedVRAMWriteHeight, tr("Dump Size Threshold"), tr("128px"), 574 tr("Determines the threshold that triggers a VRAM write to be dumped.")); 575 576 // Debugging Tab 577 578 dialog->registerWidgetHelp(m_ui.gpuWireframeMode, tr("Wireframe Mode"), tr("Disabled"), 579 tr("Draws a wireframe outline of the triangles rendered by the console's GPU, either as a " 580 "replacement or an overlay.")); 581 582 dialog->registerWidgetHelp( 583 m_ui.useDebugDevice, tr("Use Debug Device"), tr("Unchecked"), 584 tr("Enable debugging when supported by the host's renderer API. <strong>Only for developer use.</strong>")); 585 dialog->registerWidgetHelp( 586 m_ui.disableShaderCache, tr("Disable Shader Cache"), tr("Unchecked"), 587 tr("Forces shaders to be compiled for every run of the program. <strong>Only for developer use.</strong>")); 588 dialog->registerWidgetHelp(m_ui.disableDualSource, tr("Disable Dual-Source Blending"), tr("Unchecked"), 589 tr("Prevents dual-source blending from being used. Useful for testing broken graphics " 590 "drivers. <strong>Only for developer use.</strong>")); 591 dialog->registerWidgetHelp(m_ui.disableFramebufferFetch, tr("Disable Framebuffer Fetch"), tr("Unchecked"), 592 tr("Prevents the framebuffer fetch extensions from being used. Useful for testing broken " 593 "graphics drivers. <strong>Only for developer use.</strong>")); 594 dialog->registerWidgetHelp( 595 m_ui.disableTextureBuffers, tr("Disable Texture Buffers"), tr("Unchecked"), 596 tr("Forces VRAM updates through texture updates, instead of texture buffers and draws. Useful for testing broken " 597 "graphics drivers. <strong>Only for developer use.</strong>")); 598 dialog->registerWidgetHelp(m_ui.disableTextureCopyToSelf, tr("Disable Texture Copies To Self"), tr("Unchecked"), 599 tr("Disables the use of self-copy updates for the VRAM texture. Useful for testing broken " 600 "graphics drivers. <strong>Only for developer use.</strong>")); 601 dialog->registerWidgetHelp(m_ui.disableMemoryImport, tr("Disable Memory Import"), tr("Unchecked"), 602 tr("Disables the use of host memory importing. Useful for testing broken graphics " 603 "drivers. <strong>Only for developer use.</strong>")); 604 dialog->registerWidgetHelp(m_ui.disableRasterOrderViews, tr("Disable Rasterizer Order Views"), tr("Unchecked"), 605 tr("Disables the use of rasterizer order views. Useful for testing broken graphics " 606 "drivers. <strong>Only for developer use.</strong>")); 607 } 608 609 GraphicsSettingsWidget::~GraphicsSettingsWidget() = default; 610 611 void GraphicsSettingsWidget::setupAdditionalUi() 612 { 613 // Rendering Tab 614 615 for (u32 i = 0; i < static_cast<u32>(GPURenderer::Count); i++) 616 { 617 m_ui.renderer->addItem(QString::fromUtf8(Settings::GetRendererDisplayName(static_cast<GPURenderer>(i)))); 618 } 619 620 for (u32 i = 0; i < static_cast<u32>(GPUTextureFilter::Count); i++) 621 { 622 m_ui.textureFiltering->addItem( 623 QString::fromUtf8(Settings::GetTextureFilterDisplayName(static_cast<GPUTextureFilter>(i)))); 624 m_ui.spriteTextureFiltering->addItem( 625 QString::fromUtf8(Settings::GetTextureFilterDisplayName(static_cast<GPUTextureFilter>(i)))); 626 } 627 628 for (u32 i = 0; i < static_cast<u32>(GPUDownsampleMode::Count); i++) 629 { 630 m_ui.gpuDownsampleMode->addItem( 631 QString::fromUtf8(Settings::GetDownsampleModeDisplayName(static_cast<GPUDownsampleMode>(i)))); 632 } 633 634 for (u32 i = 0; i < static_cast<u32>(DisplayAspectRatio::Count); i++) 635 { 636 m_ui.displayAspectRatio->addItem( 637 QString::fromUtf8(Settings::GetDisplayAspectRatioDisplayName(static_cast<DisplayAspectRatio>(i)))); 638 } 639 640 for (u32 i = 0; i < static_cast<u32>(DisplayDeinterlacingMode::Count); i++) 641 { 642 m_ui.displayDeinterlacing->addItem( 643 QString::fromUtf8(Settings::GetDisplayDeinterlacingModeDisplayName(static_cast<DisplayDeinterlacingMode>(i)))); 644 } 645 646 for (u32 i = 0; i < static_cast<u32>(DisplayCropMode::Count); i++) 647 { 648 m_ui.displayCropMode->addItem( 649 QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i)))); 650 } 651 652 for (u32 i = 0; i < static_cast<u32>(DisplayScalingMode::Count); i++) 653 { 654 m_ui.displayScaling->addItem( 655 QString::fromUtf8(Settings::GetDisplayScalingDisplayName(static_cast<DisplayScalingMode>(i)))); 656 } 657 658 // Advanced Tab 659 660 for (u32 i = 0; i < static_cast<u32>(DisplayExclusiveFullscreenControl::Count); i++) 661 { 662 m_ui.exclusiveFullscreenControl->addItem(QString::fromUtf8( 663 Settings::GetDisplayExclusiveFullscreenControlDisplayName(static_cast<DisplayExclusiveFullscreenControl>(i)))); 664 } 665 666 for (u32 i = 0; i < static_cast<u32>(DisplayAlignment::Count); i++) 667 { 668 m_ui.displayAlignment->addItem( 669 QString::fromUtf8(Settings::GetDisplayAlignmentDisplayName(static_cast<DisplayAlignment>(i)))); 670 } 671 672 for (u32 i = 0; i < static_cast<u32>(DisplayRotation::Count); i++) 673 { 674 m_ui.displayRotation->addItem( 675 QString::fromUtf8(Settings::GetDisplayRotationDisplayName(static_cast<DisplayRotation>(i)))); 676 } 677 678 for (u32 i = 0; i < static_cast<u32>(GPULineDetectMode::Count); i++) 679 { 680 m_ui.gpuLineDetectMode->addItem( 681 QString::fromUtf8(Settings::GetLineDetectModeDisplayName(static_cast<GPULineDetectMode>(i)))); 682 } 683 684 // Capture Tab 685 686 for (u32 i = 0; i < static_cast<u32>(DisplayScreenshotMode::Count); i++) 687 { 688 m_ui.screenshotSize->addItem( 689 QString::fromUtf8(Settings::GetDisplayScreenshotModeDisplayName(static_cast<DisplayScreenshotMode>(i)))); 690 } 691 692 for (u32 i = 0; i < static_cast<u32>(DisplayScreenshotFormat::Count); i++) 693 { 694 m_ui.screenshotFormat->addItem( 695 QString::fromUtf8(Settings::GetDisplayScreenshotFormatDisplayName(static_cast<DisplayScreenshotFormat>(i)))); 696 } 697 698 for (u32 i = 0; i < static_cast<u32>(MediaCaptureBackend::MaxCount); i++) 699 { 700 m_ui.mediaCaptureBackend->addItem( 701 QString::fromUtf8(MediaCapture::GetBackendDisplayName(static_cast<MediaCaptureBackend>(i)))); 702 } 703 704 // Debugging Tab 705 706 for (u32 i = 0; i < static_cast<u32>(GPUWireframeMode::Count); i++) 707 { 708 m_ui.gpuWireframeMode->addItem( 709 QString::fromUtf8(Settings::GetGPUWireframeModeDisplayName(static_cast<GPUWireframeMode>(i)))); 710 } 711 } 712 713 void GraphicsSettingsWidget::removePlatformSpecificUi() 714 { 715 #ifndef _WIN32 716 m_ui.advancedDisplayOptionsLayout->removeWidget(m_ui.blitSwapChain); 717 delete m_ui.blitSwapChain; 718 m_ui.blitSwapChain = nullptr; 719 #endif 720 } 721 722 GPURenderer GraphicsSettingsWidget::getEffectiveRenderer() const 723 { 724 return Settings::ParseRendererName( 725 m_dialog 726 ->getEffectiveStringValue("GPU", "Renderer", Settings::GetRendererName(Settings::DEFAULT_GPU_RENDERER)) 727 .c_str()) 728 .value_or(Settings::DEFAULT_GPU_RENDERER); 729 } 730 731 bool GraphicsSettingsWidget::effectiveRendererIsHardware() const 732 { 733 return (getEffectiveRenderer() != GPURenderer::Software); 734 } 735 736 void GraphicsSettingsWidget::onShowDebugSettingsChanged(bool enabled) 737 { 738 m_ui.tabs->setTabVisible(TAB_INDEX_DEBUGGING, enabled); 739 } 740 741 void GraphicsSettingsWidget::updateRendererDependentOptions() 742 { 743 const GPURenderer renderer = getEffectiveRenderer(); 744 const RenderAPI render_api = Settings::GetRenderAPIForRenderer(renderer); 745 const bool is_hardware = (renderer != GPURenderer::Software); 746 747 m_ui.resolutionScale->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableUpscaling)); 748 m_ui.resolutionScaleLabel->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableUpscaling)); 749 m_ui.msaaMode->setEnabled(is_hardware); 750 m_ui.msaaModeLabel->setEnabled(is_hardware); 751 m_ui.textureFiltering->setEnabled(is_hardware && 752 !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTextureFiltering)); 753 m_ui.textureFilteringLabel->setEnabled(is_hardware && 754 !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTextureFiltering)); 755 m_ui.gpuDownsampleLabel->setEnabled(is_hardware); 756 m_ui.gpuDownsampleMode->setEnabled(is_hardware); 757 m_ui.gpuDownsampleScale->setEnabled(is_hardware); 758 m_ui.trueColor->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTrueColor)); 759 m_ui.pgxpEnable->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXP)); 760 761 m_ui.gpuLineDetectMode->setEnabled(is_hardware); 762 m_ui.gpuLineDetectModeLabel->setEnabled(is_hardware); 763 m_ui.gpuWireframeMode->setEnabled(is_hardware); 764 m_ui.gpuWireframeModeLabel->setEnabled(is_hardware); 765 m_ui.debanding->setEnabled(is_hardware); 766 m_ui.scaledDithering->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledDithering)); 767 m_ui.useSoftwareRendererForReadbacks->setEnabled(is_hardware); 768 m_ui.forceRoundedTexcoords->setEnabled(is_hardware); 769 m_ui.accurateBlending->setEnabled(is_hardware); 770 771 m_ui.tabs->setTabEnabled(TAB_INDEX_TEXTURE_REPLACEMENTS, is_hardware); 772 773 #ifdef _WIN32 774 m_ui.blitSwapChain->setEnabled(render_api == RenderAPI::D3D11); 775 #endif 776 777 m_ui.gpuThread->setEnabled(!is_hardware); 778 m_ui.threadedPresentation->setEnabled(render_api == RenderAPI::Vulkan); 779 780 m_ui.exclusiveFullscreenLabel->setEnabled(render_api == RenderAPI::D3D11 || render_api == RenderAPI::D3D12 || 781 render_api == RenderAPI::Vulkan); 782 m_ui.exclusiveFullscreenControl->setEnabled(render_api == RenderAPI::Vulkan); 783 784 populateGPUAdaptersAndResolutions(render_api); 785 updatePGXPSettingsEnabled(); 786 } 787 788 void GraphicsSettingsWidget::populateGPUAdaptersAndResolutions(RenderAPI render_api) 789 { 790 // Don't re-query, it's expensive. 791 if (m_adapters_render_api != render_api) 792 { 793 m_adapters_render_api = render_api; 794 m_adapters = GPUDevice::GetAdapterListForAPI(render_api); 795 } 796 797 const GPUDevice::AdapterInfo* current_adapter = nullptr; 798 SettingsInterface* const sif = m_dialog->getSettingsInterface(); 799 800 { 801 m_ui.adapter->disconnect(); 802 m_ui.adapter->clear(); 803 m_ui.adapter->addItem(tr("(Default)"), QVariant(QString())); 804 805 const std::string current_adapter_name = m_dialog->getEffectiveStringValue("GPU", "Adapter", ""); 806 for (const GPUDevice::AdapterInfo& adapter : m_adapters) 807 { 808 const QString qadaptername = QString::fromStdString(adapter.name); 809 m_ui.adapter->addItem(qadaptername, QVariant(qadaptername)); 810 if (adapter.name == current_adapter_name) 811 current_adapter = &adapter; 812 } 813 814 // default adapter 815 if (!m_adapters.empty() && current_adapter_name.empty()) 816 current_adapter = &m_adapters.front(); 817 818 // disable it if we don't have a choice 819 m_ui.adapter->setEnabled(!m_adapters.empty()); 820 SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.adapter, "GPU", "Adapter"); 821 connect(m_ui.adapter, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 822 &GraphicsSettingsWidget::updateRendererDependentOptions); 823 } 824 825 { 826 m_ui.fullscreenMode->disconnect(); 827 m_ui.fullscreenMode->clear(); 828 829 m_ui.fullscreenMode->addItem(tr("Borderless Fullscreen"), QVariant(QString())); 830 if (current_adapter) 831 { 832 for (const std::string& mode_name : current_adapter->fullscreen_modes) 833 { 834 const QString qmodename = QString::fromStdString(mode_name); 835 m_ui.fullscreenMode->addItem(qmodename, QVariant(qmodename)); 836 } 837 } 838 839 // disable it if we don't have a choice 840 m_ui.fullscreenMode->setEnabled(current_adapter && !current_adapter->fullscreen_modes.empty()); 841 SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.fullscreenMode, "GPU", "FullscreenMode"); 842 } 843 844 if (!m_dialog->hasGameTrait(GameDatabase::Trait::DisableUpscaling)) 845 { 846 m_ui.resolutionScale->disconnect(); 847 m_ui.resolutionScale->clear(); 848 849 static constexpr const std::pair<int, const char*> templates[] = { 850 {0, QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Automatic (Based on Window Size)")}, 851 {1, QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "1x Native (Default)")}, 852 {3, QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "3x Native (for 720p)")}, 853 {5, QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "5x Native (for 1080p)")}, 854 {6, QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "6x Native (for 1440p)")}, 855 {9, QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "9x Native (for 4K)")}, 856 }; 857 858 const int max_scale = 859 static_cast<int>(current_adapter ? std::max<u32>(current_adapter->max_texture_size / 1024, 1) : 16); 860 for (int scale = 0; scale <= max_scale; scale++) 861 { 862 const auto it = std::find_if(std::begin(templates), std::end(templates), 863 [&scale](const std::pair<int, const char*>& it) { return scale == it.first; }); 864 m_ui.resolutionScale->addItem((it != std::end(templates)) ? 865 qApp->translate("GraphicsSettingsWidget", it->second) : 866 qApp->translate("GraphicsSettingsWidget", "%1x Native").arg(scale)); 867 } 868 869 SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.resolutionScale, "GPU", "ResolutionScale", 1); 870 connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 871 &GraphicsSettingsWidget::updateResolutionDependentOptions); 872 } 873 874 { 875 m_ui.msaaMode->disconnect(); 876 m_ui.msaaMode->clear(); 877 878 if (m_dialog->isPerGameSettings()) 879 m_ui.msaaMode->addItem(tr("Use Global Setting")); 880 881 const u32 max_multisamples = current_adapter ? current_adapter->max_multisamples : 8; 882 m_ui.msaaMode->addItem(tr("Disabled"), GetMSAAModeValue(1, false)); 883 for (uint i = 2; i <= max_multisamples; i *= 2) 884 m_ui.msaaMode->addItem(tr("%1x MSAA").arg(i), GetMSAAModeValue(i, false)); 885 for (uint i = 2; i <= max_multisamples; i *= 2) 886 m_ui.msaaMode->addItem(tr("%1x SSAA").arg(i), GetMSAAModeValue(i, true)); 887 888 if (!m_dialog->isPerGameSettings() || (m_dialog->containsSettingValue("GPU", "Multisamples") || 889 m_dialog->containsSettingValue("GPU", "PerSampleShading"))) 890 { 891 const QVariant current_msaa_mode( 892 GetMSAAModeValue(static_cast<uint>(m_dialog->getEffectiveIntValue("GPU", "Multisamples", 1)), 893 m_dialog->getEffectiveBoolValue("GPU", "PerSampleShading", false))); 894 const int current_msaa_index = m_ui.msaaMode->findData(current_msaa_mode); 895 if (current_msaa_index >= 0) 896 m_ui.msaaMode->setCurrentIndex(current_msaa_index); 897 } 898 else 899 { 900 m_ui.msaaMode->setCurrentIndex(0); 901 } 902 connect(m_ui.msaaMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]() { 903 const int index = m_ui.msaaMode->currentIndex(); 904 if (m_dialog->isPerGameSettings() && index == 0) 905 { 906 m_dialog->removeSettingValue("GPU", "Multisamples"); 907 m_dialog->removeSettingValue("GPU", "PerSampleShading"); 908 } 909 else 910 { 911 uint multisamples; 912 bool ssaa; 913 DecodeMSAAModeValue(m_ui.msaaMode->itemData(index), &multisamples, &ssaa); 914 m_dialog->setIntSettingValue("GPU", "Multisamples", static_cast<int>(multisamples)); 915 m_dialog->setBoolSettingValue("GPU", "PerSampleShading", ssaa); 916 } 917 }); 918 } 919 } 920 921 void GraphicsSettingsWidget::updatePGXPSettingsEnabled() 922 { 923 const bool enabled = (effectiveRendererIsHardware() && m_dialog->getEffectiveBoolValue("GPU", "PGXPEnable", false) && 924 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXP)); 925 const bool tc_enabled = (enabled && m_dialog->getEffectiveBoolValue("GPU", "PGXPTextureCorrection", true)); 926 const bool depth_enabled = (enabled && m_dialog->getEffectiveBoolValue("GPU", "PGXPDepthBuffer", false)); 927 m_ui.tabs->setTabEnabled(TAB_INDEX_PGXP, enabled); 928 m_ui.pgxpTab->setEnabled(enabled); 929 m_ui.pgxpCulling->setEnabled(enabled && !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPCulling)); 930 m_ui.pgxpTextureCorrection->setEnabled(enabled && 931 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPTextureCorrection)); 932 m_ui.pgxpColorCorrection->setEnabled(tc_enabled && 933 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPColorCorrection)); 934 m_ui.pgxpDepthBuffer->setEnabled(enabled && !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPDepthBuffer)); 935 m_ui.pgxpPreserveProjPrecision->setEnabled(enabled && 936 !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXPPreserveProjFP)); 937 m_ui.pgxpCPU->setEnabled(enabled); 938 m_ui.pgxpVertexCache->setEnabled(enabled); 939 m_ui.pgxpGeometryTolerance->setEnabled(enabled); 940 m_ui.pgxpGeometryToleranceLabel->setEnabled(enabled); 941 m_ui.pgxpDepthClearThreshold->setEnabled(depth_enabled); 942 m_ui.pgxpDepthClearThresholdLabel->setEnabled(depth_enabled); 943 } 944 945 void GraphicsSettingsWidget::onAspectRatioChanged() 946 { 947 const DisplayAspectRatio ratio = 948 Settings::ParseDisplayAspectRatio( 949 m_dialog 950 ->getEffectiveStringValue("Display", "AspectRatio", 951 Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)) 952 .c_str()) 953 .value_or(Settings::DEFAULT_DISPLAY_ASPECT_RATIO); 954 955 const bool is_custom = (ratio == DisplayAspectRatio::Custom); 956 957 m_ui.customAspectRatioNumerator->setVisible(is_custom); 958 m_ui.customAspectRatioDenominator->setVisible(is_custom); 959 m_ui.customAspectRatioSeparator->setVisible(is_custom); 960 } 961 962 void GraphicsSettingsWidget::updateResolutionDependentOptions() 963 { 964 const int scale = m_dialog->getEffectiveIntValue("GPU", "ResolutionScale", 1); 965 const GPUTextureFilter texture_filtering = 966 Settings::ParseTextureFilterName( 967 m_dialog 968 ->getEffectiveStringValue("GPU", "TextureFilter", 969 Settings::GetTextureFilterName(Settings::DEFAULT_GPU_TEXTURE_FILTER)) 970 .c_str()) 971 .value_or(Settings::DEFAULT_GPU_TEXTURE_FILTER); 972 m_ui.forceRoundedTexcoords->setEnabled(scale > 1 && texture_filtering == GPUTextureFilter::Nearest); 973 onTrueColorChanged(); 974 } 975 976 void GraphicsSettingsWidget::onTrueColorChanged() 977 { 978 const int resolution_scale = m_dialog->getEffectiveIntValue("GPU", "ResolutionScale", 1); 979 const bool true_color = m_dialog->getEffectiveBoolValue("GPU", "TrueColor", false); 980 const bool allow_scaled_dithering = 981 (resolution_scale != 1 && !true_color && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledDithering)); 982 m_ui.scaledDithering->setEnabled(allow_scaled_dithering); 983 m_ui.debanding->setEnabled(true_color); 984 m_ui.accurateBlending->setEnabled(!true_color); 985 } 986 987 void GraphicsSettingsWidget::onDownsampleModeChanged() 988 { 989 const GPUDownsampleMode mode = 990 Settings::ParseDownsampleModeName( 991 m_dialog 992 ->getEffectiveStringValue("GPU", "DownsampleMode", 993 Settings::GetDownsampleModeName(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE)) 994 .c_str()) 995 .value_or(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE); 996 997 const bool visible = (mode == GPUDownsampleMode::Box); 998 if (visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) < 0) 999 { 1000 m_ui.gpuDownsampleScale->setVisible(true); 1001 m_ui.gpuDownsampleLayout->addWidget(m_ui.gpuDownsampleScale, 0); 1002 } 1003 else if (!visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) >= 0) 1004 { 1005 m_ui.gpuDownsampleScale->setVisible(false); 1006 m_ui.gpuDownsampleLayout->removeWidget(m_ui.gpuDownsampleScale); 1007 } 1008 } 1009 1010 void GraphicsSettingsWidget::onMediaCaptureBackendChanged() 1011 { 1012 SettingsInterface* const sif = m_dialog->getSettingsInterface(); 1013 const MediaCaptureBackend backend = 1014 MediaCapture::ParseBackendName( 1015 m_dialog 1016 ->getEffectiveStringValue("MediaCapture", "Backend", 1017 MediaCapture::GetBackendName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND)) 1018 .c_str()) 1019 .value_or(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND); 1020 1021 { 1022 m_ui.captureContainer->disconnect(); 1023 m_ui.captureContainer->clear(); 1024 1025 for (const auto& [name, display_name] : MediaCapture::GetContainerList(backend)) 1026 { 1027 const QString qname = QString::fromStdString(name); 1028 m_ui.captureContainer->addItem(tr("%1 (%2)").arg(QString::fromStdString(display_name)).arg(qname), qname); 1029 } 1030 1031 SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.captureContainer, "MediaCapture", "Container", 1032 Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER); 1033 connect(m_ui.captureContainer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 1034 &GraphicsSettingsWidget::onMediaCaptureContainerChanged); 1035 } 1036 1037 onMediaCaptureContainerChanged(); 1038 } 1039 1040 void GraphicsSettingsWidget::onMediaCaptureContainerChanged() 1041 { 1042 SettingsInterface* const sif = m_dialog->getSettingsInterface(); 1043 const MediaCaptureBackend backend = 1044 MediaCapture::ParseBackendName( 1045 m_dialog 1046 ->getEffectiveStringValue("MediaCapture", "Backend", 1047 MediaCapture::GetBackendName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND)) 1048 .c_str()) 1049 .value_or(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND); 1050 const std::string container = m_dialog->getEffectiveStringValue("MediaCapture", "Container", "mp4"); 1051 1052 { 1053 m_ui.videoCaptureCodec->disconnect(); 1054 m_ui.videoCaptureCodec->clear(); 1055 m_ui.videoCaptureCodec->addItem(tr("Default"), QVariant(QString())); 1056 1057 for (const auto& [name, display_name] : MediaCapture::GetVideoCodecList(backend, container.c_str())) 1058 { 1059 const QString qname = QString::fromStdString(name); 1060 m_ui.videoCaptureCodec->addItem(tr("%1 (%2)").arg(QString::fromStdString(display_name)).arg(qname), qname); 1061 } 1062 1063 SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.videoCaptureCodec, "MediaCapture", "VideoCodec"); 1064 } 1065 1066 { 1067 m_ui.audioCaptureCodec->disconnect(); 1068 m_ui.audioCaptureCodec->clear(); 1069 m_ui.audioCaptureCodec->addItem(tr("Default"), QVariant(QString())); 1070 1071 for (const auto& [name, display_name] : MediaCapture::GetAudioCodecList(backend, container.c_str())) 1072 { 1073 const QString qname = QString::fromStdString(name); 1074 m_ui.audioCaptureCodec->addItem(tr("%1 (%2)").arg(QString::fromStdString(display_name)).arg(qname), qname); 1075 } 1076 1077 SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.audioCaptureCodec, "MediaCapture", "AudioCodec"); 1078 } 1079 } 1080 1081 void GraphicsSettingsWidget::onMediaCaptureVideoEnabledChanged() 1082 { 1083 const bool enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "VideoCapture", true); 1084 m_ui.videoCaptureCodecLabel->setEnabled(enabled); 1085 m_ui.videoCaptureCodec->setEnabled(enabled); 1086 m_ui.videoCaptureBitrateLabel->setEnabled(enabled); 1087 m_ui.videoCaptureBitrate->setEnabled(enabled); 1088 m_ui.videoCaptureResolutionLabel->setEnabled(enabled); 1089 m_ui.videoCaptureResolutionAuto->setEnabled(enabled); 1090 m_ui.enableVideoCaptureArguments->setEnabled(enabled); 1091 m_ui.videoCaptureArguments->setEnabled(enabled); 1092 onMediaCaptureVideoAutoResolutionChanged(); 1093 } 1094 1095 void GraphicsSettingsWidget::onMediaCaptureVideoAutoResolutionChanged() 1096 { 1097 const bool enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "VideoCapture", true); 1098 const bool auto_enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "VideoAutoSize", false); 1099 m_ui.videoCaptureWidth->setEnabled(enabled && !auto_enabled); 1100 m_ui.xLabel->setEnabled(enabled && !auto_enabled); 1101 m_ui.videoCaptureHeight->setEnabled(enabled && !auto_enabled); 1102 } 1103 1104 void GraphicsSettingsWidget::onMediaCaptureAudioEnabledChanged() 1105 { 1106 const bool enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "AudioCapture", true); 1107 m_ui.audioCaptureCodecLabel->setEnabled(enabled); 1108 m_ui.audioCaptureCodec->setEnabled(enabled); 1109 m_ui.audioCaptureBitrateLabel->setEnabled(enabled); 1110 m_ui.audioCaptureBitrate->setEnabled(enabled); 1111 m_ui.enableAudioCaptureArguments->setEnabled(enabled); 1112 m_ui.audioCaptureArguments->setEnabled(enabled); 1113 } 1114 1115 void GraphicsSettingsWidget::onEnableAnyTextureReplacementsChanged() 1116 { 1117 const bool any_replacements_enabled = 1118 m_dialog->getEffectiveBoolValue("TextureReplacements", "EnableVRAMWriteReplacements", false); 1119 m_ui.preloadTextureReplacements->setEnabled(any_replacements_enabled); 1120 } 1121 1122 void GraphicsSettingsWidget::onEnableVRAMWriteDumpingChanged() 1123 { 1124 const bool enabled = m_dialog->getEffectiveBoolValue("TextureReplacements", "DumpVRAMWrites", false); 1125 m_ui.setVRAMWriteAlphaChannel->setEnabled(enabled); 1126 m_ui.minDumpedVRAMWriteWidth->setEnabled(enabled); 1127 m_ui.minDumpedVRAMWriteHeight->setEnabled(enabled); 1128 m_ui.vramWriteDumpThresholdLabel->setEnabled(enabled); 1129 m_ui.vramWriteDumpThresholdSeparator->setEnabled(enabled); 1130 }