Make "Skip GPU readbacks" a multi-choice option, for easier experimentation by users

This commit is contained in:
Henrik Rydgård 2023-12-13 14:10:30 +01:00
parent da318e0974
commit caec201c4d
8 changed files with 23 additions and 13 deletions

View File

@ -658,7 +658,7 @@ static const ConfigSetting graphicsSettings[] = {
ConfigSetting("TextureShader", &g_Config.sTextureShaderName, "Off", CfgFlag::PER_GAME),
ConfigSetting("ShaderChainRequires60FPS", &g_Config.bShaderChainRequires60FPS, false, CfgFlag::PER_GAME),
ConfigSetting("SkipGPUReadbacks", &g_Config.bSkipGPUReadbacks, false, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("SkipGPUReadbackMode", &g_Config.iSkipGPUReadbackMode, false, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("GfxDebugOutput", &g_Config.bGfxDebugOutput, false, CfgFlag::DONT_SAVE),
ConfigSetting("LogFrameDrops", &g_Config.bLogFrameDrops, false, CfgFlag::DEFAULT),

View File

@ -235,7 +235,7 @@ public:
float fCwCheatScrollPosition;
float fGameListScrollPosition;
int iBloomHack; //0 = off, 1 = safe, 2 = balanced, 3 = aggressive
bool bSkipGPUReadbacks;
int iSkipGPUReadbackMode; // 0 = off, 1 = skip, 2 = to texture
int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High
bool bHardwareTessellation;
bool bShaderCache; // Hidden ini-only setting, useful for debugging shader compile times.

View File

@ -176,3 +176,9 @@ enum class DisplayFramerateMode : int {
FORCE_60HZ_METHOD1,
FORCE_60HZ_METHOD2,
};
enum class SkipGPUReadbackMode : int {
NO,
SKIP,
COPY_TO_TEXTURE,
};

View File

@ -1024,7 +1024,7 @@ void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *v
// Saving each frame would be slow.
// TODO: This type of download could be made async, for less stutter on framebuffer creation.
if (!g_Config.bSkipGPUReadbacks && !PSP_CoreParameter().compat.flags().DisableFirstFrameReadback) {
if (g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::NO && !PSP_CoreParameter().compat.flags().DisableFirstFrameReadback) {
ReadFramebufferToMemory(vfb, 0, 0, vfb->safeWidth, vfb->safeHeight, RASTER_COLOR, Draw::ReadbackMode::BLOCK);
vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD | FB_USAGE_FIRST_FRAME_SAVED) & ~FB_USAGE_DOWNLOAD_CLEAR;
vfb->safeWidth = 0;
@ -1040,7 +1040,7 @@ bool FramebufferManagerCommon::ShouldDownloadFramebufferColor(const VirtualFrame
bool FramebufferManagerCommon::ShouldDownloadFramebufferDepth(const VirtualFramebuffer *vfb) const {
// Download depth buffer for Syphon Filter lens flares
if (!PSP_CoreParameter().compat.flags().ReadbackDepth || g_Config.bSkipGPUReadbacks) {
if (!PSP_CoreParameter().compat.flags().ReadbackDepth || g_Config.iSkipGPUReadbackMode != (int)SkipGPUReadbackMode::NO) {
return false;
}
return (vfb->usageFlags & FB_USAGE_RENDER_DEPTH) != 0 && vfb->width >= 480 && vfb->height >= 272;
@ -2080,7 +2080,8 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size,
if (!dstBuffer && srcBuffer && channel != RASTER_DEPTH) {
// 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 && !(flags & GPUCopyFlag::DISALLOW_CREATE_VFB)) {
bool allowCreateFB = (PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB || g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::COPY_TO_TEXTURE);
if (allowCreateFB && !(flags & GPUCopyFlag::DISALLOW_CREATE_VFB)) {
dstBuffer = CreateRAMFramebuffer(dst, srcBuffer->width, srcBuffer->height, srcBuffer->fb_stride, srcBuffer->fb_format);
dstY = 0;
}
@ -2129,7 +2130,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size,
// Again we have the problem though that it's doing a lot of small copies here, one for each line.
if (srcH == 0 || srcY + srcH > srcBuffer->bufferHeight) {
WARN_LOG_ONCE(btdcpyheight, G3D, "Memcpy fbo download %08x -> %08x skipped, %d+%d is taller than %d", src, dst, srcY, srcH, srcBuffer->bufferHeight);
} else if (!g_Config.bSkipGPUReadbacks && (!srcBuffer->memoryUpdated || channel == RASTER_DEPTH)) {
} else if (g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::NO && (!srcBuffer->memoryUpdated || channel == RASTER_DEPTH)) {
Draw::ReadbackMode readbackMode = Draw::ReadbackMode::BLOCK;
if (PSP_CoreParameter().compat.flags().AllowDelayedReadbacks) {
readbackMode = Draw::ReadbackMode::OLD_DATA_OK;
@ -2543,6 +2544,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
if (srcBuffer && !dstBuffer) {
// In here, we can't read from dstRect.
if (PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB ||
g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::COPY_TO_TEXTURE ||
(PSP_CoreParameter().compat.flags().IntraVRAMBlockTransferAllowCreateFB &&
Memory::IsVRAMAddress(srcRect.vfb->fb_address) && Memory::IsVRAMAddress(dstBasePtr))) {
GEBufferFormat ramFormat;
@ -2666,7 +2668,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
srcBasePtr, srcRect.x_bytes / bpp, srcRect.y, srcStride,
dstBasePtr, dstRect.x_bytes / bpp, dstRect.y, dstStride);
FlushBeforeCopy();
if (!g_Config.bSkipGPUReadbacks && !srcRect.vfb->memoryUpdated) {
if (g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::NO && !srcRect.vfb->memoryUpdated) {
const int srcBpp = BufferFormatBytesPerPixel(srcRect.vfb->fb_format);
const float srcXFactor = (float)bpp / srcBpp;
const bool tooTall = srcY + srcRect.h > srcRect.vfb->bufferHeight;

View File

@ -347,9 +347,9 @@ void EmuScreen::bootGame(const Path &filename) {
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("BufferedRenderingRequired", "Warning: This game requires Rendering Mode to be set to Buffered."), 10.0f);
}
if (PSP_CoreParameter().compat.flags().RequireBlockTransfer && g_Config.bSkipGPUReadbacks) {
if (PSP_CoreParameter().compat.flags().RequireBlockTransfer && g_Config.iSkipGPUReadbackMode != (int)SkipGPUReadbackMode::NO) {
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("BlockTransferRequired", "Warning: This game requires Simulate Block Transfer Mode to be set to On."), 10.0f);
g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("BlockTransferRequired", "Warning: This game requires Skip GPU Readbacks be set to No."), 10.0f);
}
if (PSP_CoreParameter().compat.flags().RequireDefaultCPUClock && g_Config.iLockedCPUSpeed != 0) {

View File

@ -407,7 +407,9 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
});
skipBufferEffects->SetDisabledPtr(&g_Config.bSoftwareRendering);
CheckBox *skipGPUReadbacks = graphicsSettings->Add(new CheckBox(&g_Config.bSkipGPUReadbacks, gr->T("Skip GPU Readbacks")));
static const char *skipGpuReadbackModes[] = { "No (default)", "Skip", "Copy to texture" };
PopupMultiChoice *skipGPUReadbacks = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iSkipGPUReadbackMode, gr->T("Skip GPU Readbacks"), skipGpuReadbackModes, 0, ARRAY_SIZE(skipGpuReadbackModes), I18NCat::GRAPHICS, screenManager()));
skipGPUReadbacks->SetDisabledPtr(&g_Config.bSoftwareRendering);
CheckBox *texBackoff = graphicsSettings->Add(new CheckBox(&g_Config.bTextureBackoffCache, gr->T("Lazy texture caching", "Lazy texture caching (speedup)")));

View File

@ -468,7 +468,7 @@ int main(int argc, const char* argv[])
g_Config.sReportHost.clear();
g_Config.bAutoSaveSymbolMap = false;
g_Config.bSkipBufferEffects = false;
g_Config.bSkipGPUReadbacks = false;
g_Config.iSkipGPUReadbackMode = (int)SkipGPUReadbackMode::NO;
g_Config.bHardwareTransform = true;
g_Config.iAnisotropyLevel = 0; // When testing mipmapping we really don't want this.
g_Config.iMultiSampleLevel = 0;

View File

@ -634,9 +634,9 @@ static void check_variables(CoreParameter &coreParam)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "disabled"))
g_Config.bSkipGPUReadbacks = false;
g_Config.iSkipGPUReadbackMode = (int)SkipGPUReadbackMode::SKIP;
else
g_Config.bSkipGPUReadbacks = true;
g_Config.iSkipGPUReadbackMode = (int)SkipGPUReadbackMode::NO;
}
var.key = "ppsspp_frameskip";