mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-03 19:42:45 +01:00
Merge pull request #336 from magumagu/xfb-vertical-scale
XFB width/height handling fixes
This commit is contained in:
commit
edbf90f9d2
@ -39,13 +39,13 @@ static u16 m_VBeamPos = 0; // 0: Inactive
|
|||||||
static u16 m_HBeamPos = 0; // 0: Inactive
|
static u16 m_HBeamPos = 0; // 0: Inactive
|
||||||
static UVIInterruptRegister m_InterruptRegister[4];
|
static UVIInterruptRegister m_InterruptRegister[4];
|
||||||
static UVILatchRegister m_LatchRegister[2];
|
static UVILatchRegister m_LatchRegister[2];
|
||||||
static UVIHorizontalStepping m_HorizontalStepping;
|
static PictureConfigurationRegister m_PictureConfiguration;
|
||||||
static UVIHorizontalScaling m_HorizontalScaling;
|
static UVIHorizontalScaling m_HorizontalScaling;
|
||||||
static SVIFilterCoefTables m_FilterCoefTables;
|
static SVIFilterCoefTables m_FilterCoefTables;
|
||||||
static u32 m_UnkAARegister = 0;// ??? 0x00FF0000
|
static u32 m_UnkAARegister = 0;// ??? 0x00FF0000
|
||||||
static u16 m_Clock = 0; // 0: 27MHz, 1: 54MHz
|
static u16 m_Clock = 0; // 0: 27MHz, 1: 54MHz
|
||||||
static UVIDTVStatus m_DTVStatus;
|
static UVIDTVStatus m_DTVStatus;
|
||||||
static u16 m_FBWidth = 0; // Only correct when scaling is enabled?
|
static UVIHorizontalStepping m_FBWidth; // Only correct when scaling is enabled?
|
||||||
static UVIBorderBlankRegister m_BorderHBlank;
|
static UVIBorderBlankRegister m_BorderHBlank;
|
||||||
// 0xcc002076 - 0xcc00207f is full of 0x00FF: unknown
|
// 0xcc002076 - 0xcc00207f is full of 0x00FF: unknown
|
||||||
// 0xcc002080 - 0xcc002100 even more unknown
|
// 0xcc002080 - 0xcc002100 even more unknown
|
||||||
@ -76,7 +76,7 @@ void DoState(PointerWrap &p)
|
|||||||
p.Do(m_HBeamPos);
|
p.Do(m_HBeamPos);
|
||||||
p.DoArray(m_InterruptRegister, 4);
|
p.DoArray(m_InterruptRegister, 4);
|
||||||
p.DoArray(m_LatchRegister, 2);
|
p.DoArray(m_LatchRegister, 2);
|
||||||
p.Do(m_HorizontalStepping);
|
p.Do(m_PictureConfiguration);
|
||||||
p.DoPOD(m_HorizontalScaling);
|
p.DoPOD(m_HorizontalScaling);
|
||||||
p.Do(m_FilterCoefTables);
|
p.Do(m_FilterCoefTables);
|
||||||
p.Do(m_UnkAARegister);
|
p.Do(m_UnkAARegister);
|
||||||
@ -129,8 +129,8 @@ void Preset(bool _bNTSC)
|
|||||||
m_InterruptRegister[1].IR_MASK = 1;
|
m_InterruptRegister[1].IR_MASK = 1;
|
||||||
m_InterruptRegister[1].IR_INT = 0;
|
m_InterruptRegister[1].IR_INT = 0;
|
||||||
|
|
||||||
m_HorizontalStepping.FbSteps = 40;
|
m_PictureConfiguration.STD = 40;
|
||||||
m_HorizontalStepping.FieldSteps = 40;
|
m_PictureConfiguration.WPL = 40;
|
||||||
|
|
||||||
m_HBeamPos = -1; // NTSC-U N64 VC games check for a non-zero HBeamPos
|
m_HBeamPos = -1; // NTSC-U N64 VC games check for a non-zero HBeamPos
|
||||||
m_VBeamPos = 0; // RG4JC0 checks for a zero VBeamPos
|
m_VBeamPos = 0; // RG4JC0 checks for a zero VBeamPos
|
||||||
@ -160,12 +160,12 @@ void Init()
|
|||||||
m_3DFBInfoBottom.Hex = 0;
|
m_3DFBInfoBottom.Hex = 0;
|
||||||
m_VBeamPos = 0;
|
m_VBeamPos = 0;
|
||||||
m_HBeamPos = 0;
|
m_HBeamPos = 0;
|
||||||
m_HorizontalStepping.Hex = 0;
|
m_PictureConfiguration.Hex = 0;
|
||||||
m_HorizontalScaling.Hex = 0;
|
m_HorizontalScaling.Hex = 0;
|
||||||
m_UnkAARegister = 0;
|
m_UnkAARegister = 0;
|
||||||
m_Clock = 0;
|
m_Clock = 0;
|
||||||
m_DTVStatus.Hex = 0;
|
m_DTVStatus.Hex = 0;
|
||||||
m_FBWidth = 0;
|
m_FBWidth.Hex = 0;
|
||||||
m_BorderHBlank.Hex = 0;
|
m_BorderHBlank.Hex = 0;
|
||||||
memset(&m_FilterCoefTables, 0, sizeof(m_FilterCoefTables));
|
memset(&m_FilterCoefTables, 0, sizeof(m_FilterCoefTables));
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
{ VI_DISPLAY_LATCH_0_LO, &m_LatchRegister[0].Lo },
|
{ VI_DISPLAY_LATCH_0_LO, &m_LatchRegister[0].Lo },
|
||||||
{ VI_DISPLAY_LATCH_1_HI, &m_LatchRegister[1].Hi },
|
{ VI_DISPLAY_LATCH_1_HI, &m_LatchRegister[1].Hi },
|
||||||
{ VI_DISPLAY_LATCH_1_LO, &m_LatchRegister[1].Lo },
|
{ VI_DISPLAY_LATCH_1_LO, &m_LatchRegister[1].Lo },
|
||||||
{ VI_HSCALEW, &m_HorizontalStepping.Hex },
|
{ VI_HSCALEW, &m_PictureConfiguration.Hex },
|
||||||
{ VI_HSCALER, &m_HorizontalScaling.Hex },
|
{ VI_HSCALER, &m_HorizontalScaling.Hex },
|
||||||
{ VI_FILTER_COEF_0_HI, &m_FilterCoefTables.Tables02[0].Hi },
|
{ VI_FILTER_COEF_0_HI, &m_FilterCoefTables.Tables02[0].Hi },
|
||||||
{ VI_FILTER_COEF_0_LO, &m_FilterCoefTables.Tables02[0].Lo },
|
{ VI_FILTER_COEF_0_LO, &m_FilterCoefTables.Tables02[0].Lo },
|
||||||
@ -236,7 +236,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
{ VI_FILTER_COEF_6_LO, &m_FilterCoefTables.Tables36[3].Lo },
|
{ VI_FILTER_COEF_6_LO, &m_FilterCoefTables.Tables36[3].Lo },
|
||||||
{ VI_CLOCK, &m_Clock },
|
{ VI_CLOCK, &m_Clock },
|
||||||
{ VI_DTV_STATUS, &m_DTVStatus.Hex },
|
{ VI_DTV_STATUS, &m_DTVStatus.Hex },
|
||||||
{ VI_FBWIDTH, &m_FBWidth },
|
{ VI_FBWIDTH, &m_FBWidth.Hex },
|
||||||
{ VI_BORDER_BLANK_END, &m_BorderHBlank.Lo },
|
{ VI_BORDER_BLANK_END, &m_BorderHBlank.Lo },
|
||||||
{ VI_BORDER_BLANK_START, &m_BorderHBlank.Hi },
|
{ VI_BORDER_BLANK_START, &m_BorderHBlank.Hi },
|
||||||
};
|
};
|
||||||
@ -505,8 +505,18 @@ unsigned int GetTicksPerFrame()
|
|||||||
|
|
||||||
static void BeginField(FieldType field)
|
static void BeginField(FieldType field)
|
||||||
{
|
{
|
||||||
u32 fbWidth = m_HorizontalStepping.FieldSteps * 16;
|
// TODO: the stride and height shouldn't depend on whether the FieldType is
|
||||||
u32 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
|
// "progressive". We're actually telling the video backend to draw unspecified
|
||||||
|
// junk. Due to the way XFB copies work, the unspecified junk is usually
|
||||||
|
// the contents of the other field, so it looks okay in most cases, but we
|
||||||
|
// shouldn't depend on that; a good example of where our output is wrong is
|
||||||
|
// the title screen teaser videos in Metroid Prime.
|
||||||
|
//
|
||||||
|
// What should actually happen is that we should pass on the correct width,
|
||||||
|
// stride, and height to the video backend, and it should deinterlace the
|
||||||
|
// output when appropriate.
|
||||||
|
u32 fbWidth = m_PictureConfiguration.STD * (field == FIELD_PROGRESSIVE ? 16 : 8);
|
||||||
|
u32 fbHeight = m_VerticalTimingRegister.ACV * (field == FIELD_PROGRESSIVE ? 1 : 2);
|
||||||
u32 xfbAddr;
|
u32 xfbAddr;
|
||||||
|
|
||||||
// NTSC and PAL have opposite field orders.
|
// NTSC and PAL have opposite field orders.
|
||||||
@ -535,8 +545,8 @@ static void BeginField(FieldType field)
|
|||||||
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };
|
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };
|
||||||
|
|
||||||
DEBUG_LOG(VIDEOINTERFACE,
|
DEBUG_LOG(VIDEOINTERFACE,
|
||||||
"(VI->BeginField): Address: %.08X | FieldSteps %u | FbSteps %u | ACV %u | Field %s",
|
"(VI->BeginField): Address: %.08X | WPL %u | STD %u | ACV %u | Field %s",
|
||||||
xfbAddr, m_HorizontalStepping.FieldSteps,m_HorizontalStepping.FbSteps,
|
xfbAddr, m_PictureConfiguration.WPL, m_PictureConfiguration.STD,
|
||||||
m_VerticalTimingRegister.ACV, fieldTypeNames[field]);
|
m_VerticalTimingRegister.ACV, fieldTypeNames[field]);
|
||||||
|
|
||||||
if (xfbAddr)
|
if (xfbAddr)
|
||||||
|
@ -135,8 +135,8 @@ union UVIHorizontalTiming0
|
|||||||
struct { u16 Lo, Hi; };
|
struct { u16 Lo, Hi; };
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u32 HLW : 9; // Halfline Width (W*16 = Width (720))
|
u32 HLW : 10; // Halfline Width (W*16 = Width (720))
|
||||||
u32 : 7;
|
u32 : 6;
|
||||||
u32 HCE : 7; // Horizontal Sync Start to Color Burst End
|
u32 HCE : 7; // Horizontal Sync Start to Color Burst End
|
||||||
u32 : 1;
|
u32 : 1;
|
||||||
u32 HCS : 7; // Horizontal Sync Start to Color Burst Start
|
u32 HCS : 7; // Horizontal Sync Start to Color Burst Start
|
||||||
@ -151,10 +151,9 @@ union UVIHorizontalTiming1
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u32 HSY : 7; // Horizontal Sync Width
|
u32 HSY : 7; // Horizontal Sync Width
|
||||||
u32 HBE640 : 9; // Horizontal Sync Start to horizontal blank end
|
u32 HBE640 : 10; // Horizontal Sync Start to horizontal blank end
|
||||||
u32 : 1;
|
u32 HBS640 : 10; // Half line to horizontal blanking start
|
||||||
u32 HBS640 : 9; // Half line to horizontal blanking start
|
u32 : 5;
|
||||||
u32 : 6;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -232,13 +231,14 @@ union UVILatchRegister
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
union UVIHorizontalStepping
|
union PictureConfigurationRegister
|
||||||
{
|
{
|
||||||
u16 Hex;
|
u16 Hex;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u16 FbSteps : 8;
|
u16 STD : 8;
|
||||||
u16 FieldSteps : 8;
|
u16 WPL : 7;
|
||||||
|
u16 : 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -316,6 +316,16 @@ union UVIDTVStatus
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union UVIHorizontalStepping
|
||||||
|
{
|
||||||
|
u16 Hex;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u16 srcwidth : 10;
|
||||||
|
u16 : 6;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// urgh, ugly externs.
|
// urgh, ugly externs.
|
||||||
extern u32 TargetRefreshRate;
|
extern u32 TargetRefreshRate;
|
||||||
|
|
||||||
|
@ -46,6 +46,13 @@ const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr
|
|||||||
{
|
{
|
||||||
xfbCount = 1;
|
xfbCount = 1;
|
||||||
|
|
||||||
|
// recreate if needed
|
||||||
|
if (m_realXFBSource && (m_realXFBSource->texWidth != fbWidth || m_realXFBSource->texHeight != fbHeight))
|
||||||
|
{
|
||||||
|
delete m_realXFBSource;
|
||||||
|
m_realXFBSource = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_realXFBSource)
|
if (!m_realXFBSource)
|
||||||
m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight);
|
m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight);
|
||||||
|
|
||||||
@ -142,8 +149,8 @@ void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHe
|
|||||||
// recreate if needed
|
// recreate if needed
|
||||||
if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height))
|
if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height))
|
||||||
{
|
{
|
||||||
//delete vxfb->xfbSource;
|
delete vxfb->xfbSource;
|
||||||
//vxfb->xfbSource = nullptr;
|
vxfb->xfbSource = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vxfb->xfbSource)
|
if (!vxfb->xfbSource)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user