mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-12-14 00:49:49 +00:00
Add texture cache stats to ImDebugger
This commit is contained in:
parent
61ae6d6c90
commit
b195061a45
@ -58,6 +58,7 @@ enum class ReplacementState : uint32_t {
|
||||
NOT_FOUND, // Also used on error loading the images.
|
||||
ACTIVE,
|
||||
CANCEL_INIT,
|
||||
COUNT, // Not a valid state
|
||||
};
|
||||
|
||||
const char *StateString(ReplacementState state);
|
||||
@ -168,6 +169,10 @@ public:
|
||||
return fmt;
|
||||
}
|
||||
|
||||
const ReplacementDesc &Desc() const {
|
||||
return desc_;
|
||||
}
|
||||
|
||||
u8 AlphaStatus() const {
|
||||
return (u8)alphaStatus_;
|
||||
}
|
||||
|
@ -3068,12 +3068,23 @@ void TextureCacheCommon::DrawImGuiDebug(uint64_t &selectedTextureId) const {
|
||||
ImGui::BeginChild("left", ImVec2(140.0f, 0.0f), ImGuiChildFlags_ResizeX);
|
||||
float window_visible_x2 = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x;
|
||||
|
||||
// Global texture stats
|
||||
int replacementStateCounts[(int)ReplacementState::COUNT]{};
|
||||
if (!secondCache_.empty()) {
|
||||
ImGui::Text("Primary Cache");
|
||||
}
|
||||
|
||||
for (auto &iter : cache_) {
|
||||
u64 id = iter.first;
|
||||
const TexCacheEntry *entry = iter.second.get();
|
||||
void *nativeView = GetNativeTextureView(iter.second.get(), true);
|
||||
int w = 128;
|
||||
int h = 128;
|
||||
|
||||
if (entry->replacedTexture) {
|
||||
replacementStateCounts[(int)entry->replacedTexture->State()]++;
|
||||
}
|
||||
|
||||
ImTextureID texId = ImGui_ImplThin3d_AddNativeTextureTemp(nativeView);
|
||||
float last_button_x2 = ImGui::GetItemRectMax().x;
|
||||
float next_button_x2 = last_button_x2 + style.ItemSpacing.x + w; // Expected position if next button was on same line
|
||||
@ -3084,39 +3095,90 @@ void TextureCacheCommon::DrawImGuiDebug(uint64_t &selectedTextureId) const {
|
||||
if (ImGui::Selectable(("##Image" + std::to_string(id)).c_str(), selectedTextureId == id, 0, ImVec2(w, h))) {
|
||||
selectedTextureId = id; // Update the selected index if clicked
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(x + 2.0f);
|
||||
ImGui::Image(texId, ImVec2(128, 128));
|
||||
}
|
||||
|
||||
if (!secondCache_.size()) {
|
||||
ImGui::Text("Secondary Cache (%d): TODO", (int)secondCache_.size());
|
||||
// TODO
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginChild("right", ImVec2(0.f, 0.0f));
|
||||
if (selectedTextureId) {
|
||||
auto iter = cache_.find(selectedTextureId);
|
||||
if (iter != cache_.end()) {
|
||||
void *nativeView = GetNativeTextureView(iter->second.get(), true);
|
||||
ImTextureID texId = ImGui_ImplThin3d_AddNativeTextureTemp(nativeView);
|
||||
const TexCacheEntry *entry = iter->second.get();
|
||||
int dim = entry->dim;
|
||||
int w = dimWidth(dim);
|
||||
int h = dimHeight(dim);
|
||||
ImGui::Image(texId, ImVec2(w, h));
|
||||
ImGui::Text("%08x: %dx%d, %d mips, %s", (uint32_t)(selectedTextureId & 0xFFFFFFFF), w, h, entry->maxLevel + 1, GeTextureFormatToString((GETextureFormat)entry->format));
|
||||
ImGui::Text("Stride: %d", entry->bufw);
|
||||
ImGui::Text("Status: %08x", entry->status); // TODO: Show the flags
|
||||
ImGui::Text("Hash: %08x", entry->fullhash);
|
||||
ImGui::Text("CLUT Hash: %08x", entry->cluthash);
|
||||
ImGui::Text("Minihash: %08x", entry->minihash);
|
||||
ImGui::Text("MaxSeenV: %08x", entry->maxSeenV);
|
||||
ImGui::Text("Replaced: %s", entry->replacedTexture ? "true" : "false");
|
||||
ImGui::Text("Frames until next full hash: %08x", entry->framesUntilNextFullHash); // TODO: Show the flags
|
||||
if (ImGui::CollapsingHeader("Texture", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
if (selectedTextureId) {
|
||||
auto iter = cache_.find(selectedTextureId);
|
||||
if (iter != cache_.end()) {
|
||||
void *nativeView = GetNativeTextureView(iter->second.get(), true);
|
||||
ImTextureID texId = ImGui_ImplThin3d_AddNativeTextureTemp(nativeView);
|
||||
const TexCacheEntry *entry = iter->second.get();
|
||||
int dim = entry->dim;
|
||||
int w = dimWidth(dim);
|
||||
int h = dimHeight(dim);
|
||||
ImGui::Image(texId, ImVec2(w, h));
|
||||
ImGui::Text("%08x: %dx%d, %d mips, %s", (uint32_t)(selectedTextureId & 0xFFFFFFFF), w, h, entry->maxLevel + 1, GeTextureFormatToString((GETextureFormat)entry->format));
|
||||
ImGui::Text("Stride: %d", entry->bufw);
|
||||
ImGui::Text("Status: %08x", entry->status); // TODO: Show the flags
|
||||
ImGui::Text("Hash: %08x", entry->fullhash);
|
||||
ImGui::Text("CLUT Hash: %08x", entry->cluthash);
|
||||
ImGui::Text("Minihash: %08x", entry->minihash);
|
||||
ImGui::Text("MaxSeenV: %08x", entry->maxSeenV);
|
||||
if (entry->replacedTexture) {
|
||||
if (ImGui::CollapsingHeader("Replacement", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
const auto &desc = entry->replacedTexture->Desc();
|
||||
ImGui::Text("State: %s", StateString(entry->replacedTexture->State()));
|
||||
// ImGui::Text("Original: %dx%d (%dx%d)", desc.w, desc.h, desc.newW, desc.newH);
|
||||
if (entry->replacedTexture->State() == ReplacementState::ACTIVE) {
|
||||
int w, h;
|
||||
entry->replacedTexture->GetSize(0, &w, &h);
|
||||
int numLevels = entry->replacedTexture->NumLevels();
|
||||
ImGui::Text("Replaced: %dx%d, %d mip levels", w, h, numLevels);
|
||||
ImGui::Text("Level 0 size: %d bytes, format: %s", entry->replacedTexture->GetLevelDataSizeAfterCopy(0), Draw::DataFormatToString(entry->replacedTexture->Format()));
|
||||
}
|
||||
ImGui::Text("Key: %08x_%08x", (u32)(desc.cachekey >> 32), (u32)desc.cachekey);
|
||||
ImGui::Text("Hashfiles: %s", desc.hashfiles.c_str());
|
||||
ImGui::Text("Base: %s", desc.basePath.c_str());
|
||||
ImGui::Text("Alpha status: %02x", entry->replacedTexture->AlphaStatus());
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("Not replaced");
|
||||
}
|
||||
ImGui::Text("Frames until next full hash: %08x", entry->framesUntilNextFullHash); // TODO: Show the flags
|
||||
} else {
|
||||
selectedTextureId = 0;
|
||||
}
|
||||
} else {
|
||||
selectedTextureId = 0;
|
||||
ImGui::Text("(no texture selected)");
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Texture Cache State"), ImGuiTreeNodeFlags_DefaultOpen) {
|
||||
ImGui::Text("Cache: %d textures, size est %d", (int)cache_.size(), cacheSizeEstimate_);
|
||||
ImGui::Text("Second: %d textures, size est %d", (int)secondCache_.size(), secondCacheSizeEstimate_);
|
||||
ImGui::Text("Low memory mode: %d", (int)lowMemoryMode_);
|
||||
ImGui::Text("Standard/shader scale factor: %d/%d", standardScaleFactor_, shaderScaleFactor_);
|
||||
ImGui::Text("Texels scaled this frame: %d", texelsScaledThisFrame_);
|
||||
if (ImGui::CollapsingHeader("Texture Replacement", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
ImGui::Text("Frame time/budget: %0.3f/%0.3f ms", replacementTimeThisFrame_, replacementFrameBudget_);
|
||||
ImGui::Text("UNLOADED: %d PENDING: %d NOT_FOUND: %d ACTIVE: %d CANCEL_INIT: %d",
|
||||
replacementStateCounts[(int)ReplacementState::UNLOADED],
|
||||
replacementStateCounts[(int)ReplacementState::PENDING],
|
||||
replacementStateCounts[(int)ReplacementState::NOT_FOUND],
|
||||
replacementStateCounts[(int)ReplacementState::ACTIVE],
|
||||
replacementStateCounts[(int)ReplacementState::CANCEL_INIT]);
|
||||
}
|
||||
if (videos_.size()) {
|
||||
if (ImGui::CollapsingHeader("Tracked video playback memory")) {
|
||||
for (auto &video : videos_) {
|
||||
ImGui::Text("%08x: %d flips, size = %d", video.addr, video.flips, video.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("(no texture selected)");
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
@ -515,6 +515,12 @@ u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, bool swizzled
|
||||
const u32 totalPixels = bufw * h + (w - bufw);
|
||||
const u32 sizeInRAM = (textureBitsPerPixel[fmt] * totalPixels) / 8 * reduceHashSize;
|
||||
|
||||
// Sanity check: Ignore textures that are at the end of RAM.
|
||||
if (Memory::MaxSizeAtAddress(addr) < sizeInRAM) {
|
||||
ERROR_LOG(Log::G3D, "Can't hash a %d bytes textures at %08x - end point is outside memory", sizeInRAM, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (hash_) {
|
||||
case ReplacedTextureHash::QUICK:
|
||||
return StableQuickTexHash(checkp, sizeInRAM);
|
||||
|
@ -833,6 +833,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Tools")) {
|
||||
ImGui::MenuItem("Debug stats", nullptr, &cfg_.debugStatsOpen);
|
||||
ImGui::MenuItem("Struct viewer", nullptr, &cfg_.structViewerOpen);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@ -911,6 +912,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
|
||||
DrawDisplayWindow(cfg_, gpuDebug->GetFramebufferManagerCommon());
|
||||
}
|
||||
|
||||
if (cfg_.debugStatsOpen) {
|
||||
DrawDebugStatsWindow(cfg_);
|
||||
}
|
||||
|
||||
if (cfg_.structViewerOpen) {
|
||||
structViewer_.Draw(mipsDebug, &cfg_.structViewerOpen);
|
||||
}
|
||||
@ -1121,6 +1126,7 @@ void ImConfig::SyncConfig(IniFile *ini, bool save) {
|
||||
sync.Sync("kernelObjectsOpen", &kernelObjectsOpen, false);
|
||||
sync.Sync("audioChannelsOpen", &audioChannelsOpen, false);
|
||||
sync.Sync("texturesOpen", &texturesOpen, false);
|
||||
sync.Sync("debugStatsOpen", &debugStatsOpen, false);
|
||||
|
||||
sync.SetSection(ini->GetOrCreateSection("Settings"));
|
||||
sync.Sync("displayLatched", &displayLatched, false);
|
||||
|
@ -77,6 +77,7 @@ struct ImConfig {
|
||||
bool filesystemBrowserOpen;
|
||||
bool kernelObjectsOpen;
|
||||
bool audioChannelsOpen;
|
||||
bool debugStatsOpen;
|
||||
|
||||
// HLE explorer settings
|
||||
// bool filterByUsed = true;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "GPU/Common/TextureCacheCommon.h"
|
||||
|
||||
#include "Core/HLE/sceDisplay.h"
|
||||
#include "Core/HW/Display.h"
|
||||
|
||||
void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager) {
|
||||
if (!ImGui::Begin("Framebuffers", &cfg.framebuffersOpen)) {
|
||||
@ -55,3 +56,15 @@ void DrawDisplayWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManag
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Note: This is not exclusively graphics.
|
||||
void DrawDebugStatsWindow(ImConfig &cfg) {
|
||||
if (!ImGui::Begin("Debug Stats", &cfg.debugStatsOpen)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
char statbuf[4096];
|
||||
__DisplayGetDebugStats(statbuf, sizeof(statbuf));
|
||||
ImGui::TextUnformatted(statbuf);
|
||||
ImGui::End();
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ class TextureCacheCommon;
|
||||
void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager);
|
||||
void DrawTexturesWindow(ImConfig &cfg, TextureCacheCommon *textureCache);
|
||||
void DrawDisplayWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager);
|
||||
void DrawDebugStatsWindow(ImConfig &cfg);
|
||||
|
||||
class ImGeDebugger {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user