mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-12 02:08:45 +00:00
GS: Improve PCRTC offset wrapping and simplify some deinterlacing
This commit is contained in:
committed by
lightningterror
parent
4e1975ec80
commit
4e6b6904cb
@@ -27852,8 +27852,6 @@ SLES-54812:
|
||||
SLES-54813:
|
||||
name: "NASCAR 08"
|
||||
region: "PAL-A-E"
|
||||
gsHWFixes:
|
||||
deinterlace: 8 # Game requires AdaptiveTFF de-interlacing when auto.
|
||||
SLES-54814:
|
||||
name: "Dead Eye Jim"
|
||||
region: "PAL-E"
|
||||
@@ -29206,8 +29204,6 @@ SLES-55199:
|
||||
name: "NASCAR 09"
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
deinterlace: 8 # Game requires AdaptiveTFF de-interlacing when auto.
|
||||
SLES-55200:
|
||||
name: "Guitar Hero - Aerosmith"
|
||||
region: "PAL-M4"
|
||||
@@ -66483,7 +66479,6 @@ SLUS-20535:
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fix horizontal and vertical lines when racing.
|
||||
deinterlace: 8 # Fixes misdetection of game deinterlace.
|
||||
SLUS-20536:
|
||||
name: "NBA Live 2003"
|
||||
region: "NTSC-U"
|
||||
@@ -67683,7 +67678,6 @@ SLUS-20754:
|
||||
region: "NTSC-U"
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fix horizontal and vertical lines when racing.
|
||||
deinterlace: 8 # Fixes misdetection of game deinterlace.
|
||||
memcardFilters:
|
||||
- "PSCD10088" # Enables EA Sports BIO.
|
||||
- "SLUS-20754"
|
||||
@@ -68048,7 +68042,6 @@ SLUS-20824:
|
||||
region: "NTSC-U"
|
||||
gsHWFixes:
|
||||
roundSprite: 1 # Fix horizontal and vertical lines when racing.
|
||||
deinterlace: 8 # Fixes misdetection of game deinterlace.
|
||||
memcardFilters:
|
||||
- "PSCD10088" # Enables EA Sports BIO.
|
||||
- "SLUS-20824"
|
||||
@@ -73096,8 +73089,6 @@ SLUS-21639:
|
||||
name: "NASCAR 08"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
deinterlace: 8 # Game requires AdaptiveTFF de-interlacing when auto.
|
||||
SLUS-21640:
|
||||
name: "Rugby 08"
|
||||
region: "NTSC-U"
|
||||
@@ -73665,8 +73656,6 @@ SLUS-21744:
|
||||
name: "NASCAR 09"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
deinterlace: 8 # Game requires AdaptiveTFF de-interlacing when auto.
|
||||
patches:
|
||||
1B6C22B9:
|
||||
content: |-
|
||||
|
||||
+1
-1
@@ -442,7 +442,7 @@ void GSvsync(u32 field, bool registers_written)
|
||||
g_gs_renderer->PCRTCDisplays.SetRects(0, g_gs_renderer->m_regs->DISP[0].DISPLAY, g_gs_renderer->m_regs->DISP[0].DISPFB);
|
||||
g_gs_renderer->PCRTCDisplays.SetRects(1, g_gs_renderer->m_regs->DISP[1].DISPLAY, g_gs_renderer->m_regs->DISP[1].DISPFB);
|
||||
g_gs_renderer->PCRTCDisplays.CalculateDisplayOffset(g_gs_renderer->m_scanmask_used);
|
||||
g_gs_renderer->PCRTCDisplays.CalculateFramebufferOffset(g_gs_renderer->m_scanmask_used);
|
||||
g_gs_renderer->PCRTCDisplays.CalculateFramebufferOffset(g_gs_renderer->m_scanmask_used, g_gs_renderer->m_regs->DISP[0].DISPFB, g_gs_renderer->m_regs->DISP[1].DISPFB);
|
||||
|
||||
// Do not move the flush into the VSync() method. It's here because EE transfers
|
||||
// get cleared in HW VSync, and may be needed for a buffered draw (FFX FMVs).
|
||||
|
||||
+41
-35
@@ -5961,44 +5961,36 @@ void GSState::GSPCRTCRegs::SetRects(int display, GSRegDISPLAY displayReg, GSRegD
|
||||
|
||||
// Calculate framebuffer read offsets, should be considered if only one circuit is enabled, or difference is more than 1 line.
|
||||
// Only considered if "Anti-blur" is enabled.
|
||||
void GSState::GSPCRTCRegs::CalculateFramebufferOffset(bool scanmask)
|
||||
void GSState::GSPCRTCRegs::CalculateFramebufferOffset(bool scanmask, GSRegDISPFB framebuffer0Reg, GSRegDISPFB framebuffer1Reg)
|
||||
{
|
||||
GSVector2i fb0 = GSVector2i(PCRTCDisplays[0].framebufferOffsets.x, PCRTCDisplays[0].framebufferOffsets.y);
|
||||
GSVector2i fb1 = GSVector2i(PCRTCDisplays[1].framebufferOffsets.x, PCRTCDisplays[1].framebufferOffsets.y);
|
||||
|
||||
if (fb0.x + PCRTCDisplays[0].displayRect.z > 2048)
|
||||
{
|
||||
fb0.x -= 2048;
|
||||
PCRTCDisplays[0].framebufferOffsets.x = fb0.x;
|
||||
}
|
||||
if (fb0.y + PCRTCDisplays[0].displayRect.w > 2048)
|
||||
{
|
||||
fb0.y -= 2048;
|
||||
PCRTCDisplays[0].framebufferOffsets.y = fb0.y;
|
||||
}
|
||||
if (fb1.x + PCRTCDisplays[1].displayRect.z > 2048)
|
||||
{
|
||||
fb1.x -= 2048;
|
||||
PCRTCDisplays[1].framebufferOffsets.x = fb1.x;
|
||||
}
|
||||
if (fb1.y + PCRTCDisplays[1].displayRect.w > 2048)
|
||||
{
|
||||
fb1.y -= 2048;
|
||||
PCRTCDisplays[1].framebufferOffsets.y = fb1.y;
|
||||
}
|
||||
|
||||
if (GSConfig.PCRTCAntiBlur && PCRTCSameSrc && !scanmask)
|
||||
{
|
||||
GSVector2i fb0 = GSVector2i(PCRTCDisplays[0].framebufferOffsets.x, PCRTCDisplays[0].framebufferOffsets.y);
|
||||
GSVector2i fb1 = GSVector2i(PCRTCDisplays[1].framebufferOffsets.x, PCRTCDisplays[1].framebufferOffsets.y);
|
||||
|
||||
if (fb0.x + PCRTCDisplays[0].displayRect.z > 2048)
|
||||
{
|
||||
fb0.x -= 2048;
|
||||
fb0.x = abs(fb0.x);
|
||||
}
|
||||
if (fb0.y + PCRTCDisplays[0].displayRect.w > 2048)
|
||||
{
|
||||
fb0.y -= 2048;
|
||||
fb0.y = abs(fb0.y);
|
||||
}
|
||||
if (fb1.x + PCRTCDisplays[1].displayRect.z > 2048)
|
||||
{
|
||||
fb1.x -= 2048;
|
||||
fb1.x = abs(fb1.x);
|
||||
}
|
||||
if (fb1.y + PCRTCDisplays[1].displayRect.w > 2048)
|
||||
{
|
||||
fb1.y -= 2048;
|
||||
fb1.y = abs(fb1.y);
|
||||
}
|
||||
|
||||
if (abs(fb1.y - fb0.y) == 1
|
||||
&& PCRTCDisplays[0].displayRect.y == PCRTCDisplays[1].displayRect.y)
|
||||
{
|
||||
if (fb1.y < fb0.y)
|
||||
PCRTCDisplays[0].framebufferOffsets.y = fb1.y;
|
||||
else
|
||||
PCRTCDisplays[1].framebufferOffsets.y = fb0.y;
|
||||
}
|
||||
if (abs(fb1.x - fb0.x) == 1
|
||||
&& PCRTCDisplays[0].displayRect.x == PCRTCDisplays[1].displayRect.x)
|
||||
|
||||
if (abs(fb1.x - fb0.x) == 1 && PCRTCDisplays[0].displayRect.x == PCRTCDisplays[1].displayRect.x)
|
||||
{
|
||||
if (fb1.x < fb0.x)
|
||||
PCRTCDisplays[0].framebufferOffsets.x = fb1.x;
|
||||
@@ -6015,6 +6007,20 @@ void GSState::GSPCRTCRegs::CalculateFramebufferOffset(bool scanmask)
|
||||
PCRTCDisplays[1].framebufferRect.z += PCRTCDisplays[1].framebufferOffsets.x;
|
||||
PCRTCDisplays[1].framebufferRect.y += PCRTCDisplays[1].framebufferOffsets.y;
|
||||
PCRTCDisplays[1].framebufferRect.w += PCRTCDisplays[1].framebufferOffsets.y;
|
||||
|
||||
if (GSConfig.PCRTCAntiBlur && PCRTCSameSrc && !scanmask && abs(fb1.y - fb0.y) <= 1)
|
||||
{
|
||||
if (framebuffer0Reg.DBY != PCRTCDisplays[0].prevFramebufferReg.DBY)
|
||||
{
|
||||
PCRTCDisplays[0].framebufferRect.y = PCRTCDisplays[1].framebufferRect.y;
|
||||
PCRTCDisplays[0].framebufferRect.w = PCRTCDisplays[1].framebufferRect.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
PCRTCDisplays[1].framebufferRect.y = PCRTCDisplays[0].framebufferRect.y;
|
||||
PCRTCDisplays[1].framebufferRect.w = PCRTCDisplays[0].framebufferRect.w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used in software mode to align the buffer when reading. Offset is accounted for (block aligned) by GetOutput.
|
||||
|
||||
+1
-1
@@ -408,7 +408,7 @@ public:
|
||||
|
||||
// Calculate framebuffer read offsets, should be considered if only one circuit is enabled, or difference is more than 1 line.
|
||||
// Only considered if "Anti-blur" is enabled.
|
||||
void CalculateFramebufferOffset(bool scanmask);
|
||||
void CalculateFramebufferOffset(bool scanmask, GSRegDISPFB framebuffer0Reg, GSRegDISPFB framebuffer1Reg);
|
||||
|
||||
// Used in software mode to align the buffer when reading. Offset is accounted for (block aligned) by GetOutput.
|
||||
void RemoveFramebufferOffset(int display);
|
||||
|
||||
@@ -94,8 +94,8 @@ bool GSRenderer::Merge(int field)
|
||||
}
|
||||
|
||||
// Need to do this here, if the user has Anti-Blur enabled, these offsets can get wiped out/changed.
|
||||
const bool game_deinterlacing = (m_regs->DISP[0].DISPFB.DBY != PCRTCDisplays.PCRTCDisplays[0].prevFramebufferReg.DBY) !=
|
||||
(m_regs->DISP[1].DISPFB.DBY != PCRTCDisplays.PCRTCDisplays[1].prevFramebufferReg.DBY);
|
||||
const bool game_deinterlacing = (PCRTCDisplays.PCRTCDisplays[0].prevFramebufferOffsets.y != PCRTCDisplays.PCRTCDisplays[0].framebufferOffsets.y) !=
|
||||
(PCRTCDisplays.PCRTCDisplays[1].prevFramebufferOffsets.y != PCRTCDisplays.PCRTCDisplays[1].framebufferOffsets.y);
|
||||
|
||||
// Only need to check the right/bottom on software renderer, hardware always gets the full texture then cuts a bit out later.
|
||||
if (PCRTCDisplays.FrameRectMatch() && !PCRTCDisplays.FrameWrap() && !feedback_merge)
|
||||
@@ -156,19 +156,10 @@ bool GSRenderer::Merge(int field)
|
||||
bool is_bob = GSConfig.InterlaceMode == GSInterlaceMode::BobTFF || GSConfig.InterlaceMode == GSInterlaceMode::BobBFF;
|
||||
|
||||
// FFMD (half frames) requires blend deinterlacing, so automatically use that. Same when SCANMSK is used but not blended in the merge circuit (Alpine Racer 3).
|
||||
if (GSConfig.InterlaceMode != GSInterlaceMode::Automatic || (!m_regs->SMODE2.FFMD && !scanmask_frame))
|
||||
if (GSConfig.InterlaceMode != GSInterlaceMode::Automatic || (!game_deinterlacing && !m_regs->SMODE2.FFMD && !scanmask_frame))
|
||||
{
|
||||
// If the game is offsetting each frame itself and we're using full height buffers, we can offset this with Bob.
|
||||
if (game_deinterlacing && !scanmask_frame && GSConfig.InterlaceMode == GSInterlaceMode::Automatic)
|
||||
{
|
||||
mode = 1; // Bob.
|
||||
is_bob = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
field2 = ((static_cast<int>(GSConfig.InterlaceMode) - 2) & 1);
|
||||
mode = ((static_cast<int>(GSConfig.InterlaceMode) - 2) >> 1);
|
||||
}
|
||||
field2 = ((static_cast<int>(GSConfig.InterlaceMode) - 2) & 1);
|
||||
mode = ((static_cast<int>(GSConfig.InterlaceMode) - 2) >> 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
|
||||
Reference in New Issue
Block a user