From 404af95a2c7e928026479c3261ed8e4a89ae53ee Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Fri, 27 Jan 2023 09:18:55 +0100 Subject: [PATCH] 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. --- src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp | 2 +- .../HW/Latte/Core/LatteTextureReadback.cpp | 19 +++++++++++-------- .../Vulkan/VulkanPipelineStableCache.cpp | 1 - src/Cemu/Logging/CemuLogging.h | 7 +++++-- src/gui/MainWindow.cpp | 6 +++--- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp b/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp index f5988f98..c873bbb8 100644 --- a/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp @@ -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) { diff --git a/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp b/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp index bd579b11..9018fba6 100644 --- a/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp @@ -21,6 +21,7 @@ std::queue 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; } diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.cpp index 0d3ff771..e42c2c3d 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.cpp @@ -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) { diff --git a/src/Cemu/Logging/CemuLogging.h b/src/Cemu/Logging/CemuLogging.h index 6bea01e7..72d10ad3 100644 --- a/src/Cemu/Logging/CemuLogging.h +++ b/src/Cemu/Logging/CemuLogging.h @@ -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 @@ -28,12 +29,14 @@ enum class LogType : sint32 PPC_IPC = 20, 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 <> diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 45673cbe..e95b0e68 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -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()); }