diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index ad64afe5e7..3466ec3f73 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -1583,10 +1583,15 @@ void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, co BindCurrentPipeline(); ApplyDynamicState(); - int descSetIndex; - PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex); for (auto &draw : draws) { + if (draw.bindTexture) { + BindTexture(0, draw.bindTexture); + } else if (draw.bindFramebufferAsTex) { + BindFramebufferAsTexture(draw.bindFramebufferAsTex, 0, FBChannel::FB_COLOR_BIT, 0); + } + int descSetIndex; + PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex); BindDescriptors(vulkanUBObuf, descriptors); renderManager_.SetScissor(draw.clipx, draw.clipy, draw.clipw, draw.cliph); renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vulkanIbuf, diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index d2fe0d9222..3e2076cc8c 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -703,6 +703,8 @@ struct ClippedDraw { s16 clipy; s16 clipw; s16 cliph; + Draw::Texture *bindTexture; + Draw::Framebuffer *bindFramebufferAsTex; }; class DrawContext { diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index c658170964..bc3674a901 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -20,6 +20,7 @@ #include #include "ext/imgui/imgui.h" +#include "ext/imgui/imgui_impl_thin3d.h" #include "Common/GPU/thin3d.h" #include "Common/GPU/OpenGL/GLFeatures.h" @@ -3704,5 +3705,10 @@ void FramebufferManagerCommon::DrawImGuiDebug(int &selected) const { } ImGui::EndTable(); - // Now, draw the actual framebuffer image. This could be refined a lot. + if (selected != -1) { + // Now, draw the image of the selected framebuffer. + Draw::Framebuffer *fb = vfbs_[selected]->fbo; + ImTextureID texId = ImGui_ImplThin3d_AddFBAsTextureTemp(fb); + ImGui::Image(texId, ImVec2(fb->Width(), fb->Height())); + } } diff --git a/ext/imgui/imgui_impl_thin3d.cpp b/ext/imgui/imgui_impl_thin3d.cpp index 4cf9590c92..7486f0d2ad 100644 --- a/ext/imgui/imgui_impl_thin3d.cpp +++ b/ext/imgui/imgui_impl_thin3d.cpp @@ -36,20 +36,6 @@ static BackendData *ImGui_ImplThin3d_GetBackendData() { return ImGui::GetCurrentContext() ? (BackendData *)ImGui::GetIO().BackendRendererUserData : nullptr; } -static void BindTexture(Draw::DrawContext *draw, BackendData *bd, ImTextureID textureId) { - if (!textureId) { - draw->BindTexture(0, bd->fontImage); - } else { - size_t index = (size_t)textureId - TEX_ID_OFFSET; - _dbg_assert_(index < bd->tempTextures.size()); - if (bd->tempTextures[index].framebuffer) { - draw->BindFramebufferAsTexture(bd->tempTextures[index].framebuffer, 0, Draw::FBChannel::FB_COLOR_BIT, 0); - } else { - draw->BindTexture(0, bd->tempTextures[index].texture); - } - } -} - static void ImGui_ImplThin3d_SetupRenderState(Draw::DrawContext *draw, ImDrawData* drawData, Draw::Pipeline *pipeline, int fb_width, int fb_height) { BackendData *bd = ImGui_ImplThin3d_GetBackendData(); @@ -103,19 +89,18 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d _assert_(sizeof(ImDrawIdx) == 2); - ImTextureID prev = (ImTextureID)-1; + ImTextureID prevTexId = (ImTextureID)-1; std::vector draws; + Draw::Texture *boundTexture = nullptr; + Draw::Framebuffer *boundFBAsTexture = nullptr; + // Render command lists for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; draws.clear(); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->TextureId != prev) { - BindTexture(draw, bd, pcmd->TextureId); - prev = pcmd->TextureId; - } if (pcmd->UserCallback != nullptr) { // User callback, registered via ImDrawList::AddCallback() // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) @@ -125,6 +110,24 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d pcmd->UserCallback(cmd_list, pcmd); } } else { + // Update the texture pointers. + if (pcmd->TextureId != prevTexId) { + if (!pcmd->TextureId) { + draw->BindTexture(0, bd->fontImage); + } else { + size_t index = (size_t)pcmd->TextureId - TEX_ID_OFFSET; + _dbg_assert_(index < bd->tempTextures.size()); + if (bd->tempTextures[index].framebuffer) { + boundFBAsTexture = bd->tempTextures[index].framebuffer; + boundTexture = nullptr; + } else { + boundTexture = bd->tempTextures[index].texture; + boundFBAsTexture = nullptr; + } + } + prevTexId = pcmd->TextureId; + } + // Project scissor/clipping rectangles into framebuffer space ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); @@ -137,14 +140,16 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) continue; - Draw::ClippedDraw draw; - draw.clipx = clip_min.x; - draw.clipy = clip_min.y; - draw.clipw = clip_max.x - clip_min.x; - draw.cliph = clip_max.y - clip_min.y; - draw.indexCount = pcmd->ElemCount; - draw.indexOffset = pcmd->IdxOffset; - draws.push_back(draw); + Draw::ClippedDraw clippedDraw; + clippedDraw.bindTexture = boundTexture; + clippedDraw.bindFramebufferAsTex = boundFBAsTexture; + clippedDraw.clipx = clip_min.x; + clippedDraw.clipy = clip_min.y; + clippedDraw.clipw = clip_max.x - clip_min.x; + clippedDraw.cliph = clip_max.y - clip_min.y; + clippedDraw.indexCount = pcmd->ElemCount; + clippedDraw.indexOffset = pcmd->IdxOffset; + draws.push_back(clippedDraw); } } draw->DrawIndexedClippedBatchUP(cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.size(), cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.size(), draws); @@ -231,7 +236,7 @@ bool ImGui_ImplThin3d_CreateDeviceObjects(Draw::DrawContext *draw) { desc.tag = "imgui-font"; desc.initData.push_back((const uint8_t *)pixels); bd->fontImage = draw->CreateTexture(desc); - io.Fonts->SetTexID((ImTextureID)bd->fontImage); + io.Fonts->SetTexID(0); } return true;