summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorBryan Jacobs <b@q3q.us>2024-08-15 17:20:00 +1000
committerBryan Jacobs <b@q3q.us>2024-08-22 07:11:43 +1000
commit7ec6d116e8ee94bee8bdecf2bf2801ea45f09432 (patch)
tree3a6ade09680357339872b26b8c329ba3787fe256 /Source/Core
parent93617e96c3c208e032f31053e1b02f6c9ddc35e9 (diff)
Graphics: Adapt aspect ratio when SBS/TAB 3D is used
Adds support for choosing to present the full resolution independently to each eye when using side-by-side or top-and-bottom 3D.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.cpp2
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.h2
-rw-r--r--Source/Core/Core/DolphinAnalytics.cpp2
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp26
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h1
-rw-r--r--Source/Core/VideoCommon/Present.cpp70
-rw-r--r--Source/Core/VideoCommon/VideoConfig.cpp1
-rw-r--r--Source/Core/VideoCommon/VideoConfig.h1
8 files changed, 82 insertions, 23 deletions
diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp
index 4dfe819beb..cd916c6864 100644
--- a/Source/Core/Core/Config/GraphicsSettings.cpp
+++ b/Source/Core/Core/Config/GraphicsSettings.cpp
@@ -163,6 +163,8 @@ const Info<float> GFX_CC_HDR_PAPER_WHITE_NITS{{System::GFX, "ColorCorrection", "
// Graphics.Stereoscopy
const Info<StereoMode> GFX_STEREO_MODE{{System::GFX, "Stereoscopy", "StereoMode"}, StereoMode::Off};
+const Info<bool> GFX_STEREO_PER_EYE_RESOLUTION_FULL{
+ {System::GFX, "Stereoscopy", "StereoPerEyeResolutionFull"}, false};
const Info<int> GFX_STEREO_DEPTH{{System::GFX, "Stereoscopy", "StereoDepth"}, 20};
const Info<int> GFX_STEREO_CONVERGENCE_PERCENTAGE{
{System::GFX, "Stereoscopy", "StereoConvergencePercentage"}, 100};
diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h
index bccc5ae293..7bad7fefbb 100644
--- a/Source/Core/Core/Config/GraphicsSettings.h
+++ b/Source/Core/Core/Config/GraphicsSettings.h
@@ -10,6 +10,7 @@
enum class AspectMode : int;
enum class ShaderCompilationMode : int;
enum class StereoMode : int;
+enum class StereoPerEyeResolution : int;
enum class TextureFilteringMode : int;
enum class OutputResamplingMode : int;
enum class ColorCorrectionRegion : int;
@@ -139,6 +140,7 @@ extern const Info<float> GFX_CC_HDR_PAPER_WHITE_NITS;
// Graphics.Stereoscopy
extern const Info<StereoMode> GFX_STEREO_MODE;
+extern const Info<bool> GFX_STEREO_PER_EYE_RESOLUTION_FULL;
extern const Info<int> GFX_STEREO_DEPTH;
extern const Info<int> GFX_STEREO_CONVERGENCE_PERCENTAGE;
extern const Info<bool> GFX_STEREO_SWAP_EYES;
diff --git a/Source/Core/Core/DolphinAnalytics.cpp b/Source/Core/Core/DolphinAnalytics.cpp
index 5a5118932b..cc74b4d8af 100644
--- a/Source/Core/Core/DolphinAnalytics.cpp
+++ b/Source/Core/Core/DolphinAnalytics.cpp
@@ -385,6 +385,8 @@ void DolphinAnalytics::MakePerGameBuilder()
builder.AddData("cfg-gfx-internal-resolution", g_Config.iEFBScale);
builder.AddData("cfg-gfx-tc-samples", g_Config.iSafeTextureCache_ColorSamples);
builder.AddData("cfg-gfx-stereo-mode", static_cast<int>(g_Config.stereo_mode));
+ builder.AddData("cfg-gfx-stereo-per-eye-resolution-full",
+ g_Config.stereo_per_eye_resolution_full);
builder.AddData("cfg-gfx-hdr", static_cast<int>(g_Config.bHDR));
builder.AddData("cfg-gfx-per-pixel-lighting", g_Config.bEnablePixelLighting);
builder.AddData("cfg-gfx-shader-compilation-mode", GetShaderCompilationMode(g_Config));
diff --git a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
index f70b01ef6a..897eea6be6 100644
--- a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
@@ -213,8 +213,12 @@ void EnhancementsWidget::CreateWidgets()
m_3d_depth = new ConfigSlider(0, Config::GFX_STEREO_DEPTH_MAXIMUM, Config::GFX_STEREO_DEPTH);
m_3d_convergence = new ConfigSlider(0, Config::GFX_STEREO_CONVERGENCE_MAXIMUM,
Config::GFX_STEREO_CONVERGENCE, 100);
+
m_3d_swap_eyes = new ConfigBool(tr("Swap Eyes"), Config::GFX_STEREO_SWAP_EYES);
+ m_3d_per_eye_resolution =
+ new ConfigBool(tr("Use Full Resolution Per Eye"), Config::GFX_STEREO_PER_EYE_RESOLUTION_FULL);
+
stereoscopy_layout->addWidget(new QLabel(tr("Stereoscopic 3D Mode:")), 0, 0);
stereoscopy_layout->addWidget(m_3d_mode, 0, 1);
stereoscopy_layout->addWidget(new QLabel(tr("Depth:")), 1, 0);
@@ -222,6 +226,11 @@ void EnhancementsWidget::CreateWidgets()
stereoscopy_layout->addWidget(new QLabel(tr("Convergence:")), 2, 0);
stereoscopy_layout->addWidget(m_3d_convergence, 2, 1);
stereoscopy_layout->addWidget(m_3d_swap_eyes, 3, 0);
+ stereoscopy_layout->addWidget(m_3d_per_eye_resolution, 4, 0);
+
+ auto current_stereo_mode = Config::Get(Config::GFX_STEREO_MODE);
+ if (current_stereo_mode != StereoMode::SBS && current_stereo_mode != StereoMode::TAB)
+ m_3d_per_eye_resolution->hide();
main_layout->addWidget(enhancements_box);
main_layout->addWidget(stereoscopy_box);
@@ -241,9 +250,16 @@ void EnhancementsWidget::ConnectWidgets()
connect(m_3d_mode, &QComboBox::currentIndexChanged, [this] {
m_block_save = true;
m_configure_color_correction->setEnabled(g_Config.backend_info.bSupportsPostProcessing);
- LoadPPShaders(static_cast<StereoMode>(m_3d_mode->currentIndex()));
- m_block_save = false;
+ auto current_stereo_mode = Config::Get(Config::GFX_STEREO_MODE);
+ LoadPPShaders(current_stereo_mode);
+
+ if (current_stereo_mode == StereoMode::SBS || current_stereo_mode == StereoMode::TAB)
+ m_3d_per_eye_resolution->show();
+ else
+ m_3d_per_eye_resolution->hide();
+
+ m_block_save = false;
SaveSettings();
});
connect(m_configure_color_correction, &QPushButton::clicked, this,
@@ -609,6 +625,10 @@ void EnhancementsWidget::AddDescriptions()
static const char TR_3D_SWAP_EYES_DESCRIPTION[] = QT_TR_NOOP(
"Swaps the left and right eye. Most useful in side-by-side stereoscopy "
"mode.<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
+ static const char TR_3D_PER_EYE_RESOLUTION_DESCRIPTION[] =
+ QT_TR_NOOP("Whether each eye gets full or half image resolution when using side-by-side "
+ "or above-and-below 3D."
+ "<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
static const char TR_FORCE_24BIT_DESCRIPTION[] = QT_TR_NOOP(
"Forces the game to render the RGB color channels in 24-bit, thereby increasing "
"quality by reducing color banding.<br><br>Has no impact on performance and causes "
@@ -679,6 +699,8 @@ void EnhancementsWidget::AddDescriptions()
m_3d_convergence->SetTitle(tr("Convergence"));
m_3d_convergence->SetDescription(tr(TR_3D_CONVERGENCE_DESCRIPTION));
+ m_3d_per_eye_resolution->SetDescription(tr(TR_3D_PER_EYE_RESOLUTION_DESCRIPTION));
+
m_3d_swap_eyes->SetDescription(tr(TR_3D_SWAP_EYES_DESCRIPTION));
}
diff --git a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h
index 7c4c193fb4..9e64d5400f 100644
--- a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h
+++ b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h
@@ -58,6 +58,7 @@ private:
ConfigSlider* m_3d_depth;
ConfigSlider* m_3d_convergence;
ConfigBool* m_3d_swap_eyes;
+ ConfigBool* m_3d_per_eye_resolution;
int m_msaa_modes;
bool m_block_save;
diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp
index 66d377acd7..c7ae018bbc 100644
--- a/Source/Core/VideoCommon/Present.cpp
+++ b/Source/Core/VideoCommon/Present.cpp
@@ -398,40 +398,68 @@ Presenter::ConvertStereoRectangle(const MathUtil::Rectangle<int>& rc) const
float Presenter::CalculateDrawAspectRatio(bool allow_stretch) const
{
auto aspect_mode = g_ActiveConfig.aspect_mode;
+ float resulting_aspect_ratio;
if (!allow_stretch && aspect_mode == AspectMode::Stretch)
aspect_mode = AspectMode::Auto;
// If stretch is enabled, we prefer the aspect ratio of the window.
if (aspect_mode == AspectMode::Stretch)
- return (static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height));
-
- // The actual aspect ratio of the XFB texture is irrelevant, the VI one is the one that matters
- const auto& vi = Core::System::GetInstance().GetVideoInterface();
- const float source_aspect_ratio = vi.GetAspectRatio();
-
- // This will scale up the source ~4:3 resolution to its equivalent ~16:9 resolution
- if (aspect_mode == AspectMode::ForceWide ||
- (aspect_mode == AspectMode::Auto && g_widescreen->IsGameWidescreen()))
- {
- return SourceAspectRatioToWidescreen(source_aspect_ratio);
- }
- else if (aspect_mode == AspectMode::Custom)
{
- return source_aspect_ratio * (g_ActiveConfig.GetCustomAspectRatio() / (4.0f / 3.0f));
+ resulting_aspect_ratio =
+ (static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height));
}
- // For the "custom stretch" mode, we force the exact target aspect ratio, without
- // acknowleding the difference between the source aspect ratio and 4:3.
- else if (aspect_mode == AspectMode::CustomStretch)
+ else
{
- return g_ActiveConfig.GetCustomAspectRatio();
+ // The actual aspect ratio of the XFB texture is irrelevant, the VI one is the one that matters
+ const auto& vi = Core::System::GetInstance().GetVideoInterface();
+ const float source_aspect_ratio = vi.GetAspectRatio();
+
+ // This will scale up the source ~4:3 resolution to its equivalent ~16:9 resolution
+ if (aspect_mode == AspectMode::ForceWide ||
+ (aspect_mode == AspectMode::Auto && g_widescreen->IsGameWidescreen()))
+ {
+ resulting_aspect_ratio = SourceAspectRatioToWidescreen(source_aspect_ratio);
+ }
+ else if (aspect_mode == AspectMode::Custom)
+ {
+ resulting_aspect_ratio =
+ source_aspect_ratio * (g_ActiveConfig.GetCustomAspectRatio() / (4.0f / 3.0f));
+ }
+ // For the "custom stretch" mode, we force the exact target aspect ratio, without
+ // acknowledging the difference between the source aspect ratio and 4:3.
+ else if (aspect_mode == AspectMode::CustomStretch)
+ {
+ resulting_aspect_ratio = g_ActiveConfig.GetCustomAspectRatio();
+ }
+ else if (aspect_mode == AspectMode::Raw)
+ {
+ resulting_aspect_ratio =
+ m_xfb_entry ? (static_cast<float>(m_last_xfb_width) / m_last_xfb_height) : 1.f;
+ }
+ else
+ {
+ resulting_aspect_ratio = source_aspect_ratio;
+ }
}
- else if (aspect_mode == AspectMode::Raw)
+
+ if (g_ActiveConfig.stereo_per_eye_resolution_full)
{
- return m_xfb_entry ? (static_cast<float>(m_last_xfb_width) / m_last_xfb_height) : 1.f;
+ if (g_ActiveConfig.stereo_mode == StereoMode::SBS)
+ {
+ // Render twice as wide if using side-by-side 3D, since the 3D will halve the horizontal
+ // resolution
+ resulting_aspect_ratio *= 2.0;
+ }
+ else if (g_ActiveConfig.stereo_mode == StereoMode::TAB)
+ {
+ // Render twice as tall if using top-and-bottom 3D, since the 3D will halve the vertical
+ // resolution
+ resulting_aspect_ratio /= 2.0;
+ }
}
- return source_aspect_ratio;
+ return resulting_aspect_ratio;
}
void Presenter::AdjustRectanglesToFitBounds(MathUtil::Rectangle<int>* target_rect,
diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp
index efa159795c..8ca1f4ec63 100644
--- a/Source/Core/VideoCommon/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/VideoConfig.cpp
@@ -171,6 +171,7 @@ void VideoConfig::Refresh()
color_correction.fHDRPaperWhiteNits = Config::Get(Config::GFX_CC_HDR_PAPER_WHITE_NITS);
stereo_mode = Config::Get(Config::GFX_STEREO_MODE);
+ stereo_per_eye_resolution_full = Config::Get(Config::GFX_STEREO_PER_EYE_RESOLUTION_FULL);
iStereoDepth = Config::Get(Config::GFX_STEREO_DEPTH);
iStereoConvergencePercentage = Config::Get(Config::GFX_STEREO_CONVERGENCE_PERCENTAGE);
bStereoSwapEyes = Config::Get(Config::GFX_STEREO_SWAP_EYES);
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index 1e5f03d0e5..5cce23bfd2 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -241,6 +241,7 @@ struct VideoConfig final
// Stereoscopy
StereoMode stereo_mode{};
+ bool stereo_per_eye_resolution_full = false;
int iStereoDepth = 0;
int iStereoConvergence = 0;
int iStereoConvergencePercentage = 0;