- Fix crashing bug that can occur if BMPAddress maps into the custom VRAM blank region. (Regression from r5366.)
- Fix bug where a 128-width display capture would actually perform a 256-width capture in custom VRAM. (Regression from r5243.)
- Fix bug where if the display mode is Off or MainMemory, then the destination buffer may not always be the native buffer.
- Remove VRAM display mode’s dependence on the isCustomRenderingNeeded flag.
This commit is contained in:
rogerman 2016-02-24 21:09:47 +00:00
parent ee5fcf6bd2
commit dcb2c5fa05
2 changed files with 31 additions and 13 deletions

View File

@ -4155,7 +4155,7 @@ void GPUEngineA::RenderLine(const u16 l)
switch (displayMode)
{
case GPUDisplayMode_Off: // Display Off(Display white)
this->_HandleDisplayModeOff(dstColorLine);
this->_HandleDisplayModeOff(this->nativeBuffer + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH));
break;
case GPUDisplayMode_Normal: // Display BG and OBJ layers
@ -4163,11 +4163,11 @@ void GPUEngineA::RenderLine(const u16 l)
break;
case GPUDisplayMode_VRAM: // Display vram framebuffer
this->_HandleDisplayModeVRAM<ISCUSTOMRENDERINGNEEDED>(dstColorLine, l, dstLineWidth, dstLineCount);
this->_HandleDisplayModeVRAM(dstColorLine, l, dstLineWidth, dstLineCount);
break;
case GPUDisplayMode_MainMemory: // Display memory FIFO
this->_HandleDisplayModeMainMemory(dstColorLine);
this->_HandleDisplayModeMainMemory(this->nativeBuffer + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH));
break;
}
@ -4547,7 +4547,7 @@ void GPUEngineA::_RenderLine_DisplayCapture(u16 *dstColorLine, const u16 l)
if (DIDCUSTOMRENDER)
{
const size_t captureLengthExt = (CAPTURELENGTH) ? dispInfo.customWidth : dispInfo.customWidth / 2;
const size_t captureLengthExt = (CAPTURELENGTH == GPU_FRAMEBUFFER_NATIVE_WIDTH) ? dispInfo.customWidth : dispInfo.customWidth / 2;
const size_t captureLineCount = _gpuDstLineCount[l];
size_t cap_dst_adr_ext = (DISPCAPCNT.VRAMWriteOffset * _gpuCaptureLineIndex[64] * dispInfo.customWidth) + (_gpuCaptureLineIndex[l] * captureLengthExt);
@ -4938,10 +4938,9 @@ void GPUEngineA::_RenderLine_DispCapture_Blend(const u16 *srcA, const u16 *srcB,
}
}
template<bool ISCUSTOMRENDERINGNEEDED>
void GPUEngineA::_HandleDisplayModeVRAM(u16 *__restrict dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount)
{
if (!ISCUSTOMRENDERINGNEEDED)
if (!this->isCustomOutputSize)
{
const u16 *__restrict src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH);
#ifdef LOCAL_LE
@ -4955,8 +4954,6 @@ void GPUEngineA::_HandleDisplayModeVRAM(u16 *__restrict dstColorLine, const size
}
else
{
// TODO: Get rid of this method's dependence on _engineMain->isCustomRenderingNeeded.
//
// The reason we need to check this on a per line basis instead of figuring this out at
// GPUSubsystem::UpdateRenderProperties() is because GPUSubsystem::UpdateRenderProperties()
// is called at line 0, but some games, such as Nanostray 2, might change DISPCNT in the
@ -4964,7 +4961,7 @@ void GPUEngineA::_HandleDisplayModeVRAM(u16 *__restrict dstColorLine, const size
const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT;
const VRAM3DUsageProperties &vramUsageProperty = GPU->GetRenderProperties();
if (vramUsageProperty.isCustomBlockUsed[DISPCNT.VRAM_Block])
if (vramUsageProperty.isCustomBlockUsed[DISPCNT.VRAM_Block] && (vramUsageProperty.blockIndexDisplayVRAM == DISPCNT.VRAM_Block))
{
const u16 *__restrict src = this->_VRAMaddrCustom + (_gpuDstLineIndex[l] * dstLineWidth);
#ifdef LOCAL_LE
@ -5389,6 +5386,7 @@ void GPUSubsystem::Reset()
this->_engineMain->Reset();
this->_engineSub->Reset();
this->_VRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE;
this->_VRAM3DUsage.isCustomBlockUsed[0] = false;
this->_VRAM3DUsage.isCustomBlockUsed[1] = false;
this->_VRAM3DUsage.isCustomBlockUsed[2] = false;
@ -5400,6 +5398,8 @@ void GPUSubsystem::Reset()
void GPUSubsystem::UpdateRenderProperties()
{
this->_VRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE;
this->_engineMain->isCustomRenderingNeeded = false;
this->_engineMain->isCustomOutputSize = false;
this->_engineMain->vramBlockBGIndex = VRAM_NO_3D_USAGE;
@ -5464,6 +5464,17 @@ void GPUSubsystem::UpdateRenderProperties()
this->_engineSub->UpdateVRAM3DUsageProperties_OBJLayer(i, this->_VRAM3DUsage);
break;
case VramConfiguration::LCDC:
{
const IOREG_DISPCNT &mainDISPCNT = this->GetEngineMain()->GetIORegisterMap().DISPCNT;
if ((mainDISPCNT.DisplayMode == GPUDisplayMode_VRAM) && (mainDISPCNT.VRAM_Block == i))
{
this->_VRAM3DUsage.blockIndexDisplayVRAM = i;
}
break;
}
default:
this->_VRAM3DUsage.isCustomBlockUsed[i] = false;
break;
@ -5492,8 +5503,7 @@ void GPUSubsystem::UpdateRenderProperties()
break;
case GPUDisplayMode_VRAM:
// TODO: Get rid of this method's dependence on _engineMain->isCustomRenderingNeeded.
this->_engineMain->isCustomOutputSize = this->_engineMain->isCustomRenderingNeeded;
this->_engineMain->isCustomOutputSize = ((this->_VRAM3DUsage.blockIndexDisplayVRAM != VRAM_NO_3D_USAGE) && this->_VRAM3DUsage.isCustomBlockUsed[this->_VRAM3DUsage.blockIndexDisplayVRAM]);
break;
}
@ -5658,7 +5668,7 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativ
}
const size_t newCustomVRAMBlockSize = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w;
const size_t newCustomVRAMBlankSize = newGpuLargestDstLineCount * w;
const size_t newCustomVRAMBlankSize = newGpuLargestDstLineCount * GPU_VRAM_BLANK_REGION_LINES * w;
u16 *newCustomVRAM = (u16 *)malloc_alignedCacheLine(((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16));
memset(newCustomVRAM, 0, ((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16));
@ -5715,6 +5725,7 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativ
if (!this->_displayInfo.isCustomSizeRequested)
{
this->_VRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE;
this->_VRAM3DUsage.isCustomBlockUsed[0] = false;
this->_VRAM3DUsage.isCustomBlockUsed[1] = false;
this->_VRAM3DUsage.isCustomBlockUsed[2] = false;
@ -5777,6 +5788,11 @@ u16* GPUSubsystem::GetCustomVRAMBlankBuffer()
u16* GPUSubsystem::GetCustomVRAMAddressUsingMappedAddress(const u32 mappedAddr)
{
const size_t vramPixel = (size_t)((u8 *)MMU_gpu_map(mappedAddr) - MMU.ARM9_LCD) / sizeof(u16);
if (vramPixel > (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_VRAM_BLOCK_LINES * 4))
{
return this->_customVRAMBlank;
}
const size_t blockID = vramPixel / (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_VRAM_BLOCK_LINES);
const size_t blockPixel = vramPixel % (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_VRAM_BLOCK_LINES);
const size_t blockLine = blockPixel / GPU_FRAMEBUFFER_NATIVE_WIDTH;

View File

@ -45,6 +45,7 @@ struct MMU_struct;
#define GPU_FRAMEBUFFER_NATIVE_HEIGHT 192
#define GPU_VRAM_BLOCK_LINES 256
#define GPU_VRAM_BLANK_REGION_LINES 544
void gpu_savestate(EMUFILE* os);
bool gpu_loadstate(EMUFILE* is, int size);
@ -1034,6 +1035,7 @@ struct DISPCAPCNT_parsed
typedef struct
{
u8 blockIndexDisplayVRAM;
bool isCustomBlockUsed[4];
} VRAM3DUsageProperties;
@ -1392,7 +1394,7 @@ protected:
template<size_t CAPTURELENGTH, bool CAPTUREFROMNATIVESRCA, bool CAPTUREFROMNATIVESRCB, bool CAPTURETONATIVEDST>
void _RenderLine_DispCapture_Blend(const u16 *srcA, const u16 *srcB, u16 *dst, const size_t captureLengthExt, const size_t l); // Do not use restrict pointers, since srcB and dst can be the same
template<bool ISCUSTOMRENDERINGNEEDED> void _HandleDisplayModeVRAM(u16 *__restrict dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
void _HandleDisplayModeVRAM(u16 *__restrict dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount);
void _HandleDisplayModeMainMemory(u16 *dstColorLine);
public: