From a32ccd3eb8571d07550d30f5a3e129cd5ee1367b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Dec 2017 01:31:04 -0800 Subject: [PATCH 1/3] GE Debugger: Fix preview when zooming. Before, the coordinates were only right when scaled to fit. When you zoomed in and panned, it would show in the wrong place because it wasn't accounting for the flipped backbuffer. --- Windows/GEDebugger/VertexPreview.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index 75577a1a3c..8bad6b3331 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -189,8 +189,9 @@ void CGEDebugger::UpdatePrimPreview(u32 op) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); glBindTexture(GL_TEXTURE_2D, 0); - glViewport((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh); - glScissor((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh); + // The surface is upside down, so vertical offsets are negated. + glViewport((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh); + glScissor((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh); BindPreviewProgram(previewProgram); // TODO: Probably there's a better way and place to do this. @@ -277,8 +278,9 @@ void CGEDebugger::UpdatePrimPreview(u32 op) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); glBindTexture(GL_TEXTURE_2D, 0); - glViewport((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh); - glScissor((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh); + // The surface is upside down, so vertical offsets are flipped. + glViewport((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh); + glScissor((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh); BindPreviewProgram(texPreviewProgram); if (texPreviewVao == 0 && gl_extensions.ARB_vertex_array_object) { From c55db7a4963945a3857adeca9c8dab770c988a27 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Dec 2017 01:57:03 -0800 Subject: [PATCH 2/3] GE Debugger: Keep prim preview on pan/zoom. --- Windows/GEDebugger/GEDebugger.cpp | 20 +- Windows/GEDebugger/GEDebugger.h | 5 +- Windows/GEDebugger/SimpleGLWindow.cpp | 26 ++- Windows/GEDebugger/SimpleGLWindow.h | 36 ++-- Windows/GEDebugger/VertexPreview.cpp | 289 +++++++++++++++----------- 5 files changed, 225 insertions(+), 151 deletions(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 86cf69d1b2..1ffe5bdda5 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -167,6 +167,9 @@ void CGEDebugger::SetupPreviews() { return true; }); + primaryWindow->SetRedrawCallback([&] { + HandleRedraw(1); + }); primaryWindow->Clear(); } if (secondWindow == nullptr) { @@ -188,6 +191,9 @@ void CGEDebugger::SetupPreviews() { return true; }); + secondWindow->SetRedrawCallback([&] { + HandleRedraw(2); + }); secondWindow->Clear(); } } @@ -258,19 +264,18 @@ void CGEDebugger::UpdatePreviews() { state = gpuDebug->GetGState(); } + updating_ = true; UpdateTextureLevel(textureLevel_); UpdatePrimaryPreview(state); UpdateSecondPreview(state); + u32 primOp = PrimPreviewOp(); + if (primOp != 0) { + UpdatePrimPreview(primOp, 3); + } + DisplayList list; if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) { - const u32 op = Memory::Read_U32(list.pc); - const u32 cmd = op >> 24; - // TODO: Bezier/spline? - if (cmd == GE_CMD_PRIM && !showClut_) { - UpdatePrimPreview(op); - } - displayList->setDisplayList(list); } @@ -282,6 +287,7 @@ void CGEDebugger::UpdatePreviews() { matrices->Update(); lists->Update(); watch->Update(); + updating_ = false; } u32 CGEDebugger::TexturePreviewFlags(const GPUgstate &state) { diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index d520931054..c541337de2 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -70,8 +70,10 @@ private: void UpdatePreviews(); void UpdatePrimaryPreview(const GPUgstate &state); void UpdateSecondPreview(const GPUgstate &state); - void UpdatePrimPreview(u32 op); + u32 PrimPreviewOp(); + void UpdatePrimPreview(u32 op, int which); void CleanupPrimPreview(); + void HandleRedraw(int which); void UpdateSize(WORD width, WORD height); void SavePosition(); void SetBreakNext(BreakNextType type); @@ -106,6 +108,7 @@ private: const GPUDebugBuffer *primaryBuffer_ = nullptr; const GPUDebugBuffer *secondBuffer_ = nullptr; + bool updating_ = false; int minWidth_; int minHeight_; }; diff --git a/Windows/GEDebugger/SimpleGLWindow.cpp b/Windows/GEDebugger/SimpleGLWindow.cpp index cd848cb03a..eab3370301 100644 --- a/Windows/GEDebugger/SimpleGLWindow.cpp +++ b/Windows/GEDebugger/SimpleGLWindow.cpp @@ -68,8 +68,7 @@ static const char basic_vs[] = "}\n"; SimpleGLWindow::SimpleGLWindow(HWND wnd) - : hWnd_(wnd), valid_(false), drawProgram_(nullptr), vao_(0), tex_(0), flags_(0), zoom_(false), - dragging_(false), offsetX_(0), offsetY_(0), reformatBuf_(nullptr), hoverCallback_(nullptr) { + : hWnd_(wnd) { SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR) this); } @@ -365,10 +364,23 @@ void SimpleGLWindow::GetContentSize(float &x, float &y, float &fw, float &fh) { void SimpleGLWindow::Redraw(bool andSwap) { DrawChecker(); - if (tw_ == 0 && th_ == 0) { + auto swapWithCallback = [andSwap, this]() { if (andSwap) { - Swap(); + swapped_ = false; + if (redrawCallback_ && !inRedrawCallback_) { + inRedrawCallback_ = true; + redrawCallback_(); + inRedrawCallback_ = false; + } + // In case the callback swaps, don't do it twice. + if (!swapped_) { + Swap(); + } } + }; + + if (tw_ == 0 && th_ == 0) { + swapWithCallback(); return; } @@ -412,7 +424,7 @@ void SimpleGLWindow::Redraw(bool andSwap) { glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, vao_ ? 0 : indices); if (andSwap) { - Swap(); + swapWithCallback(); } } @@ -423,7 +435,9 @@ void SimpleGLWindow::Clear() { } void SimpleGLWindow::Begin() { - Redraw(false); + if (!inRedrawCallback_) { + Redraw(false); + } if (vao_) { glBindVertexArray(0); diff --git a/Windows/GEDebugger/SimpleGLWindow.h b/Windows/GEDebugger/SimpleGLWindow.h index 5b08fcb95c..7cc305d9ca 100644 --- a/Windows/GEDebugger/SimpleGLWindow.h +++ b/Windows/GEDebugger/SimpleGLWindow.h @@ -81,6 +81,7 @@ struct SimpleGLWindow { } void Swap() { + swapped_ = true; SwapBuffers(hDC_); } @@ -106,6 +107,10 @@ struct SimpleGLWindow { void GetContentSize(float &x, float &y, float &fw, float &fh); + void SetRedrawCallback(std::function callback) { + redrawCallback_ = callback; + } + void SetHoverCallback(std::function hoverCallback) { hoverCallback_ = hoverCallback; } @@ -134,7 +139,7 @@ protected: HWND hWnd_; HDC hDC_; HGLRC hGLRC_; - bool valid_; + bool valid_ = false; // Width and height of the window. int w_; int h_; @@ -143,25 +148,28 @@ protected: int th_; bool tflipped_; - GLSLProgram *drawProgram_; - GLuint vao_; - GLuint ibuf_; - GLuint vbuf_; - GLuint checker_; - GLuint tex_; - u32 flags_; + GLSLProgram *drawProgram_ = nullptr; + GLuint vao_ = 0; + GLuint ibuf_ = 0; + GLuint vbuf_ = 0; + GLuint checker_ = 0; + GLuint tex_ = 0; + u32 flags_ = 0; // Disable shrink (toggled by double click.) - bool zoom_; - bool dragging_; + bool zoom_ = false; + bool dragging_ = false; + bool inRedrawCallback_ = false; + bool swapped_ = false; int dragStartX_; int dragStartY_; u32 dragLastUpdate_; // Offset to position the texture is drawn at. - int offsetX_; - int offsetY_; - u32 *reformatBuf_; - u32 reformatBufSize_; + int offsetX_ = 0; + int offsetY_ = 0; + u32 *reformatBuf_ = nullptr; + u32 reformatBufSize_ = 0; + std::function redrawCallback_; std::function hoverCallback_; std::function rightClickCallback_; HMENU rightClickMenu_; diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index 8bad6b3331..4e91a35b6b 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -151,7 +151,21 @@ static void ExpandRectangles(std::vector &vertices, std::vector< count *= 3; } -void CGEDebugger::UpdatePrimPreview(u32 op) { +u32 CGEDebugger::PrimPreviewOp() { + DisplayList list; + if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) { + const u32 op = Memory::Read_U32(list.pc); + const u32 cmd = op >> 24; + // TODO: Bezier/spline? + if (cmd == GE_CMD_PRIM && !showClut_) { + return op; + } + } + + return 0; +} + +void CGEDebugger::UpdatePrimPreview(u32 op, int which) { const u32 prim_type = (op >> 16) & 0x7; int count = op & 0xFFFF; if (prim_type >= 7) { @@ -162,7 +176,7 @@ void CGEDebugger::UpdatePrimPreview(u32 op) { ERROR_LOG(G3D, "Invalid debugging environment, shutting down?"); return; } - if (count == 0) { + if (count == 0 || which == 0) { return; } @@ -182,18 +196,6 @@ void CGEDebugger::UpdatePrimPreview(u32 op) { float fw, fh; float x, y; - primaryWindow->Begin(); - primaryWindow->GetContentSize(x, y, fw, fh); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); - glBindTexture(GL_TEXTURE_2D, 0); - // The surface is upside down, so vertical offsets are negated. - glViewport((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh); - glScissor((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh); - BindPreviewProgram(previewProgram); - // TODO: Probably there's a better way and place to do this. u16 minIndex = 0; u16 maxIndex = count - 1; @@ -210,125 +212,155 @@ void CGEDebugger::UpdatePrimPreview(u32 op) { } } - const float invTexWidth = 1.0f / gstate_c.curTextureWidth; - const float invTexHeight = 1.0f / gstate_c.curTextureHeight; + auto wrapCoord = [](float &coord) { + if (coord < 0.0f) { + coord += ceilf(-coord); + } + if (coord > 1.0f) { + coord -= floorf(coord); + } + }; + + const float invTexWidth = 1.0f / gpuDebug->GetGState().getTextureWidth(0); + const float invTexHeight = 1.0f / gpuDebug->GetGState().getTextureHeight(0); + const float invRealTexWidth = 1.0f / gstate_c.curTextureWidth; + const float invRealTexHeight = 1.0f / gstate_c.curTextureHeight; + bool clampS = gpuDebug->GetGState().isTexCoordClampedS(); + bool clampT = gpuDebug->GetGState().isTexCoordClampedT(); for (u16 i = minIndex; i <= maxIndex; ++i) { vertices[i].u *= invTexWidth; vertices[i].v *= invTexHeight; - if (vertices[i].u > 1.0f || vertices[i].u < 0.0f) - vertices[i].u -= floor(vertices[i].u); - if (vertices[i].v > 1.0f || vertices[i].v < 0.0f) - vertices[i].v -= floor(vertices[i].v); + if (!clampS) + wrapCoord(vertices[i].u); + if (!clampT) + wrapCoord(vertices[i].v); } - if (previewVao == 0 && gl_extensions.ARB_vertex_array_object) { - glGenVertexArrays(1, &previewVao); - glBindVertexArray(previewVao); - glEnableVertexAttribArray(previewProgram->a_position); + if (which & 1) { + primaryWindow->Begin(); + primaryWindow->GetContentSize(x, y, fw, fh); - glGenBuffers(1, &ibuf); - glGenBuffers(1, &vbuf); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf); - glBindBuffer(GL_ARRAY_BUFFER, vbuf); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + glBindTexture(GL_TEXTURE_2D, 0); + // The surface is upside down, so vertical offsets are negated. + glViewport((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh); + glScissor((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh); + BindPreviewProgram(previewProgram); - glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (void *)(2 * sizeof(float))); + if (previewVao == 0 && gl_extensions.ARB_vertex_array_object) { + glGenVertexArrays(1, &previewVao); + glBindVertexArray(previewVao); + glEnableVertexAttribArray(previewProgram->a_position); + + glGenBuffers(1, &ibuf); + glGenBuffers(1, &vbuf); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf); + glBindBuffer(GL_ARRAY_BUFFER, vbuf); + + glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (void *)(2 * sizeof(float))); + } + + if (vbuf != 0) { + glBindBuffer(GL_ARRAY_BUFFER, vbuf); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW); + } + + if (ibuf != 0 && !indices.empty()) { + glBindVertexArray(previewVao); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW); + } + + float scale[] = { + 480.0f / (float)PSP_CoreParameter().renderWidth, + 272.0f / (float)PSP_CoreParameter().renderHeight, + }; + + Matrix4x4 ortho; + ortho.setOrtho(-(float)gstate_c.curRTOffsetX, (primaryWindow->TexWidth() - (int)gstate_c.curRTOffsetX) * scale[0], primaryWindow->TexHeight() * scale[1], 0, -1, 1); + glUniformMatrix4fv(previewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr()); + if (previewVao != 0) { + glBindVertexArray(previewVao); + } else { + glEnableVertexAttribArray(previewProgram->a_position); + glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data() + 2); + } + + if (indices.empty()) { + glDrawArrays(glprim[prim], 0, count); + } else { + glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, previewVao != 0 ? 0 : indices.data()); + } + + if (previewVao == 0) { + glDisableVertexAttribArray(previewProgram->a_position); + } + + primaryWindow->End(); } - if (vbuf != 0) { - glBindBuffer(GL_ARRAY_BUFFER, vbuf); - glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW); + if (which & 2) { + secondWindow->Begin(); + secondWindow->GetContentSize(x, y, fw, fh); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + glBindTexture(GL_TEXTURE_2D, 0); + // The surface is upside down, so vertical offsets are flipped. + glViewport((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh); + glScissor((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh); + BindPreviewProgram(texPreviewProgram); + + if (texPreviewVao == 0 && gl_extensions.ARB_vertex_array_object) { + glGenVertexArrays(1, &texPreviewVao); + glBindVertexArray(texPreviewVao); + glEnableVertexAttribArray(texPreviewProgram->a_position); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf); + glBindBuffer(GL_ARRAY_BUFFER, vbuf); + + glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0); + } + + // TODO: For some reason we have to re-upload the data? + if (vbuf != 0) { + glBindBuffer(GL_ARRAY_BUFFER, vbuf); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW); + } + + if (ibuf != 0 && !indices.empty()) { + glBindVertexArray(texPreviewVao); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW); + } + + Matrix4x4 ortho; + ortho.setOrtho(0.0f - (float)gstate_c.curTextureXOffset * invRealTexWidth, 1.0f - (float)gstate_c.curTextureXOffset * invRealTexWidth, 1.0f - (float)gstate_c.curTextureYOffset * invRealTexHeight, 0.0f - (float)gstate_c.curTextureYOffset * invRealTexHeight, -1.0f, 1.0f); + glUniformMatrix4fv(texPreviewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr()); + if (texPreviewVao != 0) { + glBindVertexArray(texPreviewVao); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf); + glBindBuffer(GL_ARRAY_BUFFER, vbuf); + glEnableVertexAttribArray(texPreviewProgram->a_position); + glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0); + } else { + glEnableVertexAttribArray(texPreviewProgram->a_position); + glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data()); + } + + if (indices.empty()) { + glDrawArrays(glprim[prim], 0, count); + } else { + glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, texPreviewVao != 0 ? 0 : indices.data()); + } + + if (texPreviewVao == 0) { + glDisableVertexAttribArray(previewProgram->a_position); + } + + secondWindow->End(); } - - if (ibuf != 0 && !indices.empty()) { - glBindVertexArray(previewVao); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW); - } - - float scale[] = { - 480.0f / (float)PSP_CoreParameter().renderWidth, - 272.0f / (float)PSP_CoreParameter().renderHeight, - }; - - Matrix4x4 ortho; - ortho.setOrtho(-(float)gstate_c.curRTOffsetX, (primaryWindow->TexWidth() - (int)gstate_c.curRTOffsetX) * scale[0], primaryWindow->TexHeight() * scale[1], 0, -1, 1); - glUniformMatrix4fv(previewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr()); - if (previewVao != 0) { - glBindVertexArray(previewVao); - } else { - glEnableVertexAttribArray(previewProgram->a_position); - glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data() + 2); - } - - if (indices.empty()) { - glDrawArrays(glprim[prim], 0, count); - } else { - glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, previewVao != 0 ? 0 : indices.data()); - } - - if (previewVao == 0) { - glDisableVertexAttribArray(previewProgram->a_position); - } - - primaryWindow->End(); - - secondWindow->Begin(); - secondWindow->GetContentSize(x, y, fw, fh); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); - glBindTexture(GL_TEXTURE_2D, 0); - // The surface is upside down, so vertical offsets are flipped. - glViewport((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh); - glScissor((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh); - BindPreviewProgram(texPreviewProgram); - - if (texPreviewVao == 0 && gl_extensions.ARB_vertex_array_object) { - glGenVertexArrays(1, &texPreviewVao); - glBindVertexArray(texPreviewVao); - glEnableVertexAttribArray(texPreviewProgram->a_position); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf); - glBindBuffer(GL_ARRAY_BUFFER, vbuf); - - glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0); - } - - // TODO: For some reason we have to re-upload the data? - if (vbuf != 0) { - glBindBuffer(GL_ARRAY_BUFFER, vbuf); - glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW); - } - - if (ibuf != 0 && !indices.empty()) { - glBindVertexArray(texPreviewVao); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW); - } - - ortho.setOrtho(0.0f - (float)gstate_c.curTextureXOffset * invTexWidth, 1.0f - (float)gstate_c.curTextureXOffset * invTexWidth, 1.0f - (float)gstate_c.curTextureYOffset * invTexHeight, 0.0f - (float)gstate_c.curTextureYOffset * invTexHeight, -1.0f, 1.0f); - glUniformMatrix4fv(texPreviewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr()); - if (texPreviewVao != 0) { - glBindVertexArray(texPreviewVao); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf); - glBindBuffer(GL_ARRAY_BUFFER, vbuf); - glEnableVertexAttribArray(texPreviewProgram->a_position); - glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0); - } else { - glEnableVertexAttribArray(texPreviewProgram->a_position); - glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data()); - } - - if (indices.empty()) { - glDrawArrays(glprim[prim], 0, count); - } else { - glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, texPreviewVao != 0 ? 0 : indices.data()); - } - - if (texPreviewVao == 0) { - glDisableVertexAttribArray(previewProgram->a_position); - } - - secondWindow->End(); } void CGEDebugger::CleanupPrimPreview() { @@ -339,3 +371,14 @@ void CGEDebugger::CleanupPrimPreview() { glsl_destroy(texPreviewProgram); } } + +void CGEDebugger::HandleRedraw(int which) { + if (updating_) { + return; + } + + u32 op = PrimPreviewOp(); + if (op) { + UpdatePrimPreview(op, which); + } +} From 3c5816e2aafd7841ff314b1f27cfb6358cc9e962 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Dec 2017 02:16:43 -0800 Subject: [PATCH 3/3] GE Debugger: Allow enable/disable of prim preview. --- Windows/GEDebugger/GEDebugger.cpp | 16 ++++++++++++++++ Windows/GEDebugger/GEDebugger.h | 1 + Windows/GEDebugger/SimpleGLWindow.cpp | 1 + Windows/GEDebugger/SimpleGLWindow.h | 1 + Windows/GEDebugger/VertexPreview.cpp | 1 + Windows/ppsspp.rc | 1 + Windows/resource.h | 3 ++- 7 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 1ffe5bdda5..2b1639971f 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -157,10 +157,18 @@ void CGEDebugger::SetupPreviews() { PrimaryPreviewHover(x, y); }); primaryWindow->SetRightClickMenu(subMenu, [&] (int cmd) { + HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_GEDBG_PREVIEW); switch (cmd) { + case 0: + // Setup. + CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 1) ? MF_CHECKED : MF_UNCHECKED)); + break; case ID_GEDBG_EXPORT_IMAGE: PreviewExport(primaryBuffer_); break; + case ID_GEDBG_ENABLE_PREVIEW: + previewsEnabled_ ^= 1; + primaryWindow->Redraw(); default: break; } @@ -181,10 +189,18 @@ void CGEDebugger::SetupPreviews() { SecondPreviewHover(x, y); }); secondWindow->SetRightClickMenu(subMenu, [&] (int cmd) { + HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_GEDBG_PREVIEW); switch (cmd) { + case 0: + // Setup. + CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 2) ? MF_CHECKED : MF_UNCHECKED)); + break; case ID_GEDBG_EXPORT_IMAGE: PreviewExport(secondBuffer_); break; + case ID_GEDBG_ENABLE_PREVIEW: + previewsEnabled_ ^= 2; + secondWindow->Redraw(); default: break; } diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index c541337de2..f47afc4236 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -109,6 +109,7 @@ private: const GPUDebugBuffer *secondBuffer_ = nullptr; bool updating_ = false; + int previewsEnabled_ = 3; int minWidth_; int minHeight_; }; diff --git a/Windows/GEDebugger/SimpleGLWindow.cpp b/Windows/GEDebugger/SimpleGLWindow.cpp index eab3370301..f9c06b5c02 100644 --- a/Windows/GEDebugger/SimpleGLWindow.cpp +++ b/Windows/GEDebugger/SimpleGLWindow.cpp @@ -563,6 +563,7 @@ bool SimpleGLWindow::RightClick(int mouseX, int mouseY) { POINT pt{mouseX, mouseY}; ClientToScreen(hWnd_, &pt); + rightClickCallback_(0); int result = TrackPopupMenuEx(rightClickMenu_, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hWnd_, 0); if (result != 0) { rightClickCallback_(result); diff --git a/Windows/GEDebugger/SimpleGLWindow.h b/Windows/GEDebugger/SimpleGLWindow.h index 7cc305d9ca..8628ab5eef 100644 --- a/Windows/GEDebugger/SimpleGLWindow.h +++ b/Windows/GEDebugger/SimpleGLWindow.h @@ -115,6 +115,7 @@ struct SimpleGLWindow { hoverCallback_ = hoverCallback; } + // Called first with 0 that it's opening, then the selected item. void SetRightClickMenu(HMENU menu, std::function callback) { rightClickCallback_ = callback; rightClickMenu_ = menu; diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index 4e91a35b6b..1f78554d91 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -176,6 +176,7 @@ void CGEDebugger::UpdatePrimPreview(u32 op, int which) { ERROR_LOG(G3D, "Invalid debugging environment, shutting down?"); return; } + which &= previewsEnabled_; if (count == 0 || which == 0) { return; } diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 58b2d4ed4b..867613bd9d 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -657,6 +657,7 @@ BEGIN POPUP "gepreviewoptions" BEGIN MENUITEM "Export Image...", ID_GEDBG_EXPORT_IMAGE + MENUITEM "Show Prim Preview" ID_GEDBG_ENABLE_PREVIEW END END diff --git a/Windows/resource.h b/Windows/resource.h index 32710e3859..ba90e1ac79 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -335,6 +335,7 @@ #define ID_HELP_GITHUB 40168 #define IDC_GEDBG_RECORD 40169 #define ID_GEDBG_EXPORT_IMAGE 40170 +#define ID_GEDBG_ENABLE_PREVIEW 40171 // Dummy option to let the buffered rendering hotkey cycle through all the options. #define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500 @@ -347,7 +348,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40171 +#define _APS_NEXT_COMMAND_VALUE 40172 #define _APS_NEXT_CONTROL_VALUE 1200 #define _APS_NEXT_SYMED_VALUE 101 #endif