Create a safer variant of BlockTransferAllowCreateFB, enable for FF Type 0

Performance improvement by avoiding unnecessary readbacks.

New one is called IntraVRAMBlockTransferAllowCreateFB.

This one only allows intra-VRAM block transfers to happen on-GPU, such as the one this
game uses for bloom. Good chances to avoid missing stuff that actually requires
real readback, if there's any.
This commit is contained in:
Henrik Rydgård 2020-10-10 23:48:37 +02:00
parent 3fe1e35e3c
commit b28baed7d3
4 changed files with 31 additions and 17 deletions

View File

@ -62,6 +62,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
CheckSetting(iniFile, gameID, "MGS2AcidHack", &flags_.MGS2AcidHack);
CheckSetting(iniFile, gameID, "SonicRivalsHack", &flags_.SonicRivalsHack);
CheckSetting(iniFile, gameID, "BlockTransferAllowCreateFB", &flags_.BlockTransferAllowCreateFB);
CheckSetting(iniFile, gameID, "IntraVRAMBlockTransferAllowCreateFB", &flags_.IntraVRAMBlockTransferAllowCreateFB);
CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix);
CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay);
CheckSetting(iniFile, gameID, "ForceMax60FPS", &flags_.ForceMax60FPS);

View File

@ -60,6 +60,7 @@ struct CompatFlags {
bool MGS2AcidHack;
bool SonicRivalsHack;
bool BlockTransferAllowCreateFB;
bool IntraVRAMBlockTransferAllowCreateFB;
bool YugiohSaveFix;
bool ForceUMDDelay;
bool ForceMax60FPS;

View File

@ -1180,9 +1180,13 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size,
}
}
if (!dstBuffer && srcBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) {
dstBuffer = CreateRAMFramebuffer(dst, srcBuffer->width, srcBuffer->height, srcBuffer->fb_stride, srcBuffer->format);
dstY = 0;
if (!dstBuffer && srcBuffer) {
// Note - if we're here, we're in a memcpy, not a block transfer. Not allowing IntraVRAMBlockTransferAllowCreateFB.
// Technically, that makes BlockTransferAllowCreateFB a bit of a misnomer.
if (PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) {
dstBuffer = CreateRAMFramebuffer(dst, srcBuffer->width, srcBuffer->height, srcBuffer->fb_stride, srcBuffer->format);
dstY = 0;
}
}
if (dstBuffer) {
dstBuffer->last_frame_used = gpuStats.numFlips;
@ -1308,21 +1312,25 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst
}
}
if (srcBuffer && !dstBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) {
GEBufferFormat ramFormat;
// Try to guess the appropriate format. We only know the bpp from the block transfer command (16 or 32 bit).
if (bpp == 4) {
// Only one possibility unless it's doing split pixel tricks (which we could detect through stride maybe).
ramFormat = GE_FORMAT_8888;
} else if (srcBuffer->format != GE_FORMAT_8888) {
// We guess that the game will interpret the data the same as it was in the source of the copy.
// Seems like a likely good guess, and works in Test Drive Unlimited.
ramFormat = srcBuffer->format;
} else {
// No info left - just fall back to something. But this is definitely split pixel tricks.
ramFormat = GE_FORMAT_5551;
if (srcBuffer && !dstBuffer) {
if (PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB ||
(PSP_CoreParameter().compat.flags().IntraVRAMBlockTransferAllowCreateFB &&
Memory::IsVRAMAddress(srcBuffer->fb_address) && Memory::IsVRAMAddress(dstBasePtr))) {
GEBufferFormat ramFormat;
// Try to guess the appropriate format. We only know the bpp from the block transfer command (16 or 32 bit).
if (bpp == 4) {
// Only one possibility unless it's doing split pixel tricks (which we could detect through stride maybe).
ramFormat = GE_FORMAT_8888;
} else if (srcBuffer->format != GE_FORMAT_8888) {
// We guess that the game will interpret the data the same as it was in the source of the copy.
// Seems like a likely good guess, and works in Test Drive Unlimited.
ramFormat = srcBuffer->format;
} else {
// No info left - just fall back to something. But this is definitely split pixel tricks.
ramFormat = GE_FORMAT_5551;
}
dstBuffer = CreateRAMFramebuffer(dstBasePtr, dstWidth, dstHeight, dstStride, ramFormat);
}
dstBuffer = CreateRAMFramebuffer(dstBasePtr, dstWidth, dstHeight, dstStride, ramFormat);
}
if (dstBuffer)

View File

@ -552,6 +552,10 @@ ULUS10249 = true
ULES00637 = true
ULKS46126 = true
[IntraVRAMBlockTransferAllowCreateFB]
# Final Fantasy - Type 0
NPJH50443 = true
# Note! This whole flag is disabled temporarily by appending "Disabled" to its name). See 7914
[YugiohSaveFixDisabled]
# The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat,