From e4adc112ffb81f92c839883d9a35bf0515b65b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 29 Nov 2024 19:30:38 +0100 Subject: [PATCH] ImDebugger: Add a basic texture browser --- Common/GPU/Vulkan/thin3d_vulkan.cpp | 2 + Common/GPU/thin3d.h | 3 ++ GPU/Common/GPUDebugInterface.h | 2 + GPU/Common/TextureCacheCommon.cpp | 66 ++++++++++++++++++++++++++++- GPU/Common/TextureCacheCommon.h | 4 +- GPU/D3D11/TextureCacheD3D11.cpp | 2 +- GPU/D3D11/TextureCacheD3D11.h | 6 +-- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/Directx9/TextureCacheDX9.h | 2 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/GLES/TextureCacheGLES.h | 2 +- GPU/GPUCommon.h | 4 ++ GPU/GPUCommonHW.h | 3 ++ GPU/Vulkan/TextureCacheVulkan.cpp | 4 +- GPU/Vulkan/TextureCacheVulkan.h | 2 +- UI/ImDebugger/ImDebugger.cpp | 6 +++ UI/ImDebugger/ImDebugger.h | 2 + UI/ImDebugger/ImGe.cpp | 12 ++++++ UI/ImDebugger/ImGe.h | 2 + ext/imgui/imgui_impl_thin3d.cpp | 41 +++++++++++++++--- ext/imgui/imgui_impl_thin3d.h | 1 + 21 files changed, 152 insertions(+), 18 deletions(-) diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 5d0a8b8c86..eb74711432 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -1600,6 +1600,8 @@ void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, co BindTexture(0, draw.bindTexture); } else if (draw.bindFramebufferAsTex) { BindFramebufferAsTexture(draw.bindFramebufferAsTex, 0, FBChannel::FB_COLOR_BIT, 0); + } else if (draw.bindNativeTexture) { + BindNativeTexture(0, draw.bindNativeTexture); } Draw::SamplerState *sstate = draw.samplerState; BindSamplerStates(0, 1, &sstate); diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index c1210c7d1c..28fd4a4f8c 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -705,6 +705,7 @@ struct ClippedDraw { s16 cliph; Draw::Texture *bindTexture; Draw::Framebuffer *bindFramebufferAsTex; + void *bindNativeTexture; Draw::SamplerState *samplerState; Draw::Pipeline *pipeline; }; @@ -822,6 +823,8 @@ public: // Data types: // * Vulkan: VkImageView // * D3D11: ID3D11ShaderResourceView* + // * OpenGL: GLRTexture + // * D3D9: LPDIRECT3DTEXTURE9 virtual void BindNativeTexture(int sampler, void *nativeTexture) = 0; // Only supports a single dynamic uniform buffer, for maximum compatibility with the old APIs and ease of emulation. diff --git a/GPU/Common/GPUDebugInterface.h b/GPU/Common/GPUDebugInterface.h index 29991a6397..91e0026e77 100644 --- a/GPU/Common/GPUDebugInterface.h +++ b/GPU/Common/GPUDebugInterface.h @@ -26,6 +26,7 @@ #include "GPU/GPUInterface.h" class FramebufferManagerCommon; +class TextureCacheCommon; struct GPUDebugOp { u32 pc; @@ -223,6 +224,7 @@ public: // TODO: Make a proper debug interface instead of accessing directly? virtual FramebufferManagerCommon *GetFramebufferManagerCommon() = 0; + virtual TextureCacheCommon *GetTextureCacheCommon() = 0; virtual bool GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices) { return false; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 15e5fdfeda..8b3e1d9191 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -38,6 +38,7 @@ #include "GPU/Common/TextureDecoder.h" #include "GPU/Common/ShaderId.h" #include "GPU/Common/GPUStateUtils.h" +#include "GPU/ge_constants.h" #include "GPU/Debugger/Debugger.h" #include "GPU/Debugger/Record.h" #include "GPU/GPUCommon.h" @@ -45,6 +46,10 @@ #include "GPU/GPUState.h" #include "Core/Util/PPGeDraw.h" +#include "ext/imgui/imgui.h" +#include "ext/imgui/imgui_impl_thin3d.h" + + #if defined(_M_SSE) #include #endif @@ -2473,7 +2478,7 @@ void TextureCacheCommon::ApplyTextureDepal(TexCacheEntry *entry) { Draw::Viewport viewport{ 0.0f, 0.0f, (float)texWidth, (float)texHeight, 0.0f, 1.0f }; draw_->SetViewport(viewport); - draw_->BindNativeTexture(0, GetNativeTextureView(entry)); + draw_->BindNativeTexture(0, GetNativeTextureView(entry, false)); draw_->BindFramebufferAsTexture(dynamicClutFbo_, 1, Draw::FB_COLOR_BIT, 0); Draw::SamplerState *nearest = textureShaderCache_->GetSampler(false); Draw::SamplerState *clutSampler = textureShaderCache_->GetSampler(false); @@ -3056,3 +3061,62 @@ CheckAlphaResult TextureCacheCommon::CheckCLUTAlpha(const uint8_t *pixelData, GE return CheckAlpha32((const u32 *)pixelData, w, 0xFF000000); } } + +void TextureCacheCommon::DrawImGuiDebug(uint64_t &selectedTextureId) const { + ImVec2 avail = ImGui::GetContentRegionAvail(); + auto &style = ImGui::GetStyle(); + ImGui::BeginChild("left", ImVec2(140.0f, 0.0f), ImGuiChildFlags_ResizeX); + float window_visible_x2 = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x; + + for (auto &iter : cache_) { + u64 id = iter.first; + void *nativeView = GetNativeTextureView(iter.second.get(), true); + int w = 128; + int h = 128; + + 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 + if (next_button_x2 < window_visible_x2) + ImGui::SameLine(); + + float x = ImGui::GetCursorPosX(); + 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)); + } + 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", 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 + } else { + selectedTextureId = 0; + } + } else { + ImGui::Text("(no texture selected)"); + } + ImGui::EndChild(); +} diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index e3e30de652..0d617300e2 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -379,8 +379,10 @@ public: virtual void DeviceLost() = 0; virtual void DeviceRestore(Draw::DrawContext *draw) = 0; + virtual void DrawImGuiDebug(uint64_t &selectedTextureId) const; + protected: - virtual void *GetNativeTextureView(const TexCacheEntry *entry) = 0; + virtual void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const = 0; bool PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEntry *entry); virtual void BindTexture(TexCacheEntry *entry) = 0; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 320d688031..18d32180d3 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -535,7 +535,7 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level return true; } -void *TextureCacheD3D11::GetNativeTextureView(const TexCacheEntry *entry) { +void *TextureCacheD3D11::GetNativeTextureView(const TexCacheEntry *entry, bool flat) const { ID3D11ShaderResourceView *textureView = DxView(entry); return (void *)textureView; } diff --git a/GPU/D3D11/TextureCacheD3D11.h b/GPU/D3D11/TextureCacheD3D11.h index 31f29c68bb..2da5b1d81f 100644 --- a/GPU/D3D11/TextureCacheD3D11.h +++ b/GPU/D3D11/TextureCacheD3D11.h @@ -61,7 +61,7 @@ protected: void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; void BindAsClutTexture(Draw::Texture *tex, bool smooth) override; void ApplySamplingParams(const SamplerCacheKey &key) override; - void *GetNativeTextureView(const TexCacheEntry *entry) override; + void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const override; private: DXGI_FORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; @@ -72,10 +72,10 @@ private: ID3D11Device *device_; ID3D11DeviceContext *context_; - ID3D11Resource *&DxTex(const TexCacheEntry *entry) { + ID3D11Resource *&DxTex(const TexCacheEntry *entry) const { return (ID3D11Resource *&)entry->texturePtr; } - ID3D11ShaderResourceView *DxView(const TexCacheEntry *entry) { + ID3D11ShaderResourceView *DxView(const TexCacheEntry *entry) const { return (ID3D11ShaderResourceView *)entry->textureView; } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 28dfec2a9b..1cd2ed6f62 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -436,7 +436,7 @@ bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level, return success; } -void *TextureCacheDX9::GetNativeTextureView(const TexCacheEntry *entry) { +void *TextureCacheDX9::GetNativeTextureView(const TexCacheEntry *entry, bool flat) const { LPDIRECT3DBASETEXTURE9 tex = DxTex(entry); return (void *)tex; } diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 30b4c73a1f..ab108575d1 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -51,7 +51,7 @@ protected: void Unbind() override; void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; void BindAsClutTexture(Draw::Texture *tex, bool smooth) override; - void *GetNativeTextureView(const TexCacheEntry *entry) override; + void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const override; private: void ApplySamplingParams(const SamplerCacheKey &key) override; diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index a91918b362..2057d251ca 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -433,7 +433,7 @@ void TextureCacheGLES::DeviceRestore(Draw::DrawContext *draw) { textureShaderCache_->DeviceRestore(draw); } -void *TextureCacheGLES::GetNativeTextureView(const TexCacheEntry *entry) { +void *TextureCacheGLES::GetNativeTextureView(const TexCacheEntry *entry, bool flat) const { GLRTexture *tex = entry->textureName; return (void *)tex; } diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 5d3e993020..966c2c9963 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -63,7 +63,7 @@ protected: void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; void BindAsClutTexture(Draw::Texture *tex, bool smooth) override; - void *GetNativeTextureView(const TexCacheEntry *entry) override; + void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const override; private: void ApplySamplingParams(const SamplerCacheKey &key) override; diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 14474764cd..ece0385ab8 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -185,6 +185,10 @@ public: return nullptr; } + TextureCacheCommon *GetTextureCacheCommon() override { + return nullptr; + } + std::vector DebugGetShaderIDs(DebugShaderType shader) override { return std::vector(); }; std::string DebugGetShaderString(std::string id, DebugShaderType shader, DebugShaderStringType stringType) override { return "N/A"; diff --git a/GPU/GPUCommonHW.h b/GPU/GPUCommonHW.h index 78474c7b39..3703053385 100644 --- a/GPU/GPUCommonHW.h +++ b/GPU/GPUCommonHW.h @@ -31,6 +31,9 @@ public: FramebufferManagerCommon *GetFramebufferManagerCommon() override { return framebufferManager_; } + TextureCacheCommon *GetTextureCacheCommon() override { + return textureCache_; + } // Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend. std::vector DebugGetShaderIDs(DebugShaderType shader) override; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 96d397315c..9449ed5190 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -867,7 +867,7 @@ std::string TextureCacheVulkan::DebugGetSamplerString(const std::string &id, Deb return samplerCache_.DebugGetSamplerString(id, stringType); } -void *TextureCacheVulkan::GetNativeTextureView(const TexCacheEntry *entry) { - VkImageView view = entry->vkTex->GetImageArrayView(); +void *TextureCacheVulkan::GetNativeTextureView(const TexCacheEntry *entry, bool flat) const { + VkImageView view = flat ? entry->vkTex->GetImageView() : entry->vkTex->GetImageArrayView(); return (void *)view; } diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index e62f5ff73a..b2e95d0573 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -90,7 +90,7 @@ protected: void BindAsClutTexture(Draw::Texture *tex, bool smooth) override; void ApplySamplingParams(const SamplerCacheKey &key) override; void BoundFramebufferTexture() override; - void *GetNativeTextureView(const TexCacheEntry *entry) override; + void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const override; private: void LoadVulkanTextureLevel(TexCacheEntry &entry, uint8_t *writePtr, int rowPitch, int level, int scaleFactor, VkFormat dstFmt); diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 1531ea55ee..e7191acbfa 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -822,6 +822,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu } if (ImGui::BeginMenu("Graphics")) { ImGui::MenuItem("Display Output", nullptr, &cfg_.displayOpen); + ImGui::MenuItem("Textures", nullptr, &cfg_.texturesOpen); ImGui::MenuItem("Framebuffers", nullptr, &cfg_.framebuffersOpen); // More to come here... ImGui::EndMenu(); @@ -902,6 +903,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu DrawFramebuffersWindow(cfg_, gpuDebug->GetFramebufferManagerCommon()); } + if (cfg_.texturesOpen) { + DrawTexturesWindow(cfg_, gpuDebug->GetTextureCacheCommon()); + } + if (cfg_.displayOpen) { DrawDisplayWindow(cfg_, gpuDebug->GetFramebufferManagerCommon()); } @@ -1115,6 +1120,7 @@ void ImConfig::SyncConfig(IniFile *ini, bool save) { sync.Sync("filesystemBrowserOpen", &filesystemBrowserOpen, false); sync.Sync("kernelObjectsOpen", &kernelObjectsOpen, false); sync.Sync("audioChannelsOpen", &audioChannelsOpen, false); + sync.Sync("texturesOpen", &texturesOpen, false); sync.SetSection(ini->GetOrCreateSection("Settings")); sync.Sync("displayLatched", &displayLatched, false); diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 387fa59e2a..7a7cc567f5 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -71,6 +71,7 @@ struct ImConfig { bool audioDecodersOpen; bool structViewerOpen; bool framebuffersOpen; + bool texturesOpen; bool displayOpen; bool styleEditorOpen; bool filesystemBrowserOpen; @@ -86,6 +87,7 @@ struct ImConfig { int selectedFramebuffer = -1; int selectedBreakpoint = -1; int selectedMemCheck = -1; + uint64_t selectedTexAddr = 0; bool displayLatched = false; diff --git a/UI/ImDebugger/ImGe.cpp b/UI/ImDebugger/ImGe.cpp index 3b096b650c..35fd496204 100644 --- a/UI/ImDebugger/ImGe.cpp +++ b/UI/ImDebugger/ImGe.cpp @@ -3,6 +3,7 @@ #include "UI/ImDebugger/ImGe.h" #include "UI/ImDebugger/ImDebugger.h" #include "GPU/Common/FramebufferManagerCommon.h" +#include "GPU/Common/TextureCacheCommon.h" #include "Core/HLE/sceDisplay.h" @@ -17,6 +18,17 @@ void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebuffer ImGui::End(); } +void DrawTexturesWindow(ImConfig &cfg, TextureCacheCommon *textureCache) { + if (!ImGui::Begin("Textures", &cfg.texturesOpen)) { + ImGui::End(); + return; + } + + textureCache->DrawImGuiDebug(cfg.selectedTexAddr); + + ImGui::End(); +} + void DrawDisplayWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager) { if (!ImGui::Begin("Display", &cfg.framebuffersOpen)) { ImGui::End(); diff --git a/UI/ImDebugger/ImGe.h b/UI/ImDebugger/ImGe.h index 08868b7f0a..7edded6d11 100644 --- a/UI/ImDebugger/ImGe.h +++ b/UI/ImDebugger/ImGe.h @@ -5,8 +5,10 @@ struct ImConfig; class FramebufferManagerCommon; +class TextureCacheCommon; void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager); +void DrawTexturesWindow(ImConfig &cfg, TextureCacheCommon *textureCache); void DrawDisplayWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager); class ImGeDebugger { diff --git a/ext/imgui/imgui_impl_thin3d.cpp b/ext/imgui/imgui_impl_thin3d.cpp index 18c0a4fef4..ba9da0fd3e 100644 --- a/ext/imgui/imgui_impl_thin3d.cpp +++ b/ext/imgui/imgui_impl_thin3d.cpp @@ -12,9 +12,16 @@ static Lin::Matrix4x4 g_drawMatrix; static ImFont *g_proportionalFont = nullptr; static ImFont *g_fixedFont = nullptr; +enum class RegisteredTextureType { + Framebuffer, + Texture, + NativeTexture, +}; + struct RegisteredTexture { - bool isFramebuffer; + RegisteredTextureType type; union { + void *nativeTexture; Draw::Texture *texture; struct { Draw::Framebuffer *framebuffer; @@ -79,6 +86,7 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d std::vector draws; Draw::Texture *boundTexture; Draw::Framebuffer *boundFBAsTexture; + void *boundNativeTexture; Draw::Pipeline *boundPipeline = bd->pipelines[0]; Draw::SamplerState *boundSampler = bd->fontSampler; @@ -95,18 +103,29 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d if (!pcmd->TextureId) { // Default boundTexture = bd->fontImage; + boundNativeTexture = nullptr; boundFBAsTexture = nullptr; boundPipeline = bd->pipelines[0]; boundSampler = bd->fontSampler; } else { size_t index = (size_t)pcmd->TextureId - TEX_ID_OFFSET; _dbg_assert_(index < bd->tempTextures.size()); - if (bd->tempTextures[index].framebuffer) { + switch (bd->tempTextures[index].type) { + case RegisteredTextureType::Framebuffer: boundFBAsTexture = bd->tempTextures[index].framebuffer; boundTexture = nullptr; - } else { + boundNativeTexture = nullptr; + break; + case RegisteredTextureType::Texture: boundTexture = bd->tempTextures[index].texture; boundFBAsTexture = nullptr; + boundNativeTexture = nullptr; + break; + case RegisteredTextureType::NativeTexture: + boundTexture = nullptr; + boundFBAsTexture = nullptr; + boundNativeTexture = bd->tempTextures[index].nativeTexture;; + break; } boundPipeline = bd->pipelines[(int)bd->tempTextures[index].pipeline]; boundSampler = bd->fontSampler; @@ -128,6 +147,7 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d clippedDraw.pipeline = boundPipeline; clippedDraw.bindTexture = boundTexture; clippedDraw.bindFramebufferAsTex = boundFBAsTexture; + clippedDraw.bindNativeTexture = boundNativeTexture; clippedDraw.samplerState = boundSampler; clippedDraw.clipx = clip_min.x; clippedDraw.clipy = clip_min.y; @@ -309,10 +329,21 @@ void ImGui_ImplThin3d_NewFrame(Draw::DrawContext *draw, Lin::Matrix4x4 drawMatri g_drawMatrix = drawMatrix; } +ImTextureID ImGui_ImplThin3d_AddNativeTextureTemp(void *texture, ImGuiPipeline pipeline) { + BackendData* bd = ImGui_ImplThin3d_GetBackendData(); + + RegisteredTexture tex{ RegisteredTextureType::NativeTexture}; + tex.nativeTexture = texture; + tex.pipeline = pipeline; + + bd->tempTextures.push_back(tex); + return (ImTextureID)(uint64_t)(TEX_ID_OFFSET + bd->tempTextures.size() - 1); +} + ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, ImGuiPipeline pipeline) { BackendData* bd = ImGui_ImplThin3d_GetBackendData(); - RegisteredTexture tex{ false }; + RegisteredTexture tex{ RegisteredTextureType::Texture }; tex.texture = texture; tex.pipeline = pipeline; @@ -323,7 +354,7 @@ ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, ImGuiPipelin ImTextureID ImGui_ImplThin3d_AddFBAsTextureTemp(Draw::Framebuffer *framebuffer, Draw::FBChannel aspect, ImGuiPipeline pipeline) { BackendData* bd = ImGui_ImplThin3d_GetBackendData(); - RegisteredTexture tex{ true }; + RegisteredTexture tex{ RegisteredTextureType::Framebuffer }; tex.framebuffer = framebuffer; tex.aspect = aspect; tex.pipeline = pipeline; diff --git a/ext/imgui/imgui_impl_thin3d.h b/ext/imgui/imgui_impl_thin3d.h index 11096c9dfd..39d40b8f4f 100644 --- a/ext/imgui/imgui_impl_thin3d.h +++ b/ext/imgui/imgui_impl_thin3d.h @@ -49,6 +49,7 @@ enum class ImGuiPipeline { // These register a texture for imgui drawing, but just for the current frame. // Textures are unregistered again in RenderDrawData. This is just simpler. IMGUI_IMPL_API ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, ImGuiPipeline pipeline = ImGuiPipeline::TexturedAlphaBlend); +IMGUI_IMPL_API ImTextureID ImGui_ImplThin3d_AddNativeTextureTemp(void *texture, ImGuiPipeline pipeline = ImGuiPipeline::TexturedAlphaBlend); IMGUI_IMPL_API ImTextureID ImGui_ImplThin3d_AddFBAsTextureTemp(Draw::Framebuffer *framebuffer, Draw::FBChannel aspect = Draw::FB_COLOR_BIT, ImGuiPipeline pipeline = ImGuiPipeline::TexturedAlphaBlend); void ImGui_PushFixedFont();