GPU: Fix more rotation-scaling bugs on big-endian systems.

This commit is contained in:
rogerman 2022-05-18 18:12:23 -07:00
parent 92aab4834b
commit a5860aae8e
3 changed files with 143 additions and 50 deletions

View File

@ -617,12 +617,7 @@ void GPUEngineBase::ParseReg_BGnHOFS()
{
const IOREG_BGnHOFS &BGnHOFS = this->_IORegisterMap->BGnOFS[LAYERID].BGnHOFS;
this->_BGLayer[LAYERID].BGnHOFS = BGnHOFS;
#ifdef MSB_FIRST
this->_BGLayer[LAYERID].xOffset = LOCAL_TO_LE_16(BGnHOFS.value) & 0x01FF;
#else
this->_BGLayer[LAYERID].xOffset = BGnHOFS.Offset;
#endif
this->_BGLayer[LAYERID].xOffset = BGnHOFS.value & 0x01FF;
}
template <GPULayerID LAYERID>
@ -630,12 +625,7 @@ void GPUEngineBase::ParseReg_BGnVOFS()
{
const IOREG_BGnVOFS &BGnVOFS = this->_IORegisterMap->BGnOFS[LAYERID].BGnVOFS;
this->_BGLayer[LAYERID].BGnVOFS = BGnVOFS;
#ifdef MSB_FIRST
this->_BGLayer[LAYERID].yOffset = LOCAL_TO_LE_16(BGnVOFS.value) & 0x01FF;
#else
this->_BGLayer[LAYERID].yOffset = BGnVOFS.Offset;
#endif
this->_BGLayer[LAYERID].yOffset = BGnVOFS.value & 0x01FF;
}
template <GPULayerID LAYERID>
@ -909,8 +899,8 @@ void GPUEngineBase::UpdatePropertiesWithoutRender(const u16 l)
{
IOREG_BG2Parameter &BG2Param = this->_IORegisterMap->BG2Param;
BG2Param.BG2X.value += LE_TO_LOCAL_16(BG2Param.BG2PB.value);
BG2Param.BG2Y.value += LE_TO_LOCAL_16(BG2Param.BG2PD.value);
BG2Param.BG2X.value += BG2Param.BG2PB.value;
BG2Param.BG2Y.value += BG2Param.BG2PD.value;
}
if ( this->_isBGLayerShown[GPULayerID_BG3] &&
@ -918,8 +908,8 @@ void GPUEngineBase::UpdatePropertiesWithoutRender(const u16 l)
{
IOREG_BG3Parameter &BG3Param = this->_IORegisterMap->BG3Param;
BG3Param.BG3X.value += LE_TO_LOCAL_16(BG3Param.BG3PB.value);
BG3Param.BG3Y.value += LE_TO_LOCAL_16(BG3Param.BG3PD.value);
BG3Param.BG3X.value += BG3Param.BG3PB.value;
BG3Param.BG3Y.value += BG3Param.BG3PD.value;
}
}
@ -1168,8 +1158,8 @@ void GPUEngineBase::_RenderPixelIterate_Final(GPUEngineCompositorInfo &compInfo,
}
}
const s16 dx = (s16)LOCAL_TO_LE_16(param.BGnPA.value);
const s16 dy = (s16)LOCAL_TO_LE_16(param.BGnPC.value);
const s16 dx = param.BGnPA.value;
const s16 dy = param.BGnPC.value;
for (size_t i = 0; i < lineWidth; i++, x.value+=dx, y.value+=dy)
{
@ -1655,10 +1645,12 @@ void GPUEngineBase::_RenderLine_BGExtended(GPUEngineCompositorInfo &compInfo, co
if (!MOSAIC)
{
const bool isRotationScaled = ( (param.BGnPA.value != 0x100) ||
(param.BGnPC.value != 0) ||
(param.BGnX.value != 0) ||
(param.BGnY.value != (0x100 * (s32)compInfo.line.indexNative)) );
const bool isRotationScaled = ( (param.BGnPA.Integer != 1) ||
(param.BGnPA.Fraction != 0) ||
(param.BGnPC.value != 0) ||
(param.BGnX.value != 0) ||
(param.BGnY.Integer != (s32)compInfo.line.indexNative) ||
(param.BGnY.Fraction != 0) );
if (!isRotationScaled)
{
const size_t vramPixel = (size_t)((u8 *)MMU_gpu_map(compInfo.renderState.selectedBGLayer->BMPAddress) - MMU.ARM9_LCD) / sizeof(u16);
@ -1724,8 +1716,8 @@ void GPUEngineBase::_LineRot(GPUEngineCompositorInfo &compInfo)
IOREG_BGnParameter *__restrict bgParams = (compInfo.renderState.selectedLayerID == GPULayerID_BG2) ? (IOREG_BGnParameter *)&this->_IORegisterMap->BG2Param : (IOREG_BGnParameter *)&this->_IORegisterMap->BG3Param;
this->_RenderLine_BGAffine<COMPOSITORMODE, OUTPUTFORMAT, MOSAIC, WILLPERFORMWINDOWTEST, WILLDEFERCOMPOSITING>(compInfo, *bgParams);
bgParams->BGnX.value += LE_TO_LOCAL_16(bgParams->BGnPB.value);
bgParams->BGnY.value += LE_TO_LOCAL_16(bgParams->BGnPD.value);
bgParams->BGnX.value += bgParams->BGnPB.value;
bgParams->BGnY.value += bgParams->BGnPD.value;
}
}
@ -1742,8 +1734,8 @@ void GPUEngineBase::_LineExtRot(GPUEngineCompositorInfo &compInfo, bool &outUseC
IOREG_BGnParameter *__restrict bgParams = (compInfo.renderState.selectedLayerID == GPULayerID_BG2) ? (IOREG_BGnParameter *)&this->_IORegisterMap->BG2Param : (IOREG_BGnParameter *)&this->_IORegisterMap->BG3Param;
this->_RenderLine_BGExtended<COMPOSITORMODE, OUTPUTFORMAT, MOSAIC, WILLPERFORMWINDOWTEST, WILLDEFERCOMPOSITING>(compInfo, *bgParams, outUseCustomVRAM);
bgParams->BGnX.value += LE_TO_LOCAL_16(bgParams->BGnPB.value);
bgParams->BGnY.value += LE_TO_LOCAL_16(bgParams->BGnPD.value);
bgParams->BGnX.value += bgParams->BGnPB.value;
bgParams->BGnY.value += bgParams->BGnPD.value;
}
}

View File

@ -290,8 +290,13 @@ typedef union
struct
{
#ifndef MSB_FIRST
u16 Fraction:8;
s16 Integer:8;
#else
s16 Integer:8;
u16 Fraction:8;
#endif
};
} IOREG_BGnPA; // 0x400x020, 0x400x030: BGn rotation/scaling parameter A (Engine A+B)
typedef IOREG_BGnPA IOREG_BGnPB; // 0x400x022, 0x400x032: BGn rotation/scaling parameter B (Engine A+B)

View File

@ -3786,45 +3786,61 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
return;
case REG_DISPA_BG0HOFS:
T1WriteWord(MMU.ARM9_REG, 0x0010, val);
HostWriteWord(MMU.ARM9_REG, 0x0010, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG0>();
return;
case REG_DISPA_BG0VOFS:
T1WriteWord(MMU.ARM9_REG, 0x0012, val);
HostWriteWord(MMU.ARM9_REG, 0x0012, val);
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG0>();
return;
case REG_DISPA_BG1HOFS:
T1WriteWord(MMU.ARM9_REG, 0x0014, val);
HostWriteWord(MMU.ARM9_REG, 0x0014, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG1>();
return;
case REG_DISPA_BG1VOFS:
T1WriteWord(MMU.ARM9_REG, 0x0016, val);
HostWriteWord(MMU.ARM9_REG, 0x0016, val);
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG1>();
return;
case REG_DISPA_BG2HOFS:
T1WriteWord(MMU.ARM9_REG, 0x0018, val);
HostWriteWord(MMU.ARM9_REG, 0x0018, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG2>();
return;
case REG_DISPA_BG2VOFS:
T1WriteWord(MMU.ARM9_REG, 0x001A, val);
HostWriteWord(MMU.ARM9_REG, 0x001A, val);
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG2>();
return;
case REG_DISPA_BG3HOFS:
T1WriteWord(MMU.ARM9_REG, 0x001C, val);
HostWriteWord(MMU.ARM9_REG, 0x001C, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG3>();
return;
case REG_DISPA_BG3VOFS:
T1WriteWord(MMU.ARM9_REG, 0x001E, val);
HostWriteWord(MMU.ARM9_REG, 0x001E, val);
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG3>();
return;
case REG_DISPA_BG2PA:
HostWriteWord(MMU.ARM9_REG, 0x0020, val);
return;
case REG_DISPA_BG2PB:
HostWriteWord(MMU.ARM9_REG, 0x0022, val);
return;
case REG_DISPA_BG2PC:
HostWriteWord(MMU.ARM9_REG, 0x0024, val);
return;
case REG_DISPA_BG2PD:
HostWriteWord(MMU.ARM9_REG, 0x0026, val);
return;
case REG_DISPA_BG2XL:
HostWriteWord(MMU.ARM9_REG, 0x0028, val);
mainEngine->ParseReg_BGnX<GPULayerID_BG2>();
@ -3845,6 +3861,22 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
mainEngine->ParseReg_BGnY<GPULayerID_BG2>();
return;
case REG_DISPA_BG3PA:
HostWriteWord(MMU.ARM9_REG, 0x0030, val);
return;
case REG_DISPA_BG3PB:
HostWriteWord(MMU.ARM9_REG, 0x0032, val);
return;
case REG_DISPA_BG3PC:
HostWriteWord(MMU.ARM9_REG, 0x0034, val);
return;
case REG_DISPA_BG3PD:
HostWriteWord(MMU.ARM9_REG, 0x0036, val);
return;
case REG_DISPA_BG3XL:
HostWriteWord(MMU.ARM9_REG, 0x0038, val);
mainEngine->ParseReg_BGnX<GPULayerID_BG3>();
@ -3971,45 +4003,61 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
return;
case REG_DISPB_BG0HOFS:
T1WriteWord(MMU.ARM9_REG, 0x1010, val);
HostWriteWord(MMU.ARM9_REG, 0x1010, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG0>();
return;
case REG_DISPB_BG0VOFS:
T1WriteWord(MMU.ARM9_REG, 0x1012, val);
HostWriteWord(MMU.ARM9_REG, 0x1012, val);
subEngine->ParseReg_BGnVOFS<GPULayerID_BG0>();
return;
case REG_DISPB_BG1HOFS:
T1WriteWord(MMU.ARM9_REG, 0x1014, val);
HostWriteWord(MMU.ARM9_REG, 0x1014, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG1>();
return;
case REG_DISPB_BG1VOFS:
T1WriteWord(MMU.ARM9_REG, 0x1016, val);
HostWriteWord(MMU.ARM9_REG, 0x1016, val);
subEngine->ParseReg_BGnVOFS<GPULayerID_BG1>();
return;
case REG_DISPB_BG2HOFS:
T1WriteWord(MMU.ARM9_REG, 0x1018, val);
HostWriteWord(MMU.ARM9_REG, 0x1018, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG2>();
return;
case REG_DISPB_BG2VOFS:
T1WriteWord(MMU.ARM9_REG, 0x101A, val);
HostWriteWord(MMU.ARM9_REG, 0x101A, val);
subEngine->ParseReg_BGnVOFS<GPULayerID_BG2>();
return;
case REG_DISPB_BG3HOFS:
T1WriteWord(MMU.ARM9_REG, 0x101C, val);
HostWriteWord(MMU.ARM9_REG, 0x101C, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG3>();
return;
case REG_DISPB_BG3VOFS:
T1WriteWord(MMU.ARM9_REG, 0x101E, val);
HostWriteWord(MMU.ARM9_REG, 0x101E, val);
subEngine->ParseReg_BGnVOFS<GPULayerID_BG3>();
return;
case REG_DISPB_BG2PA:
HostWriteWord(MMU.ARM9_REG, 0x1020, val);
return;
case REG_DISPB_BG2PB:
HostWriteWord(MMU.ARM9_REG, 0x1022, val);
return;
case REG_DISPB_BG2PC:
HostWriteWord(MMU.ARM9_REG, 0x1024, val);
return;
case REG_DISPB_BG2PD:
HostWriteWord(MMU.ARM9_REG, 0x1026, val);
return;
case REG_DISPB_BG2XL:
HostWriteWord(MMU.ARM9_REG, 0x1028, val);
subEngine->ParseReg_BGnX<GPULayerID_BG2>();
@ -4030,6 +4078,22 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
subEngine->ParseReg_BGnY<GPULayerID_BG2>();
return;
case REG_DISPB_BG3PA:
HostWriteWord(MMU.ARM9_REG, 0x1030, val);
return;
case REG_DISPB_BG3PB:
HostWriteWord(MMU.ARM9_REG, 0x1032, val);
return;
case REG_DISPB_BG3PC:
HostWriteWord(MMU.ARM9_REG, 0x1034, val);
return;
case REG_DISPB_BG3PD:
HostWriteWord(MMU.ARM9_REG, 0x1036, val);
return;
case REG_DISPB_BG3XL:
HostWriteWord(MMU.ARM9_REG, 0x1038, val);
subEngine->ParseReg_BGnX<GPULayerID_BG3>();
@ -4405,29 +4469,37 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
return;
case REG_DISPA_BG0HOFS:
T1WriteLong(MMU.ARM9_REG, 0x0010, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x0010, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG0>();
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG0>();
return;
case REG_DISPA_BG1HOFS:
T1WriteLong(MMU.ARM9_REG, 0x0014, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x0014, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG1>();
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG1>();
return;
case REG_DISPA_BG2HOFS:
T1WriteLong(MMU.ARM9_REG, 0x0018, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x0018, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG2>();
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG2>();
return;
case REG_DISPA_BG3HOFS:
T1WriteLong(MMU.ARM9_REG, 0x001C, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x001C, val);
mainEngine->ParseReg_BGnHOFS<GPULayerID_BG3>();
mainEngine->ParseReg_BGnVOFS<GPULayerID_BG3>();
return;
case REG_DISPA_BG2PA:
HostWriteTwoWords(MMU.ARM9_REG, 0x0020, val);
return;
case REG_DISPA_BG2PC:
HostWriteTwoWords(MMU.ARM9_REG, 0x0024, val);
return;
case REG_DISPA_BG2XL:
HostWriteLong(MMU.ARM9_REG, 0x0028, val);
mainEngine->ParseReg_BGnX<GPULayerID_BG2>();
@ -4438,6 +4510,14 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
mainEngine->ParseReg_BGnY<GPULayerID_BG2>();
return;
case REG_DISPA_BG3PA:
HostWriteTwoWords(MMU.ARM9_REG, 0x0030, val);
return;
case REG_DISPA_BG3PC:
HostWriteTwoWords(MMU.ARM9_REG, 0x0034, val);
return;
case REG_DISPA_BG3XL:
HostWriteLong(MMU.ARM9_REG, 0x0038, val);
mainEngine->ParseReg_BGnX<GPULayerID_BG3>();
@ -4518,29 +4598,37 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
return;
case REG_DISPB_BG0HOFS:
T1WriteLong(MMU.ARM9_REG, 0x1010, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x1010, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG0>();
subEngine->ParseReg_BGnVOFS<GPULayerID_BG0>();
return;
case REG_DISPB_BG1HOFS:
T1WriteLong(MMU.ARM9_REG, 0x1014, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x1014, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG1>();
subEngine->ParseReg_BGnVOFS<GPULayerID_BG1>();
return;
case REG_DISPB_BG2HOFS:
T1WriteLong(MMU.ARM9_REG, 0x1018, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x1018, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG2>();
subEngine->ParseReg_BGnVOFS<GPULayerID_BG2>();
return;
case REG_DISPB_BG3HOFS:
T1WriteLong(MMU.ARM9_REG, 0x101C, val);
HostWriteTwoWords(MMU.ARM9_REG, 0x101C, val);
subEngine->ParseReg_BGnHOFS<GPULayerID_BG3>();
subEngine->ParseReg_BGnVOFS<GPULayerID_BG3>();
return;
case REG_DISPB_BG2PA:
HostWriteTwoWords(MMU.ARM9_REG, 0x1020, val);
return;
case REG_DISPB_BG2PC:
HostWriteTwoWords(MMU.ARM9_REG, 0x1024, val);
return;
case REG_DISPB_BG2XL:
HostWriteLong(MMU.ARM9_REG, 0x1028, val);
subEngine->ParseReg_BGnX<GPULayerID_BG2>();
@ -4551,6 +4639,14 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
subEngine->ParseReg_BGnY<GPULayerID_BG2>();
return;
case REG_DISPB_BG3PA:
HostWriteTwoWords(MMU.ARM9_REG, 0x1030, val);
return;
case REG_DISPB_BG3PC:
HostWriteTwoWords(MMU.ARM9_REG, 0x1034, val);
return;
case REG_DISPB_BG3XL:
HostWriteLong(MMU.ARM9_REG, 0x1038, val);
subEngine->ParseReg_BGnX<GPULayerID_BG3>();