diff --git a/docs/window/settings_window.rst b/docs/window/settings_window.rst
index ecf1c8f85..bac68f67c 100644
--- a/docs/window/settings_window.rst
+++ b/docs/window/settings_window.rst
@@ -182,6 +182,12 @@ When changing texture from one to another, when this option is enabled the range
Settings including which channels are displayed (red, green, blue, alpha or depth/stencil), the mip or slice/cubemap face to display, or the visible min/max range values are remembered with the texture you were looking at. In other words if you display a render target with only the alpha channel visible, then switching to view another texture will default back to RGB - and switching back to that render target will view alpha again.
+---------------
+
+ | :guilabel:`Y-flipping state saved per-texture` Default: ``Disabled``
+
+If the above setting is enabled, then also store the y-flip per texture. By default this is treated as a global toggle for all textures. With this setting enabled the flip will default to off for all textures, and then be saved per-texture.
+
Shader Viewer options
---------------------
diff --git a/qrenderdoc/Code/Interface/PersistantConfig.h b/qrenderdoc/Code/Interface/PersistantConfig.h
index 22d29628f..fab0421af 100644
--- a/qrenderdoc/Code/Interface/PersistantConfig.h
+++ b/qrenderdoc/Code/Interface/PersistantConfig.h
@@ -284,6 +284,8 @@ DECLARE_REFLECTION_STRUCT(BugReport);
\
CONFIG_SETTING_VAL(public, bool, bool, TextureViewer_PerTexSettings, true) \
\
+ CONFIG_SETTING_VAL(public, bool, bool, TextureViewer_PerTexYFlip, false) \
+ \
CONFIG_SETTING_VAL(public, bool, bool, ShaderViewer_FriendlyNaming, true) \
\
CONFIG_SETTING_VAL(public, bool, bool, AlwaysReplayLocally, false) \
@@ -480,6 +482,15 @@ For more information about some of these settings that are user-facing see
Defaults to ``True``.
+.. data:: TextureViewer_PerTexYFlip
+
+ ``True`` if the :class:`TextureViewer` should treat y-flipping as a per-texture state rather than
+ a global toggle.
+
+ Does nothing if per-texture settings are disabled in general.
+
+ Defaults to ``False``.
+
.. data:: ShaderViewer_FriendlyNaming
``True`` if the :class:`ShaderViewer` should replace register names with the high-level language
diff --git a/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp b/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp
index 9b005eb61..d5764a95b 100644
--- a/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp
+++ b/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp
@@ -108,10 +108,13 @@ SettingsDialog::SettingsDialog(ICaptureContext &ctx, QWidget *parent)
ui->TextureViewer_ResetRange->setChecked(m_Ctx.Config().TextureViewer_ResetRange);
ui->TextureViewer_PerTexSettings->setChecked(m_Ctx.Config().TextureViewer_PerTexSettings);
+ ui->TextureViewer_PerTexYFlip->setChecked(m_Ctx.Config().TextureViewer_PerTexYFlip);
ui->ShaderViewer_FriendlyNaming->setChecked(m_Ctx.Config().ShaderViewer_FriendlyNaming);
ui->CheckUpdate_AllowChecks->setChecked(m_Ctx.Config().CheckUpdate_AllowChecks);
ui->Font_PreferMonospaced->setChecked(m_Ctx.Config().Font_PreferMonospaced);
+ ui->TextureViewer_PerTexYFlip->setEnabled(ui->TextureViewer_PerTexSettings->isChecked());
+
ui->AlwaysReplayLocally->setChecked(m_Ctx.Config().AlwaysReplayLocally);
#if RENDERDOC_ANALYTICS_ENABLE
@@ -422,6 +425,15 @@ void SettingsDialog::on_TextureViewer_PerTexSettings_toggled(bool checked)
{
m_Ctx.Config().TextureViewer_PerTexSettings = ui->TextureViewer_PerTexSettings->isChecked();
+ ui->TextureViewer_PerTexYFlip->setEnabled(ui->TextureViewer_PerTexSettings->isChecked());
+
+ m_Ctx.Config().Save();
+}
+
+void SettingsDialog::on_TextureViewer_PerTexYFlip_toggled(bool checked)
+{
+ m_Ctx.Config().TextureViewer_PerTexYFlip = ui->TextureViewer_PerTexYFlip->isChecked();
+
m_Ctx.Config().Save();
}
diff --git a/qrenderdoc/Windows/Dialogs/SettingsDialog.h b/qrenderdoc/Windows/Dialogs/SettingsDialog.h
index 035953166..a9f7a77dd 100644
--- a/qrenderdoc/Windows/Dialogs/SettingsDialog.h
+++ b/qrenderdoc/Windows/Dialogs/SettingsDialog.h
@@ -76,6 +76,7 @@ private slots:
// texture viewer
void on_TextureViewer_PerTexSettings_toggled(bool checked);
void on_TextureViewer_ResetRange_toggled(bool checked);
+ void on_TextureViewer_PerTexYFlip_toggled(bool checked);
// shader viewer
void on_ShaderViewer_FriendlyNaming_toggled(bool checked);
diff --git a/qrenderdoc/Windows/Dialogs/SettingsDialog.ui b/qrenderdoc/Windows/Dialogs/SettingsDialog.ui
index d342b7d2c..c3e5e7037 100644
--- a/qrenderdoc/Windows/Dialogs/SettingsDialog.ui
+++ b/qrenderdoc/Windows/Dialogs/SettingsDialog.ui
@@ -631,14 +631,46 @@ After interop is enabled you will need to reload any capture.
- The visible channels (RGBA) and selected mip/slice are remembered and restored per-texture.
+ Settings such as visible channels (RGBA) and selected mip/slice are remembered and restored per-texture.
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Y-flipping state is remembered and restored per-texture, rather than treated as a global toggle.
+
+
+ Y-flipping state saved per-texture
+
+
+
-
+
+
+
+ 50
+ 0
+
+
+
+ Y-flipping state is remembered and restored per-texture, rather than treated as a global toggle.
+
+
+
+
+
+
+ -
Qt::Vertical
diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp
index df8eadf23..a3acbeaf7 100644
--- a/qrenderdoc/Windows/TextureViewer.cpp
+++ b/qrenderdoc/Windows/TextureViewer.cpp
@@ -1109,6 +1109,9 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw)
m_TextureSettings[m_TexDisplay.resourceId].b = ui->channelBlue->isChecked();
m_TextureSettings[m_TexDisplay.resourceId].a = ui->channelAlpha->isChecked();
+ // save state regardless, we just don't apply it without the setting
+ m_TextureSettings[m_TexDisplay.resourceId].flip_y = ui->flip_y->isChecked();
+
m_TextureSettings[m_TexDisplay.resourceId].displayType = qMax(0, ui->channels->currentIndex());
m_TextureSettings[m_TexDisplay.resourceId].customShader = ui->customShader->currentText();
@@ -1317,6 +1320,9 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw)
if(useslicesettings)
ui->sliceFace->setCurrentIndex(m_TextureSettings[tex.resourceId].slice);
+
+ if(m_Ctx.Config().TextureViewer_PerTexYFlip)
+ ui->flip_y->setChecked(m_TextureSettings[tex.resourceId].flip_y);
}
// handling for if we've switched to a new texture
@@ -1337,6 +1343,9 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw)
ui->depthDisplay->setChecked(m_TextureSettings[tex.resourceId].depth);
ui->stencilDisplay->setChecked(m_TextureSettings[tex.resourceId].stencil);
+ if(m_Ctx.Config().TextureViewer_PerTexYFlip)
+ ui->flip_y->setChecked(m_TextureSettings[tex.resourceId].flip_y);
+
m_NoRangePaint = true;
ui->rangeHistogram->setRange(m_TextureSettings[m_TexDisplay.resourceId].minrange,
m_TextureSettings[m_TexDisplay.resourceId].maxrange);
@@ -1357,6 +1366,9 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw)
ui->depthDisplay->setChecked(true);
ui->stencilDisplay->setChecked(false);
+ if(m_Ctx.Config().TextureViewer_PerTexYFlip)
+ ui->flip_y->setChecked(false);
+
m_NoRangePaint = true;
UI_SetHistogramRange(texptr, m_TexDisplay.typeHint);
m_NoRangePaint = false;
diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h
index 2f2b9ac47..d21fe8d11 100644
--- a/qrenderdoc/Windows/TextureViewer.h
+++ b/qrenderdoc/Windows/TextureViewer.h
@@ -97,6 +97,7 @@ struct TexSettings
displayType = 0;
r = g = b = true;
a = false;
+ flip_y = false;
depth = true;
stencil = false;
mip = 0;
@@ -109,6 +110,7 @@ struct TexSettings
int displayType; // RGBA, RGBM, YUV Decode, Custom
QString customShader;
bool r, g, b, a;
+ bool flip_y;
bool depth, stencil;
int mip, slice;
float minrange, maxrange;