GS/HW: Add partial target invalidation option

Eventually hopefully we can make this the default, but it breaks too
much at the moment.

Fixes missing/corrupted textures in True Crime: New York City.
This commit is contained in:
Stenzek 2023-02-25 00:06:53 +10:00 committed by refractionpcsx2
parent a06a07d961
commit 4583c64ff7
12 changed files with 177 additions and 114 deletions

View File

@ -17799,9 +17799,12 @@ SLES-53616:
eeRoundMode: 0 # Fixes scene switching in intro. eeRoundMode: 0 # Fixes scene switching in intro.
gsHWFixes: gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures. cpuSpriteRenderBW: 1 # Fixes textures.
preloadFrameData: 1 # Fixes static text screens. partialTargetInvalidation: 1 # Needed due to procedural textures overlapping EE writes.
preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
roundSprite: 1 # Fixes lines in some post-effects. roundSprite: 1 # Fixes lines in some post-effects.
cpuCLUTRender: 1 # Fixes light occlusion. gpuTargetCLUT: 1 # Fixes light occlusion.
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
SLES-53617: SLES-53617:
name: "True Crime - New York City" name: "True Crime - New York City"
region: "PAL-G" region: "PAL-G"
@ -17811,9 +17814,12 @@ SLES-53617:
eeRoundMode: 0 # Fixes scene switching in intro. eeRoundMode: 0 # Fixes scene switching in intro.
gsHWFixes: gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures. cpuSpriteRenderBW: 1 # Fixes textures.
preloadFrameData: 1 # Fixes static text screens. partialTargetInvalidation: 1 # Needed due to procedural textures overlapping EE writes.
preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
roundSprite: 1 # Fixes lines in some post-effects. roundSprite: 1 # Fixes lines in some post-effects.
cpuCLUTRender: 1 # Fixes light occlusion. gpuTargetCLUT: 1 # Fixes light occlusion.
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
SLES-53618: SLES-53618:
name: "True Crime - New York City" name: "True Crime - New York City"
region: "PAL-S" region: "PAL-S"
@ -17823,9 +17829,12 @@ SLES-53618:
eeRoundMode: 0 # Fixes scene switching in intro. eeRoundMode: 0 # Fixes scene switching in intro.
gsHWFixes: gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures. cpuSpriteRenderBW: 1 # Fixes textures.
preloadFrameData: 1 # Fixes static text screens. partialTargetInvalidation: 1 # Needed due to procedural textures overlapping EE writes.
preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
roundSprite: 1 # Fixes lines in some post-effects. roundSprite: 1 # Fixes lines in some post-effects.
cpuCLUTRender: 1 # Fixes light occlusion. gpuTargetCLUT: 1 # Fixes light occlusion.
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
SLES-53621: SLES-53621:
name: "Wallace & Gromit - The Curse of the Were-Rabbit" name: "Wallace & Gromit - The Curse of the Were-Rabbit"
region: "PAL-M5" region: "PAL-M5"
@ -32922,9 +32931,12 @@ SLPM-66473:
eeRoundMode: 0 # Fixes scene switching in intro. eeRoundMode: 0 # Fixes scene switching in intro.
gsHWFixes: gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures. cpuSpriteRenderBW: 1 # Fixes textures.
preloadFrameData: 1 # Fixes static text screens. partialTargetInvalidation: 1 # Needed due to procedural textures overlapping EE writes.
preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
roundSprite: 1 # Fixes lines in some post-effects. roundSprite: 1 # Fixes lines in some post-effects.
cpuCLUTRender: 1 # Fixes light occlusion. gpuTargetCLUT: 1 # Fixes light occlusion.
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
SLPM-66474: SLPM-66474:
name: "Odin Sphere" name: "Odin Sphere"
region: "NTSC-J" region: "NTSC-J"
@ -35287,9 +35299,12 @@ SLPM-74243:
eeRoundMode: 0 # Fixes scene switching in intro. eeRoundMode: 0 # Fixes scene switching in intro.
gsHWFixes: gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures. cpuSpriteRenderBW: 1 # Fixes textures.
preloadFrameData: 1 # Fixes static text screens. partialTargetInvalidation: 1 # Needed due to procedural textures overlapping EE writes.
preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
roundSprite: 1 # Fixes lines in some post-effects. roundSprite: 1 # Fixes lines in some post-effects.
cpuCLUTRender: 1 # Fixes light occlusion. gpuTargetCLUT: 1 # Fixes light occlusion.
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
SLPM-74244: SLPM-74244:
name: "Phantasy Star Universe [PlayStation 2 The Best]" name: "Phantasy Star Universe [PlayStation 2 The Best]"
region: "NTSC-J" region: "NTSC-J"
@ -45988,9 +46003,12 @@ SLUS-21106:
eeRoundMode: 0 # Fixes scene switching in intro. eeRoundMode: 0 # Fixes scene switching in intro.
gsHWFixes: gsHWFixes:
cpuSpriteRenderBW: 1 # Fixes textures. cpuSpriteRenderBW: 1 # Fixes textures.
preloadFrameData: 1 # Fixes static text screens. partialTargetInvalidation: 1 # Needed due to procedural textures overlapping EE writes.
preloadFrameData: 1 # Fixes numberplates and ensures above targets are valid.
roundSprite: 1 # Fixes lines in some post-effects. roundSprite: 1 # Fixes lines in some post-effects.
cpuCLUTRender: 1 # Fixes light occlusion. gpuTargetCLUT: 1 # Fixes light occlusion.
mipmap: 2 # Mipmap + trilinear, improves ground textures to match sw renderer.
trilinearFiltering: 1
SLUS-21107: SLUS-21107:
name: "X-Men - The Official Game" name: "X-Men - The Official Game"
region: "NTSC-U" region: "NTSC-U"

