Latte: Less aggressive texture readback

By mistake we would read affected textures back after every single drawcall. As an optimization if the same texture gets drawn to multiple times we'll try to only read it back once at the end of the sequence.
This commit is contained in:
Exzap 2023-01-27 09:18:55 +01:00
parent 859dc78e90
commit 404af95a2c
5 changed files with 20 additions and 15 deletions

View File

@ -746,7 +746,7 @@ void LatteTextureLoader_writeReadbackTextureToMemory(LatteTextureDefinition* tex
return;
}
cemuLog_log(LogType::TextureReadback, "[WriteReadbackTex] PhysAddr {:08x} Res {}x{} Fmt {} Slice {} Mip {}", textureData->physAddress, textureData->width, textureData->height, textureData->format, sliceIndex, mipIndex);
cemuLog_log(LogType::TextureReadback, "[TextureReadback-Write] PhysAddr {:08x} Res {}x{} Fmt {} Slice {} Mip {}", textureData->physAddress, textureData->width, textureData->height, textureData->format, sliceIndex, mipIndex);
if (textureData->tileMode == Latte::E_HWTILEMODE::TM_LINEAR_ALIGNED)
{

View File

@ -21,6 +21,7 @@ std::queue<LatteTextureReadbackInfo*> sTextureActiveReadbackQueue; // readbacks
void LatteTextureReadback_StartTransfer(LatteTextureView* textureView)
{
cemuLog_log(LogType::TextureReadback, "[TextureReadback-Start] PhysAddr {:08x} Res {}x{} Fmt {} Slice {} Mip {}", textureView->baseTexture->physAddress, textureView->baseTexture->width, textureView->baseTexture->height, textureView->baseTexture->format, textureView->firstSlice, textureView->firstMip);
// create info entry and store in ordered linked list
LatteTextureReadbackInfo* readbackInfo = g_renderer->texture_createReadback(textureView);
sTextureActiveReadbackQueue.push(readbackInfo);
@ -30,8 +31,8 @@ void LatteTextureReadback_StartTransfer(LatteTextureView* textureView)
}
/*
* Checks for queued transfers and starts them if at least one drawcall has passed since the last write
* Called after a draw operation has finished
* Checks for queued transfers and starts them if at least five drawcalls have passed since the last write
* Called after a draw sequence is completed
* Returns true if at least one transfer was started
*/
bool LatteTextureReadback_Update(bool forceStart)
@ -41,12 +42,14 @@ bool LatteTextureReadback_Update(bool forceStart)
{
LatteTextureReadbackQueueEntry& entry = sTextureScheduledReadbacks[i];
uint32 numPassedDrawcalls = LatteGPUState.drawCallCounter - entry.lastUpdateDrawcallIndex;
// initiate transfer
LatteTextureReadback_StartTransfer(entry.textureView);
// remove element
vectorRemoveByIndex(sTextureScheduledReadbacks, i);
i--;
hasStartedTransfer = true;
if (forceStart || numPassedDrawcalls >= 5)
{
LatteTextureReadback_StartTransfer(entry.textureView);
// remove element
vectorRemoveByIndex(sTextureScheduledReadbacks, i);
i--;
hasStartedTransfer = true;
}
}
return hasStartedTransfer;
}

View File

@ -59,7 +59,6 @@ uint32 VulkanPipelineStableCache::BeginLoading(uint64 cacheTitleId)
// open cache file or create it
cemu_assert_debug(s_cache == nullptr);
const uint32 cacheFileVersion = 1;
s_cache = FileCache::Open(pathCacheFile.generic_wstring(), true, LatteShaderCache_getPipelineCacheExtraVersion(cacheTitleId));
if (!s_cache)
{

View File

@ -2,6 +2,7 @@
enum class LogType : sint32
{
// note: IDs must not exceed 63
Placeholder = -2,
None = -1,
Force = 0, // this logging type is always on
@ -29,11 +30,13 @@ enum class LogType : sint32
NN_AOC = 21,
NN_PDM = 22,
TextureReadback = 30,
ProcUi = 40,
TextureReadback = 60,
APIErrors = 0, // alias for Force. Logs bad parameters or other API errors in OS libs
APIErrors = 0, // alias for 0. Logs bad parameters or other API errors in OS libs
};
template <>

View File

@ -134,7 +134,7 @@ enum
// debug->logging
MAINFRAME_MENU_ID_DEBUG_LOGGING0 = 21500,
MAINFRAME_MENU_ID_DEBUG_ADVANCED_PPC_INFO,
MAINFRAME_MENU_ID_DEBUG_ADVANCED_PPC_INFO = 21599,
// debug->dump
MAINFRAME_MENU_ID_DEBUG_DUMP_TEXTURES = 21600,
MAINFRAME_MENU_ID_DEBUG_DUMP_SHADERS,
@ -195,7 +195,7 @@ EVT_MENU(MAINFRAME_MENU_ID_TIMER_SPEED_0125X, MainWindow::OnDebugSetting)
EVT_MENU(MAINFRAME_MENU_ID_NFC_TOUCH_NFC_FILE, MainWindow::OnNFCMenu)
EVT_MENU_RANGE(MAINFRAME_MENU_ID_NFC_RECENT_0 + 0, MAINFRAME_MENU_ID_NFC_RECENT_LAST, MainWindow::OnNFCMenu)
// debug -> logging menu
EVT_MENU_RANGE(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 0, MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 19, MainWindow::OnDebugLoggingToggleFlagGeneric)
EVT_MENU_RANGE(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 0, MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 98, MainWindow::OnDebugLoggingToggleFlagGeneric)
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_ADVANCED_PPC_INFO, MainWindow::OnPPCInfoToggle)
// debug -> dump menu
EVT_MENU(MAINFRAME_MENU_ID_DEBUG_DUMP_TEXTURES, MainWindow::OnDebugDumpUsedTextures)
@ -1040,7 +1040,7 @@ void MainWindow::OnDebugLoggingToggleFlagGeneric(wxCommandEvent& event)
sint32 loggingIdBase = MAINFRAME_MENU_ID_DEBUG_LOGGING0;
sint32 id = event.GetId();
if (id >= loggingIdBase && id < (MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 20))
if (id >= loggingIdBase && id < (MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 64))
{
cafeLog_setLoggingFlagEnable(id - loggingIdBase, event.IsChecked());
}