void CGEDebugger::UpdateTextureLevel(int level) { GPUgstate state = {0}; if (gpuDebug != NULL) { state = gpuDebug->GetGState(); } int maxValid = 0; for (int i = 1; i < state.getTextureMaxLevel() + 1; ++i) { if (state.getTextureAddress(i) != 0) { maxValid = i; } } textureLevel_ = std::min(std::max(0, level), maxValid); EnableWindow(GetDlgItem(m_hDlg, IDC_GEDBG_TEXLEVELDOWN), textureLevel_ > 0); EnableWindow(GetDlgItem(m_hDlg, IDC_GEDBG_TEXLEVELUP), textureLevel_ < maxValid); }
void CGEDebugger::UpdatePreviews() { auto memLock = Memory::Lock(); if (!PSP_IsInited()) { return; } wchar_t desc[256]; const GPUDebugBuffer *primaryBuffer = NULL; bool bufferResult = false; GPUgstate state = {0}; if (gpuDebug != NULL) { state = gpuDebug->GetGState(); } switch (PrimaryDisplayType(fbTabs->CurrentTabIndex())) { case PRIMARY_FRAMEBUF: bufferResult = GPU_GetCurrentFramebuffer(primaryBuffer); if (bufferResult) { _snwprintf(desc, ARRAY_SIZE(desc), L"Color: 0x%08x (%dx%d) fmt %i", state.getFrameBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight(), state.FrameBufFormat()); } break; case PRIMARY_DEPTHBUF: bufferResult = GPU_GetCurrentDepthbuffer(primaryBuffer); if (bufferResult) { _snwprintf(desc, ARRAY_SIZE(desc), L"Depth: 0x%08x (%dx%d)", state.getDepthBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight()); } break; case PRIMARY_STENCILBUF: bufferResult = GPU_GetCurrentStencilbuffer(primaryBuffer); if (bufferResult) { _snwprintf(desc, ARRAY_SIZE(desc), L"Stencil: 0x%08x (%dx%d)", state.getFrameBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight()); } break; } if (bufferResult && primaryBuffer != NULL) { auto fmt = SimpleGLWindow::Format(primaryBuffer->GetFormat()); frameWindow->Draw(primaryBuffer->GetData(), primaryBuffer->GetStride(), primaryBuffer->GetHeight(), primaryBuffer->GetFlipped(), fmt); SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, desc); } else if (frameWindow != NULL) { frameWindow->Clear(); SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, L"Failed"); } const GPUDebugBuffer *bufferTex = NULL; UpdateTextureLevel(textureLevel_); bufferResult = GPU_GetCurrentTexture(bufferTex, textureLevel_); if (bufferResult) { auto fmt = SimpleGLWindow::Format(bufferTex->GetFormat()); texWindow->Draw(bufferTex->GetData(), bufferTex->GetStride(), bufferTex->GetHeight(), bufferTex->GetFlipped(), fmt); if (gpuDebug != NULL) { if (state.isTextureAlphaUsed()) { texWindow->SetFlags(SimpleGLWindow::ALPHA_BLEND | SimpleGLWindow::RESIZE_SHRINK_CENTER); } else { texWindow->SetFlags(SimpleGLWindow::RESIZE_SHRINK_CENTER); } _snwprintf(desc, ARRAY_SIZE(desc), L"Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_)); SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc); UpdateLastTexture(state.getTextureAddress(textureLevel_)); } else { UpdateLastTexture((u32)-1); } } else if (texWindow != NULL) { texWindow->Clear(); if (gpuDebug == NULL || state.isTextureMapEnabled()) { SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"Texture: failed"); } else { SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"Texture: disabled"); } UpdateLastTexture((u32)-1); } DisplayList list; if (gpuDebug != NULL && gpuDebug->GetCurrentDisplayList(list)) { const u32 op = Memory::Read_U32(list.pc); const u32 cmd = op >> 24; // TODO: Bezier/spline? if (cmd == GE_CMD_PRIM) { UpdatePrimPreview(op); } displayList->setDisplayList(list); } flags->Update(); lighting->Update(); textureState->Update(); settings->Update(); vertices->Update(); matrices->Update(); lists->Update(); }
void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPUgstate &gstate) { params->fb_addr = gstate.getFrameBufAddress(); params->fb_address = gstate.getFrameBufRawAddress(); params->fb_stride = gstate.FrameBufStride(); params->z_address = gstate.getDepthBufRawAddress(); params->z_stride = gstate.DepthBufStride(); params->fmt = gstate.FrameBufFormat(); params->isClearingDepth = gstate.isModeClear() && gstate.isClearModeDepthMask(); // Technically, it may write depth later, but we're trying to detect it only when it's really true. if (gstate.isModeClear()) { // Not quite seeing how this makes sense.. params->isWritingDepth = !gstate.isClearModeDepthMask() && gstate.isDepthWriteEnabled(); } else { params->isWritingDepth = gstate.isDepthWriteEnabled(); } params->isDrawing = !gstate.isModeClear() || !gstate.isClearModeColorMask() || !gstate.isClearModeAlphaMask(); params->isModeThrough = gstate.isModeThrough(); // Viewport-X1 and Y1 are not the upper left corner, but half the width/height. A bit confusing. params->viewportWidth = (int)(fabsf(gstate.getViewportXScale()*2.0f)); params->viewportHeight = (int)(fabsf(gstate.getViewportYScale()*2.0f)); params->regionWidth = gstate.getRegionX2() + 1; params->regionHeight = gstate.getRegionY2() + 1; params->scissorWidth = gstate.getScissorX2() + 1; params->scissorHeight = gstate.getScissorY2() + 1; }