From 65d1ea0250b0ad4225552566d6e9e26ad88fe903 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 16 Feb 2016 16:41:20 -0600 Subject: [PATCH 1/4] Add a zoomed image view for color targets and depth targets. --- src/xenia/gpu/trace_viewer.cc | 63 +++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/src/xenia/gpu/trace_viewer.cc b/src/xenia/gpu/trace_viewer.cc index f04b42905..559a59a9a 100644 --- a/src/xenia/gpu/trace_viewer.cc +++ b/src/xenia/gpu/trace_viewer.cc @@ -953,6 +953,18 @@ void ProgressBar(float frac, float width, float height = 0, ImGui::Dummy(ImVec2(width, height)); } +void ZoomedImage(ImTextureID tex, ImVec2 rel_pos, ImVec2 tex_size, + float focus_size, ImVec2 image_size = ImVec2(128, 128)) { + ImVec2 focus; + focus.x = rel_pos.x - (focus_size * 0.5f); + focus.y = rel_pos.y - (focus_size * 0.5f); + + ImVec2 uv0 = ImVec2(focus.x / tex_size.x, focus.y / tex_size.y); + ImVec2 uv1 = ImVec2((focus.x + focus_size) / tex_size.x, + (focus.y + focus_size) / tex_size.y); + ImGui::Image(tex, image_size, uv0, uv1); +} + void TraceViewer::DrawStateUI() { auto command_processor = graphics_system_->command_processor(); auto& regs = *graphics_system_->register_file(); @@ -1205,7 +1217,7 @@ void TraceViewer::DrawStateUI() { // Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE // if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard; uint32_t color_control = regs[XE_GPU_REG_RB_COLORCONTROL].u32; - if ((color_control & 0x4) != 0) { + if ((color_control & 0x8) != 0) { ImGui::BulletText("Alpha Test: %s %.2f", kCompareFuncNames[color_control & 0x7], regs[XE_GPU_REG_RB_ALPHA_REF].f32); @@ -1300,14 +1312,15 @@ void TraceViewer::DrawStateUI() { uint32_t color_base = color_info[i] & 0xFFF; auto color_format = static_cast((color_info[i] >> 16) & 0xF); + ImVec2 button_pos = ImGui::GetCursorScreenPos(); ImVec2 button_size(256, 256); + ImTextureID tex = 0; if (write_mask) { - // FIXME: Valid color targets with alpha=0 don't show up. - - auto color_target = GetColorRenderTarget(surface_pitch, surface_msaa, - color_base, color_format); - if (ImGui::ImageButton(ImTextureID(color_target), button_size, - ImVec2(0, 0), ImVec2(1, 1))) { + auto color_target = GetColorRenderTarget( + i, surface_pitch, surface_msaa, color_base, color_format); + tex = ImTextureID(color_target); + if (ImGui::ImageButton(tex, button_size, ImVec2(0, 0), + ImVec2(1, 1))) { // show viewer } } else { @@ -1316,9 +1329,20 @@ void TraceViewer::DrawStateUI() { ImVec4(0, 0, 0, 0)); } if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Color Target %d (%s), base %.4X, pitch %d", i, - write_mask ? "enabled" : "disabled", color_base, - surface_pitch); + ImGui::BeginTooltip(); + ImGui::Text( + "Color Target %d (%s), base %.4X, pitch %d, msaa %d, format %d", + i, write_mask ? "enabled" : "disabled", color_base, surface_pitch, + surface_msaa, color_format); + + if (tex) { + ImVec2 rel_pos; + rel_pos.x = ImGui::GetMousePos().x - button_pos.x; + rel_pos.y = ImGui::GetMousePos().y - button_pos.y; + ZoomedImage(tex, rel_pos, button_size, 32.f, ImVec2(256, 256)); + } + + ImGui::EndTooltip(); } ImGui::NextColumn(); } @@ -1380,10 +1404,21 @@ void TraceViewer::DrawStateUI() { static_cast((rb_depth_info >> 16) & 0x1); auto depth_target = GetDepthRenderTarget(surface_pitch, surface_msaa, depth_base, depth_format); + + auto button_pos = ImGui::GetCursorScreenPos(); ImVec2 button_size(256, 256); - if (ImGui::ImageButton(ImTextureID(depth_target), button_size, - ImVec2(0, 0), ImVec2(1, 1))) { - // show viewer + ImGui::ImageButton(ImTextureID(depth_target), button_size, ImVec2(0, 0), + ImVec2(1, 1)); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + + ImVec2 rel_pos; + rel_pos.x = ImGui::GetMousePos().x - button_pos.x; + rel_pos.y = ImGui::GetMousePos().y - button_pos.y; + ZoomedImage(ImTextureID(depth_target | ui::ImGuiDrawer::kIgnoreAlpha), + rel_pos, button_size, 32.f, ImVec2(256, 256)); + + ImGui::EndTooltip(); } } else { ImGui::Text("No depth target"); @@ -1411,7 +1446,7 @@ void TraceViewer::DrawStateUI() { vertices.resize(size / 4); QueryVSOutput(vertices.data(), size); - ImGui::Text("%d output vertices", vertices.size()); + ImGui::Text("%d output vertices", vertices.size() / 4); ImGui::SameLine(); static bool normalize = false; ImGui::Checkbox("Normalize", &normalize); From a8dfd6a21ad028df2e7c4d06e1cf9dfa4f54c6d4 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 16 Feb 2016 16:43:12 -0600 Subject: [PATCH 2/4] Add a flag to ImTextureID that disables alpha test --- src/xenia/ui/gl/gl_immediate_drawer.cc | 10 ++++++++++ src/xenia/ui/gl/gl_immediate_drawer.h | 2 ++ src/xenia/ui/imgui_drawer.cc | 11 ++++++++++- src/xenia/ui/imgui_drawer.h | 2 ++ src/xenia/ui/immediate_drawer.h | 2 ++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/xenia/ui/gl/gl_immediate_drawer.cc b/src/xenia/ui/gl/gl_immediate_drawer.cc index 9cbdaf037..42d9293fd 100644 --- a/src/xenia/ui/gl/gl_immediate_drawer.cc +++ b/src/xenia/ui/gl/gl_immediate_drawer.cc @@ -270,6 +270,16 @@ void GLImmediateDrawer::End() { } } +void GLImmediateDrawer::EnableAlphaTest(bool enable) { + if (enable) { + glEnablei(GL_BLEND, 0); + glBlendEquationi(0, GL_FUNC_ADD); + glBlendFunci(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } else { + glDisablei(GL_BLEND, 0); + } +} + } // namespace gl } // namespace ui } // namespace xe diff --git a/src/xenia/ui/gl/gl_immediate_drawer.h b/src/xenia/ui/gl/gl_immediate_drawer.h index e9e02798e..cf0ed1603 100644 --- a/src/xenia/ui/gl/gl_immediate_drawer.h +++ b/src/xenia/ui/gl/gl_immediate_drawer.h @@ -37,6 +37,8 @@ class GLImmediateDrawer : public ImmediateDrawer { void EndDrawBatch() override; void End() override; + void EnableAlphaTest(bool enable); + private: void InitializeShaders(); diff --git a/src/xenia/ui/imgui_drawer.cc b/src/xenia/ui/imgui_drawer.cc index 6507699e7..7be42804b 100644 --- a/src/xenia/ui/imgui_drawer.cc +++ b/src/xenia/ui/imgui_drawer.cc @@ -203,11 +203,16 @@ void ImGuiDrawer::RenderDrawLists(ImDrawData* data) { for (int j = 0; j < cmd_list->CmdBuffer.size(); ++j) { const auto& cmd = cmd_list->CmdBuffer[j]; + if (reinterpret_cast(cmd.TextureId) & kIgnoreAlpha) { + drawer->EnableAlphaTest(false); + } + ImmediateDraw draw; draw.primitive_type = ImmediatePrimitiveType::kTriangles; draw.count = cmd.ElemCount; draw.index_offset = index_offset; - draw.texture_handle = reinterpret_cast(cmd.TextureId); + draw.texture_handle = + reinterpret_cast(cmd.TextureId) & 0xFFFFFFFF; draw.scissor = true; draw.scissor_rect[0] = static_cast(cmd.ClipRect.x); draw.scissor_rect[1] = static_cast(height - cmd.ClipRect.w); @@ -215,6 +220,10 @@ void ImGuiDrawer::RenderDrawLists(ImDrawData* data) { draw.scissor_rect[3] = static_cast(cmd.ClipRect.w - cmd.ClipRect.y); drawer->Draw(draw); + if (reinterpret_cast(cmd.TextureId) & kIgnoreAlpha) { + drawer->EnableAlphaTest(true); + } + index_offset += cmd.ElemCount; } diff --git a/src/xenia/ui/imgui_drawer.h b/src/xenia/ui/imgui_drawer.h index 2bbfb0a99..f6a58f8f0 100644 --- a/src/xenia/ui/imgui_drawer.h +++ b/src/xenia/ui/imgui_drawer.h @@ -35,6 +35,8 @@ class ImGuiDrawer : public WindowListener { ImGuiIO& GetIO(); + static const uint64_t kIgnoreAlpha = (1ull << 32); + protected: void Initialize(); void SetupFont(); diff --git a/src/xenia/ui/immediate_drawer.h b/src/xenia/ui/immediate_drawer.h index 3b7f01238..1c064d91b 100644 --- a/src/xenia/ui/immediate_drawer.h +++ b/src/xenia/ui/immediate_drawer.h @@ -113,6 +113,8 @@ class ImmediateDrawer { // Ends drawing in immediate mode and flushes contents. virtual void End() = 0; + virtual void EnableAlphaTest(bool enable) = 0; + protected: ImmediateDrawer(GraphicsContext* graphics_context) : graphics_context_(graphics_context) {} From e77af94c7ca5fb91ec40663f2b4ccbcaecda0b13 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 16 Feb 2016 16:45:49 -0600 Subject: [PATCH 3/4] Ignore color target / depth target / texture alpha in the trace viewer. --- src/xenia/gpu/trace_viewer.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/xenia/gpu/trace_viewer.cc b/src/xenia/gpu/trace_viewer.cc index 559a59a9a..317675709 100644 --- a/src/xenia/gpu/trace_viewer.cc +++ b/src/xenia/gpu/trace_viewer.cc @@ -639,8 +639,8 @@ void TraceViewer::DrawTextureInfo( ImGui::Columns(2); ImVec2 button_size(256, 256); - if (ImGui::ImageButton(ImTextureID(texture), button_size, ImVec2(0, 0), - ImVec2(1, 1))) { + if (ImGui::ImageButton(ImTextureID(texture | ui::ImGuiDrawer::kIgnoreAlpha), + button_size, ImVec2(0, 0), ImVec2(1, 1))) { // show viewer } ImGui::NextColumn(); @@ -1316,9 +1316,9 @@ void TraceViewer::DrawStateUI() { ImVec2 button_size(256, 256); ImTextureID tex = 0; if (write_mask) { - auto color_target = GetColorRenderTarget( - i, surface_pitch, surface_msaa, color_base, color_format); - tex = ImTextureID(color_target); + auto color_target = GetColorRenderTarget(surface_pitch, surface_msaa, + color_base, color_format); + tex = ImTextureID(color_target | ui::ImGuiDrawer::kIgnoreAlpha); if (ImGui::ImageButton(tex, button_size, ImVec2(0, 0), ImVec2(1, 1))) { // show viewer @@ -1407,8 +1407,9 @@ void TraceViewer::DrawStateUI() { auto button_pos = ImGui::GetCursorScreenPos(); ImVec2 button_size(256, 256); - ImGui::ImageButton(ImTextureID(depth_target), button_size, ImVec2(0, 0), - ImVec2(1, 1)); + ImGui::ImageButton( + ImTextureID(depth_target | ui::ImGuiDrawer::kIgnoreAlpha), + button_size, ImVec2(0, 0), ImVec2(1, 1)); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); From 253e1647535dd93fd7cc795f63ea1302a9946098 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 16 Feb 2016 18:24:37 -0600 Subject: [PATCH 4/4] Move EnableDepthTest functionality into a bool alpha_blend var on ImmediateDraw. --- src/xenia/ui/gl/gl_immediate_drawer.cc | 18 ++++++++---------- src/xenia/ui/gl/gl_immediate_drawer.h | 2 -- src/xenia/ui/imgui_drawer.cc | 11 +++-------- src/xenia/ui/immediate_drawer.h | 5 +++-- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/xenia/ui/gl/gl_immediate_drawer.cc b/src/xenia/ui/gl/gl_immediate_drawer.cc index 42d9293fd..998ff7c50 100644 --- a/src/xenia/ui/gl/gl_immediate_drawer.cc +++ b/src/xenia/ui/gl/gl_immediate_drawer.cc @@ -228,6 +228,14 @@ void GLImmediateDrawer::Draw(const ImmediateDraw& draw) { glDisable(GL_SCISSOR_TEST); } + if (draw.alpha_blend) { + glEnablei(GL_BLEND, 0); + glBlendEquationi(0, GL_FUNC_ADD); + glBlendFunci(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } else { + glDisablei(GL_BLEND, 0); + } + if (draw.texture_handle) { glBindTextureUnit(0, static_cast(draw.texture_handle)); } else { @@ -270,16 +278,6 @@ void GLImmediateDrawer::End() { } } -void GLImmediateDrawer::EnableAlphaTest(bool enable) { - if (enable) { - glEnablei(GL_BLEND, 0); - glBlendEquationi(0, GL_FUNC_ADD); - glBlendFunci(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisablei(GL_BLEND, 0); - } -} - } // namespace gl } // namespace ui } // namespace xe diff --git a/src/xenia/ui/gl/gl_immediate_drawer.h b/src/xenia/ui/gl/gl_immediate_drawer.h index cf0ed1603..e9e02798e 100644 --- a/src/xenia/ui/gl/gl_immediate_drawer.h +++ b/src/xenia/ui/gl/gl_immediate_drawer.h @@ -37,8 +37,6 @@ class GLImmediateDrawer : public ImmediateDrawer { void EndDrawBatch() override; void End() override; - void EnableAlphaTest(bool enable); - private: void InitializeShaders(); diff --git a/src/xenia/ui/imgui_drawer.cc b/src/xenia/ui/imgui_drawer.cc index 7be42804b..87284ad82 100644 --- a/src/xenia/ui/imgui_drawer.cc +++ b/src/xenia/ui/imgui_drawer.cc @@ -203,16 +203,15 @@ void ImGuiDrawer::RenderDrawLists(ImDrawData* data) { for (int j = 0; j < cmd_list->CmdBuffer.size(); ++j) { const auto& cmd = cmd_list->CmdBuffer[j]; - if (reinterpret_cast(cmd.TextureId) & kIgnoreAlpha) { - drawer->EnableAlphaTest(false); - } - ImmediateDraw draw; draw.primitive_type = ImmediatePrimitiveType::kTriangles; draw.count = cmd.ElemCount; draw.index_offset = index_offset; draw.texture_handle = reinterpret_cast(cmd.TextureId) & 0xFFFFFFFF; + draw.alpha_blend = + reinterpret_cast(cmd.TextureId) & kIgnoreAlpha ? false + : true; draw.scissor = true; draw.scissor_rect[0] = static_cast(cmd.ClipRect.x); draw.scissor_rect[1] = static_cast(height - cmd.ClipRect.w); @@ -220,10 +219,6 @@ void ImGuiDrawer::RenderDrawLists(ImDrawData* data) { draw.scissor_rect[3] = static_cast(cmd.ClipRect.w - cmd.ClipRect.y); drawer->Draw(draw); - if (reinterpret_cast(cmd.TextureId) & kIgnoreAlpha) { - drawer->EnableAlphaTest(true); - } - index_offset += cmd.ElemCount; } diff --git a/src/xenia/ui/immediate_drawer.h b/src/xenia/ui/immediate_drawer.h index 1c064d91b..b5545541e 100644 --- a/src/xenia/ui/immediate_drawer.h +++ b/src/xenia/ui/immediate_drawer.h @@ -87,6 +87,9 @@ struct ImmediateDraw { bool scissor = false; // Scissoring region in framebuffer pixels as (x, y, w, h). int scissor_rect[4] = {0}; + + // Blends this draw with the background depending on its alpha (if true). + bool alpha_blend = true; }; class ImmediateDrawer { @@ -113,8 +116,6 @@ class ImmediateDrawer { // Ends drawing in immediate mode and flushes contents. virtual void End() = 0; - virtual void EnableAlphaTest(bool enable) = 0; - protected: ImmediateDrawer(GraphicsContext* graphics_context) : graphics_context_(graphics_context) {}