Make the frame-time budget for uploading replacement textures take framerate into account

This commit is contained in:
Henrik Rydgård
2025-04-22 20:19:43 +02:00
parent f2de70c904
commit 0f18f054ab
5 changed files with 27 additions and 14 deletions
+9 -3
View File
@@ -105,9 +105,15 @@ static void CalculateFPS() {
// TODO: Also average actualFps
void __DisplayGetFPS(float *out_vps, float *out_fps, float *out_actual_fps) {
*out_vps = (float)fps;
*out_fps = flips;
*out_actual_fps = actualFps;
if (out_vps) {
*out_vps = (float)fps;
}
if (out_fps) {
*out_fps = flips;
}
if (out_actual_fps) {
*out_actual_fps = actualFps;
}
}
void __DisplayGetVPS(float *out_vps) {
+1 -1
View File
@@ -176,7 +176,7 @@ bool ReplacedTexture::Poll(double budget) {
lastUsed_ = now;
// Let's not even start a new texture if we're already behind.
if (budget < 0.0)
if (budget <= 0.0)
return false;
_assert_(!threadWaitable_);
+14 -6
View File
@@ -34,6 +34,7 @@
#include "Core/Config.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/System.h"
#include "Core/HW/Display.h"
#include "GPU/Common/FramebufferManagerCommon.h"
#include "GPU/Common/TextureCacheCommon.h"
#include "GPU/Common/TextureDecoder.h"
@@ -127,6 +128,14 @@ void TextureCacheCommon::StartFrame() {
timesInvalidatedAllThisFrame_ = 0;
replacementTimeThisFrame_ = 0.0;
float fps;
__DisplayGetFPS(nullptr, &fps, nullptr);
if (fps <= 5.0f) {
fps = 60.0f;
}
// Allow spending half a frame on uploading textures.
replacementFrameBudgetSeconds_ = 0.5f / fps;
if ((DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS) {
gpuStats.numReplacerTrackedTex = replacer_.GetNumTrackedTextures();
gpuStats.numCachedReplacedTextures = replacer_.GetNumCachedReplacedTextures();
@@ -530,7 +539,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
}
}
if (match && (entry->status & TexCacheEntry::STATUS_TO_REPLACE) && replacementTimeThisFrame_ < replacementFrameBudget_) {
if (match && (entry->status & TexCacheEntry::STATUS_TO_REPLACE) && replacementTimeThisFrame_ < replacementFrameBudgetSeconds_) {
int w0 = gstate.getTextureWidth(0);
int h0 = gstate.getTextureHeight(0);
int d0 = 1;
@@ -1572,10 +1581,9 @@ ReplacedTexture *TextureCacheCommon::FindReplacement(TexCacheEntry *entry, int *
}
void TextureCacheCommon::PollReplacement(TexCacheEntry *entry, int *w, int *h, int *d) {
// Allow some delay to reduce pop-in.
constexpr double MAX_BUDGET_PER_TEX = 0.25 / 60.0;
double budget = std::min(MAX_BUDGET_PER_TEX, replacementFrameBudget_ - replacementTimeThisFrame_);
double budget = replacementFrameBudgetSeconds_ - replacementTimeThisFrame_;
// Note: Don't avoid the Poll call if budget is 0, we do meaningful things there.
// Poll also handles negative budgets.
double replaceStart = time_now_d();
if (entry->replacedTexture->Poll(budget)) {
@@ -3157,7 +3165,7 @@ void TextureCacheCommon::DrawImGuiDebug(uint64_t &selectedTextureId) const {
ImGui::Text("Texels scaled this frame: %d", texelsScaledThisFrame_);
ImGui::Text("Low memory mode: %d", (int)lowMemoryMode_);
if (ImGui::CollapsingHeader("Texture Replacement", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Text("Frame time/budget: %0.3f/%0.3f ms", replacementTimeThisFrame_ * 1000.0f, replacementFrameBudget_ * 1000.0f);
ImGui::Text("Frame time/budget: %0.3f/%0.3f ms", replacementTimeThisFrame_ * 1000.0f, replacementFrameBudgetSeconds_ * 1000.0f);
ImGui::Text("UNLOADED: %d PENDING: %d NOT_FOUND: %d ACTIVE: %d CANCEL_INIT: %d",
replacementStateCounts[(int)ReplacementState::UNLOADED],
replacementStateCounts[(int)ReplacementState::PENDING],
+2 -2
View File
@@ -496,8 +496,8 @@ protected:
int texelsScaledThisFrame_ = 0;
int timesInvalidatedAllThisFrame_ = 0;
double replacementTimeThisFrame_ = 0;
// TODO: Maybe vary by FPS...
double replacementFrameBudget_ = 0.5 / 60.0;
// Recomputed once per frame. Depends FPS and soon also config.
double replacementFrameBudgetSeconds_ = 0.5 / 60.0;
TexCache cache_;
u32 cacheSizeEstimate_ = 0;
+1 -2
View File
@@ -1768,8 +1768,6 @@ void EmuScreen::runImDebugger() {
if (g_Config.bShowImDebugger) {
Draw::DrawContext *draw = screenManager()->getDrawContext();
if (!imguiInited_) {
imguiInited_ = true;
// TODO: Do this only on demand.
IMGUI_CHECKVERSION();
ctx_ = ImGui::CreateContext();
@@ -1783,6 +1781,7 @@ void EmuScreen::runImDebugger() {
// This call works even if fontData is nullptr, in which case the font just won't get loaded.
// This takes ownership of the font array.
ImGui_ImplThin3d_Init(draw, fontData, size);
imguiInited_ = true;
}
if (PSP_IsInited()) {