View File

@ -178,8 +178,11 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
&GraphicsSettingsWidget::onTrilinearFilteringChanged); &GraphicsSettingsWidget::onTrilinearFilteringChanged);
connect(m_ui.gpuPaletteConversion, QOverload<int>::of(&QCheckBox::stateChanged), this, connect(m_ui.gpuPaletteConversion, QOverload<int>::of(&QCheckBox::stateChanged), this,
&GraphicsSettingsWidget::onGpuPaletteConversionChanged); &GraphicsSettingsWidget::onGpuPaletteConversionChanged);
connect(m_ui.textureInsideRt, QOverload<int>::of(&QCheckBox::stateChanged), this,
&GraphicsSettingsWidget::onTextureInsideRtChanged);
onTrilinearFilteringChanged(); onTrilinearFilteringChanged();
onGpuPaletteConversionChanged(m_ui.gpuPaletteConversion->checkState()); onGpuPaletteConversionChanged(m_ui.gpuPaletteConversion->checkState());
onTextureInsideRtChanged(m_ui.textureInsideRt->checkState());
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// HW Renderer Fixes // HW Renderer Fixes
@ -199,6 +202,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
sif, m_ui.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false); sif, m_ui.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureInsideRt, "EmuCore/GS", "UserHacks_TextureInsideRt", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureInsideRt, "EmuCore/GS", "UserHacks_TextureInsideRt", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.readTCOnClose, "EmuCore/GS", "UserHacks_ReadTCOnClose", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.readTCOnClose, "EmuCore/GS", "UserHacks_ReadTCOnClose", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.targetPartialInvalidation, "EmuCore/GS", "UserHacks_TargetPartialInvalidation", false);
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// HW Upscaling Fixes // HW Upscaling Fixes
@ -523,7 +527,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
"Disables accurate GS Memory Clearing to be done on the CPU, and let the GPU handle it, which can help Kingdom Hearts " "Disables accurate GS Memory Clearing to be done on the CPU, and let the GPU handle it, which can help Kingdom Hearts "
"games.")); "games."));
dialog->registerWidgetHelp(m_ui.disablePartialInvalidation, tr("Disable Partial Invalidation"), tr("Unchecked"), dialog->registerWidgetHelp(m_ui.disablePartialInvalidation, tr("Disable Partial Source Invalidation"), tr("Unchecked"),
tr("By default, the texture cache handles partial invalidations. Unfortunately it is very costly to compute CPU wise. " tr("By default, the texture cache handles partial invalidations. Unfortunately it is very costly to compute CPU wise. "
"This hack replaces the partial invalidation with a complete deletion of the texture to reduce the CPU load. " "This hack replaces the partial invalidation with a complete deletion of the texture to reduce the CPU load. "
"It helps snowblind engine games.")); "It helps snowblind engine games."));
@ -536,12 +540,15 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
"Fixes black screen issues in games like Armored Core: Last Raven.")); "Fixes black screen issues in games like Armored Core: Last Raven."));
dialog->registerWidgetHelp(m_ui.textureInsideRt, tr("Texture Inside RT"), tr("Unchecked"), dialog->registerWidgetHelp(m_ui.textureInsideRt, tr("Texture Inside RT"), tr("Unchecked"),
tr("Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer. " tr("Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer."));
"In some selected games this is enabled by default regardless of this setting."));
dialog->registerWidgetHelp(m_ui.readTCOnClose, tr("Read Targets When Closing"), tr("Unchecked"), dialog->registerWidgetHelp(m_ui.readTCOnClose, tr("Read Targets When Closing"), tr("Unchecked"),
tr("Flushes all targets in the texture cache back to local memory when shutting down. Can prevent lost visuals when saving " tr("Flushes all targets in the texture cache back to local memory when shutting down. Can prevent lost visuals when saving "
"state or switching renderers, but can also cause graphical corruption.")); "state or switching renderers, but can also cause graphical corruption."));
dialog->registerWidgetHelp(m_ui.targetPartialInvalidation, tr("Target Partial Invalidation"), tr("Unchecked"),
tr("Allows partial invalidation of render targets, which can fix graphical errors in some games. Texture Inside Render Target "
"automatically enables this option."));
} }
// Upscaling Fixes tab // Upscaling Fixes tab
@ -844,9 +851,19 @@ void GraphicsSettingsWidget::onEnableAudioCaptureArgumentsChanged()
void GraphicsSettingsWidget::onGpuPaletteConversionChanged(int state) void GraphicsSettingsWidget::onGpuPaletteConversionChanged(int state)
{ {
const bool enabled = state == Qt::CheckState::PartiallyChecked ? Host::GetBaseBoolSettingValue("EmuCore/GS", "paltex", false) : state; const bool disabled =
state == Qt::CheckState::PartiallyChecked ? Host::GetBaseBoolSettingValue("EmuCore/GS", "paltex", false) : (state != 0);
m_ui.anisotropicFiltering->setEnabled(!enabled); m_ui.anisotropicFiltering->setDisabled(disabled);
}
void GraphicsSettingsWidget::onTextureInsideRtChanged(int state)
{
const bool disabled = state == Qt::CheckState::PartiallyChecked ?
Host::GetBaseBoolSettingValue("EmuCore/GS", "UserHacks_TextureInsideRt", false) :
(state != 0);
m_ui.targetPartialInvalidation->setDisabled(disabled);
} }
GSRendererType GraphicsSettingsWidget::getEffectiveRenderer() const GSRendererType GraphicsSettingsWidget::getEffectiveRenderer() const

View File

@ -41,6 +41,7 @@ private Q_SLOTS:
void onAdapterChanged(int index); void onAdapterChanged(int index);
void onTrilinearFilteringChanged(); void onTrilinearFilteringChanged();
void onGpuPaletteConversionChanged(int state); void onGpuPaletteConversionChanged(int state);
void onTextureInsideRtChanged(int state);
void onFullscreenModeChanged(int index); void onFullscreenModeChanged(int index);
void onShadeBoostChanged(); void onShadeBoostChanged();
void onCaptureContainerChanged(); void onCaptureContainerChanged();

View File

@ -920,91 +920,13 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_12"> <widget class="QLabel" name="label_16">
<property name="text"> <property name="text">
<string>Skipdraw Range:</string> <string>Software CLUT Render:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="skipDrawStart">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="skipDrawEnd">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QCheckBox" name="frameBufferConversion">
<property name="text">
<string>Frame Buffer Conversion</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="hwAutoFlush">
<property name="text">
<string>Auto Flush</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="disableDepthEmulation">
<property name="text">
<string>Disable Depth Emulation</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="preloadFrameData">
<property name="text">
<string>Preload Frame Data</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="disablePartialInvalidation">
<property name="text">
<string>Disable Partial Invalidation</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="disableSafeFeatures">
<property name="text">
<string>Disable Safe Features</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="textureInsideRt">
<property name="text">
<string>Texture Inside RT</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="readTCOnClose">
<property name="text">
<string>Read Targets When Closing</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QComboBox" name="cpuCLUTRender"> <widget class="QComboBox" name="cpuCLUTRender">
<property name="currentText"> <property name="currentText">
@ -1030,13 +952,6 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Software CLUT Render:</string>
</property>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_47"> <widget class="QLabel" name="label_47">
<property name="text"> <property name="text">
@ -1063,6 +978,98 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Skipdraw Range:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="skipDrawStart">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="skipDrawEnd">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QCheckBox" name="preloadFrameData">
<property name="text">
<string>Preload Frame Data</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="textureInsideRt">
<property name="text">
<string>Texture Inside RT</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="disableDepthEmulation">
<property name="text">
<string>Disable Depth Emulation</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="disablePartialInvalidation">
<property name="text">
<string>Disable Partial Source Invalidation</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="disableSafeFeatures">
<property name="text">
<string>Disable Safe Features</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="targetPartialInvalidation">
<property name="text">
<string>Target Partial Invalidation</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="frameBufferConversion">
<property name="text">
<string>Frame Buffer Conversion</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="hwAutoFlush">
<property name="text">
<string>Auto Flush</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="readTCOnClose">
<property name="text">
<string>Read Targets When Closing</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QGroupBox" name="upscalingFixesTab"> <widget class="QGroupBox" name="upscalingFixesTab">

View File

@ -671,6 +671,7 @@ struct Pcsx2Config
UserHacks_MergePPSprite : 1, UserHacks_MergePPSprite : 1,
UserHacks_WildHack : 1, UserHacks_WildHack : 1,
UserHacks_TextureInsideRt : 1, UserHacks_TextureInsideRt : 1,
UserHacks_TargetPartialInvalidation : 1,
FXAA : 1, FXAA : 1,
ShadeBoost : 1, ShadeBoost : 1,
DumpGSData : 1, DumpGSData : 1,

View File

@ -151,6 +151,11 @@
"minimum": 0, "minimum": 0,
"maximum": 1 "maximum": 1
}, },
"partialTargetInvalidation": {
"type": "integer",
"minimum": 0,
"maximum": 1
},
"textureInsideRT": { "textureInsideRT": {
"type": "integer", "type": "integer",
"minimum": 0, "minimum": 0,

View File

@ -3196,6 +3196,10 @@ void FullscreenUI::DrawGraphicsSettingsPage()
DrawToggleSetting(bsi, "Texture Inside Render Target", DrawToggleSetting(bsi, "Texture Inside Render Target",
"Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer.", "EmuCore/GS", "Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer.", "EmuCore/GS",
"UserHacks_TextureInsideRt", false, manual_hw_fixes); "UserHacks_TextureInsideRt", false, manual_hw_fixes);
DrawToggleSetting(bsi, "Target Partial Invalidation",
"Allows partial invalidation of render targets, which can fix graphical errors in some games.", "EmuCore/GS",
"UserHacks_TargetPartialInvalidation", false,
!GetEffectiveBoolSetting(bsi, "EmuCore/GS", "UserHacks_TextureInsideRt", false));
DrawToggleSetting(bsi, "Read Targets When Closing", DrawToggleSetting(bsi, "Read Targets When Closing",
"Flushes all targets in the texture cache back to local memory when shutting down.", "EmuCore/GS", "Flushes all targets in the texture cache back to local memory when shutting down.", "EmuCore/GS",
"UserHacks_ReadTCOnClose", false, manual_hw_fixes); "UserHacks_ReadTCOnClose", false, manual_hw_fixes);

View File

@ -427,6 +427,8 @@ void ImGuiManager::DrawSettingsOverlay()
APPEND("DDE "); APPEND("DDE ");
if (GSConfig.UserHacks_DisablePartialInvalidation) if (GSConfig.UserHacks_DisablePartialInvalidation)
APPEND("DPIV "); APPEND("DPIV ");
if (GSConfig.UserHacks_TargetPartialInvalidation)
APPEND("TPV ");
if (GSConfig.UserHacks_DisableSafeFeatures) if (GSConfig.UserHacks_DisableSafeFeatures)
APPEND("DSF "); APPEND("DSF ");
if (GSConfig.WrapGSMem) if (GSConfig.WrapGSMem)

View File

@ -1210,6 +1210,9 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
const u32 end_bp = off.bn(rect.z - 1, rect.w - 1); const u32 end_bp = off.bn(rect.z - 1, rect.w - 1);
const u32 unwrapped_end_bp = end_bp + ((end_bp < bp) ? MAX_BLOCKS : 0); const u32 unwrapped_end_bp = end_bp + ((end_bp < bp) ? MAX_BLOCKS : 0);
// Ideally in the future we can turn this on unconditionally, but for now it breaks too much.
const bool check_inside_target = (GSConfig.UserHacks_TargetPartialInvalidation || GSConfig.UserHacks_TextureInsideRt);
for (int type = 0; type < 2; type++) for (int type = 0; type < 2; type++)
{ {
auto& list = m_dst[type]; auto& list = m_dst[type];
@ -1355,17 +1358,11 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
const u32 rowsize = bw * 8192; const u32 rowsize = bw * 8192;
const u32 offset = static_cast<u32>((t->m_TEX0.TBP0 - bp) * 256); const u32 offset = static_cast<u32>((t->m_TEX0.TBP0 - bp) * 256);
// This grossness is needed to fix incorrect invalidations in True Crime: New York City. if (rowsize > 0 && offset % rowsize == 0)
// Because it's writing tiny texture blocks (which are later decompressed) over previous targets,
// we need to be ensure said targets are invalidated, otherwise the SW prim render path won't be
// triggered. This whole thing needs rewriting anyway, because it can't handle non-page-aligned
// writes, but for now we'll just use the unsafer logic when the TC hack is enabled.
const bool start_of_page = rowsize > 0 && (offset % rowsize == 0);
if (start_of_page || (rowsize > 0 && GSConfig.UserHacks_CPUSpriteRenderBW != 0))
{ {
int y = GSLocalMemory::m_psm[psm].pgs.y * offset / rowsize; int y = GSLocalMemory::m_psm[psm].pgs.y * offset / rowsize;
if (r.bottom > y && (start_of_page || r.top >= y)) if (r.bottom > y)
{ {
GL_CACHE("TC: Dirty After Target(%s) %d (0x%x)", to_string(type), GL_CACHE("TC: Dirty After Target(%s) %d (0x%x)", to_string(type),
t->m_texture ? t->m_texture->GetID() : 0, t->m_texture ? t->m_texture->GetID() : 0,
@ -1410,7 +1407,7 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
continue; continue;
} }
} }
else if (GSConfig.UserHacks_TextureInsideRt && t->Overlaps(bp, bw, psm, rect) && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM)) else if (check_inside_target && t->Overlaps(bp, bw, psm, rect) && GSUtil::HasSharedBits(psm, t->m_TEX0.PSM))
{ {
SurfaceOffsetKey sok; SurfaceOffsetKey sok;
sok.elems[0].bp = bp; sok.elems[0].bp = bp;

View File

@ -347,6 +347,7 @@ static const char* s_gs_hw_fix_names[] = {
"wrapGSMem", "wrapGSMem",
"preloadFrameData", "preloadFrameData",
"disablePartialInvalidation", "disablePartialInvalidation",
"partialTargetInvalidation",
"textureInsideRT", "textureInsideRT",
"alignSprite", "alignSprite",
"mergeSprite", "mergeSprite",
@ -564,6 +565,9 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
case GSHWFixId::DisablePartialInvalidation: case GSHWFixId::DisablePartialInvalidation:
return (static_cast<int>(config.UserHacks_DisablePartialInvalidation) == value); return (static_cast<int>(config.UserHacks_DisablePartialInvalidation) == value);
case GSHWFixId::TargetPartialInvalidation:
return (static_cast<int>(config.UserHacks_TargetPartialInvalidation) == value);
case GSHWFixId::TextureInsideRT: case GSHWFixId::TextureInsideRT:
return (static_cast<int>(config.UserHacks_TextureInsideRt) == value); return (static_cast<int>(config.UserHacks_TextureInsideRt) == value);
@ -678,6 +682,10 @@ u32 GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
config.UserHacks_DisablePartialInvalidation = (value > 0); config.UserHacks_DisablePartialInvalidation = (value > 0);
break; break;
case GSHWFixId::TargetPartialInvalidation:
config.UserHacks_TargetPartialInvalidation = (value > 0);
break;
case GSHWFixId::TextureInsideRT: case GSHWFixId::TextureInsideRT:
config.UserHacks_TextureInsideRt = (value > 0); config.UserHacks_TextureInsideRt = (value > 0);
break; break;

View File

@ -67,6 +67,7 @@ namespace GameDatabaseSchema
WrapGSMem, WrapGSMem,
PreloadFrameData, PreloadFrameData,
DisablePartialInvalidation, DisablePartialInvalidation,
TargetPartialInvalidation,
TextureInsideRT, TextureInsideRT,
AlignSprite, AlignSprite,
MergeSprite, MergeSprite,

View File

@ -648,6 +648,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
GSSettingBoolEx(UserHacks_MergePPSprite, "UserHacks_merge_pp_sprite"); GSSettingBoolEx(UserHacks_MergePPSprite, "UserHacks_merge_pp_sprite");
GSSettingBoolEx(UserHacks_WildHack, "UserHacks_WildHack"); GSSettingBoolEx(UserHacks_WildHack, "UserHacks_WildHack");
GSSettingBoolEx(UserHacks_TextureInsideRt, "UserHacks_TextureInsideRt"); GSSettingBoolEx(UserHacks_TextureInsideRt, "UserHacks_TextureInsideRt");
GSSettingBoolEx(UserHacks_TargetPartialInvalidation, "UserHacks_TargetPartialInvalidation");
GSSettingBoolEx(FXAA, "fxaa"); GSSettingBoolEx(FXAA, "fxaa");
GSSettingBool(ShadeBoost); GSSettingBool(ShadeBoost);
GSSettingBoolEx(DumpGSData, "dump"); GSSettingBoolEx(DumpGSData, "dump");
@ -774,6 +775,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
UserHacks_CPUFBConversion = false; UserHacks_CPUFBConversion = false;
UserHacks_ReadTCOnClose = false; UserHacks_ReadTCOnClose = false;
UserHacks_TextureInsideRt = false; UserHacks_TextureInsideRt = false;
UserHacks_TargetPartialInvalidation = false;
UserHacks_TCOffsetX = 0; UserHacks_TCOffsetX = 0;
UserHacks_TCOffsetY = 0; UserHacks_TCOffsetY = 0;
UserHacks_CPUSpriteRenderBW = 0; UserHacks_CPUSpriteRenderBW = 0;