mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-15 03:38:37 +00:00
Merge pull request #3885 from unknownbrackets/debugger
Initial interface/hooks for GE debugger
This commit is contained in:
commit
7767495565
@ -998,6 +998,7 @@ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/git-version.cpp
|
||||
add_dependencies(${CoreLibName} GitVersion)
|
||||
|
||||
add_library(GPU OBJECT
|
||||
GPU/Common/GPUDebugInterface.h
|
||||
GPU/Common/VertexDecoderCommon.cpp
|
||||
GPU/Common/VertexDecoderCommon.h
|
||||
GPU/Common/IndexGenerator.cpp
|
||||
|
11
Core/Host.h
11
Core/Host.h
@ -58,11 +58,18 @@ public:
|
||||
|
||||
virtual void SendCoreWait(bool) {}
|
||||
|
||||
// While debugging is active, it's perfectly fine for these to block.
|
||||
virtual bool GPUDebuggingActive() { return false; }
|
||||
virtual void GPUNotifyCommand(u32 pc) {}
|
||||
virtual void GPUNotifyDisplay(u32 framebuf, u32 stride, int format) {}
|
||||
virtual void GPUNotifyDraw() {}
|
||||
virtual void GPUNotifyTextureAttachment(u32 addr) {}
|
||||
virtual bool GPUAllowTextureCache(u32 addr) { return true; }
|
||||
|
||||
virtual bool GpuStep() { return false; }
|
||||
virtual void SendGPUStart() {}
|
||||
virtual void SendGPUWait(u32 cmd, u32 addr, void* data) {}
|
||||
virtual void SetGPUStep(bool value, int flag = 0, int data = 0) {}
|
||||
virtual void NextGPUStep() {}
|
||||
|
||||
virtual bool CanCreateShortcut() {return false;}
|
||||
virtual bool CreateDesktopShortcut(std::string argumentPath, std::string title) {return false;}
|
||||
|
||||
|
56
GPU/Common/GPUDebugInterface.h
Normal file
56
GPU/Common/GPUDebugInterface.h
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct GPUDebugOp {
|
||||
u32 pc;
|
||||
u8 cmd;
|
||||
u32 op;
|
||||
std::string desc;
|
||||
};
|
||||
|
||||
class GPUDebugInterface {
|
||||
public:
|
||||
virtual bool GetCurrentDisplayList(DisplayList &list) = 0;
|
||||
virtual std::vector<DisplayList> ActiveDisplayLists() = 0;
|
||||
virtual void ResetListPC(int listID, u32 pc) = 0;
|
||||
virtual void ResetListStall(int listID, u32 stall) = 0;
|
||||
virtual void ResetListState(int listID, DisplayListState state) = 0;
|
||||
|
||||
GPUDebugOp DissassembleOp(u32 pc) {
|
||||
return DissassembleOp(pc, Memory::Read_U32(pc));
|
||||
}
|
||||
virtual GPUDebugOp DissassembleOp(u32 pc, u32 op) = 0;
|
||||
virtual std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc) = 0;
|
||||
|
||||
virtual u32 GetRelativeAddress(u32 data) = 0;
|
||||
virtual u32 GetVertexAddress() = 0;
|
||||
virtual u32 GetIndexAddress() = 0;
|
||||
virtual GPUgstate GetGState() = 0;
|
||||
|
||||
// TODO:
|
||||
// cached framebuffers / textures / vertices?
|
||||
// get content of framebuffer / texture
|
||||
// vertex / texture decoding?
|
||||
};
|
@ -470,6 +470,7 @@ void DIRECTX9_GPU::BeginFrameInternal() {
|
||||
}
|
||||
|
||||
void DIRECTX9_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {
|
||||
host->GPUNotifyDisplay(framebuf, stride, format);
|
||||
framebufferManager_.SetDisplayFramebuffer(framebuf, stride, format);
|
||||
}
|
||||
|
||||
|
@ -165,9 +165,10 @@ inline void AttachFramebufferValid(T &entry, VirtualFramebufferDX9 *framebuffer)
|
||||
const bool hasInvalidFramebuffer = entry->framebuffer == 0 || entry->invalidHint == -1;
|
||||
const bool hasOlderFramebuffer = entry->framebuffer != 0 && entry->framebuffer->last_frame_render < framebuffer->last_frame_render;
|
||||
if (hasInvalidFramebuffer || hasOlderFramebuffer) {
|
||||
entry->framebuffer = framebuffer;
|
||||
entry->invalidHint = 0;
|
||||
}
|
||||
entry->framebuffer = framebuffer;
|
||||
entry->invalidHint = 0;
|
||||
host->GPUNotifyTextureAttachment(entry->addr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -175,6 +176,7 @@ inline void AttachFramebufferInvalid(T &entry, VirtualFramebufferDX9 *framebuffe
|
||||
if (entry->framebuffer == 0 || entry->framebuffer == framebuffer) {
|
||||
entry->framebuffer = framebuffer;
|
||||
entry->invalidHint = -1;
|
||||
host->GPUNotifyTextureAttachment(entry->addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,6 +222,7 @@ inline void TextureCacheDX9::AttachFramebuffer(TexCacheEntry *entry, u32 address
|
||||
inline void TextureCacheDX9::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebufferDX9 *framebuffer) {
|
||||
if (entry->framebuffer == framebuffer) {
|
||||
entry->framebuffer = 0;
|
||||
host->GPUNotifyTextureAttachment(entry->addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1083,6 +1086,9 @@ void TextureCacheDX9::SetTexture() {
|
||||
// Validate the texture still matches the cache entry.
|
||||
int dim = gstate.texsize[0] & 0xF0F;
|
||||
bool match = entry->Matches(dim, format, maxLevel);
|
||||
#ifndef _XBOX
|
||||
match &= host->GPUAllowTextureCache(texaddr);
|
||||
#endif
|
||||
|
||||
// Check for FBO - slow!
|
||||
if (entry->framebuffer && match) {
|
||||
|
@ -1332,6 +1332,10 @@ rotateVBO:
|
||||
collectedVerts = 0;
|
||||
numDrawCalls = 0;
|
||||
prevPrim_ = GE_PRIM_INVALID;
|
||||
|
||||
#ifndef _XBOX
|
||||
host->GPUNotifyDraw();
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -517,6 +517,7 @@ void GLES_GPU::BeginFrameInternal() {
|
||||
}
|
||||
|
||||
void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {
|
||||
host->GPUNotifyDisplay(framebuf, stride, format);
|
||||
framebufferManager_.SetDisplayFramebuffer(framebuf, stride, format);
|
||||
}
|
||||
|
||||
|
@ -163,6 +163,7 @@ inline void AttachFramebufferValid(T &entry, VirtualFramebuffer *framebuffer) {
|
||||
if (hasInvalidFramebuffer || hasOlderFramebuffer) {
|
||||
entry->framebuffer = framebuffer;
|
||||
entry->invalidHint = 0;
|
||||
host->GPUNotifyTextureAttachment(entry->addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,6 +172,7 @@ inline void AttachFramebufferInvalid(T &entry, VirtualFramebuffer *framebuffer)
|
||||
if (entry->framebuffer == 0 || entry->framebuffer == framebuffer) {
|
||||
entry->framebuffer = framebuffer;
|
||||
entry->invalidHint = -1;
|
||||
host->GPUNotifyTextureAttachment(entry->addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,6 +226,7 @@ inline void TextureCache::AttachFramebuffer(TexCacheEntry *entry, u32 address, V
|
||||
inline void TextureCache::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) {
|
||||
if (entry->framebuffer == framebuffer) {
|
||||
entry->framebuffer = 0;
|
||||
host->GPUNotifyTextureAttachment(entry->addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1039,6 +1042,9 @@ void TextureCache::SetTexture() {
|
||||
// Validate the texture still matches the cache entry.
|
||||
u16 dim = gstate.getTextureDimension(0);
|
||||
bool match = entry->Matches(dim, format, maxLevel);
|
||||
#ifndef USING_GLES2
|
||||
match &= host->GPUAllowTextureCache(texaddr);
|
||||
#endif
|
||||
|
||||
// Check for FBO - slow!
|
||||
if (entry->framebuffer && match) {
|
||||
|
@ -1228,4 +1228,8 @@ rotateVBO:
|
||||
collectedVerts = 0;
|
||||
numDrawCalls = 0;
|
||||
prevPrim_ = GE_PRIM_INVALID;
|
||||
|
||||
#ifndef USING_GLES2
|
||||
host->GPUNotifyDraw();
|
||||
#endif
|
||||
}
|
||||
|
@ -155,6 +155,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\ext\xbrz\xbrz.h" />
|
||||
<ClInclude Include="Common\GPUDebugInterface.h" />
|
||||
<ClInclude Include="Common\IndexGenerator.h" />
|
||||
<ClInclude Include="Common\VertexDecoderCommon.h" />
|
||||
<ClInclude Include="Directx9\GPU_DX9.h" />
|
||||
|
@ -141,6 +141,9 @@
|
||||
<ClInclude Include="Common\TextureDecoder.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\GPUDebugInterface.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Math3D.cpp">
|
||||
|
@ -475,6 +475,7 @@ bool GPUCommon::InterpretList(DisplayList &list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Use new interface.
|
||||
#if defined(USING_QT_UI)
|
||||
if (host->GpuStep()) {
|
||||
host->SendGPUStart();
|
||||
@ -489,9 +490,8 @@ bool GPUCommon::InterpretList(DisplayList &list) {
|
||||
gpuState = list.pc == list.stall ? GPUSTATE_STALL : GPUSTATE_RUNNING;
|
||||
guard.unlock();
|
||||
|
||||
const bool dumpThisFrame = dumpThisFrame_;
|
||||
// TODO: Add check for displaylist debugger.
|
||||
const bool useFastRunLoop = !dumpThisFrame;
|
||||
const bool useDebugger = host->GPUDebuggingActive();
|
||||
const bool useFastRunLoop = !dumpThisFrame_ && !useDebugger;
|
||||
while (gpuState == GPUSTATE_RUNNING) {
|
||||
{
|
||||
easy_guard innerGuard(listLock);
|
||||
@ -537,9 +537,11 @@ void GPUCommon::SlowRunLoop(DisplayList &list)
|
||||
const bool dumpThisFrame = dumpThisFrame_;
|
||||
while (downcount > 0)
|
||||
{
|
||||
host->GPUNotifyCommand(list.pc);
|
||||
u32 op = Memory::ReadUnchecked_U32(list.pc);
|
||||
u32 cmd = op >> 24;
|
||||
|
||||
// TODO: Replace.
|
||||
#if defined(USING_QT_UI)
|
||||
if (host->GpuStep())
|
||||
host->SendGPUWait(cmd, list.pc, &gstate);
|
||||
@ -974,3 +976,101 @@ void GPUCommon::SyncEnd(WaitType waitType, int listid, bool wokeThreads) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GPUCommon::GetCurrentDisplayList(DisplayList &list) {
|
||||
easy_guard guard(listLock);
|
||||
if (!currentList) {
|
||||
return false;
|
||||
}
|
||||
list = *currentList;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<DisplayList> GPUCommon::ActiveDisplayLists() {
|
||||
std::vector<DisplayList> result;
|
||||
|
||||
easy_guard guard(listLock);
|
||||
for (auto it = dlQueue.begin(), end = dlQueue.end(); it != end; ++it) {
|
||||
result.push_back(dls[*it]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void GPUCommon::ResetListPC(int listID, u32 pc) {
|
||||
if (listID < 0 || listID >= DisplayListMaxCount) {
|
||||
_dbg_assert_msg_(G3D, false, "listID out of range: %d", listID);
|
||||
return;
|
||||
}
|
||||
|
||||
easy_guard guard(listLock);
|
||||
dls[listID].pc = pc;
|
||||
}
|
||||
|
||||
void GPUCommon::ResetListStall(int listID, u32 stall) {
|
||||
if (listID < 0 || listID >= DisplayListMaxCount) {
|
||||
_dbg_assert_msg_(G3D, false, "listID out of range: %d", listID);
|
||||
return;
|
||||
}
|
||||
|
||||
easy_guard guard(listLock);
|
||||
dls[listID].stall = stall;
|
||||
}
|
||||
|
||||
void GPUCommon::ResetListState(int listID, DisplayListState state) {
|
||||
if (listID < 0 || listID >= DisplayListMaxCount) {
|
||||
_dbg_assert_msg_(G3D, false, "listID out of range: %d", listID);
|
||||
return;
|
||||
}
|
||||
|
||||
easy_guard guard(listLock);
|
||||
dls[listID].state = state;
|
||||
}
|
||||
|
||||
GPUDebugOp GPUCommon::DissassembleOp(u32 pc, u32 op) {
|
||||
char buffer[1024];
|
||||
GeDisassembleOp(pc, op, Memory::Read_U32(pc - 4), buffer);
|
||||
|
||||
GPUDebugOp info;
|
||||
info.pc = pc;
|
||||
info.cmd = op >> 24;
|
||||
info.op = op;
|
||||
info.desc = buffer;
|
||||
return info;
|
||||
}
|
||||
|
||||
std::vector<GPUDebugOp> GPUCommon::DissassembleOpRange(u32 startpc, u32 endpc) {
|
||||
char buffer[1024];
|
||||
std::vector<GPUDebugOp> result;
|
||||
GPUDebugOp info;
|
||||
|
||||
u32 prev = Memory::Read_U32(startpc - 4);
|
||||
for (u32 pc = startpc; pc < endpc; pc += 4) {
|
||||
u32 op = Memory::Read_U32(pc);
|
||||
GeDisassembleOp(pc, op, prev, buffer);
|
||||
prev = op;
|
||||
|
||||
info.pc = pc;
|
||||
info.cmd = op >> 24;
|
||||
info.op = op;
|
||||
info.desc = buffer;
|
||||
result.push_back(info);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 GPUCommon::GetRelativeAddress(u32 data) {
|
||||
return gstate_c.getRelativeAddress(data);
|
||||
}
|
||||
|
||||
u32 GPUCommon::GetVertexAddress() {
|
||||
return gstate_c.vertexAddr;
|
||||
}
|
||||
|
||||
u32 GPUCommon::GetIndexAddress() {
|
||||
return gstate_c.indexAddr;
|
||||
}
|
||||
|
||||
GPUgstate GPUCommon::GetGState() {
|
||||
return gstate;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Common/Common.h"
|
||||
#include "Core/ThreadEventQueue.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/Common/GPUDebugInterface.h"
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <atomic>
|
||||
@ -12,7 +13,7 @@
|
||||
|
||||
typedef ThreadEventQueue<GPUInterface, GPUEvent, GPUEventType, GPU_EVENT_INVALID, GPU_EVENT_SYNC_THREAD, GPU_EVENT_FINISH_EVENT_LOOP> GPUThreadEventQueue;
|
||||
|
||||
class GPUCommon : public GPUThreadEventQueue
|
||||
class GPUCommon : public GPUThreadEventQueue, public GPUDebugInterface
|
||||
{
|
||||
public:
|
||||
GPUCommon();
|
||||
@ -137,6 +138,21 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
// From GPUDebugInterface.
|
||||
virtual bool GetCurrentDisplayList(DisplayList &list);
|
||||
virtual std::vector<DisplayList> ActiveDisplayLists();
|
||||
virtual void ResetListPC(int listID, u32 pc);
|
||||
virtual void ResetListStall(int listID, u32 stall);
|
||||
virtual void ResetListState(int listID, DisplayListState state);
|
||||
|
||||
virtual GPUDebugOp DissassembleOp(u32 pc, u32 op);
|
||||
virtual std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc);
|
||||
|
||||
virtual u32 GetRelativeAddress(u32 data);
|
||||
virtual u32 GetVertexAddress();
|
||||
virtual u32 GetIndexAddress();
|
||||
virtual GPUgstate GetGState();
|
||||
|
||||
virtual DisplayList* getList(int listid)
|
||||
{
|
||||
return &dls[listid];
|
||||
@ -146,10 +162,6 @@ public:
|
||||
{
|
||||
return dlQueue;
|
||||
}
|
||||
DisplayList* GetCurrentDisplayList()
|
||||
{
|
||||
return currentList;
|
||||
}
|
||||
virtual bool DecodeTexture(u8* dest, GPUgstate state)
|
||||
{
|
||||
return false;
|
||||
|
@ -244,7 +244,6 @@ public:
|
||||
virtual void DumpNextFrame() = 0;
|
||||
virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) = 0;
|
||||
virtual const std::list<int>& GetDisplayLists() = 0;
|
||||
virtual DisplayList* GetCurrentDisplayList() = 0;
|
||||
virtual bool DecodeTexture(u8* dest, GPUgstate state) = 0;
|
||||
virtual std::vector<FramebufferInfo> GetFramebufferList() = 0;
|
||||
};
|
||||
|
@ -33,28 +33,33 @@
|
||||
GPUgstate gstate;
|
||||
GPUStateCache gstate_c;
|
||||
GPUInterface *gpu;
|
||||
GPUDebugInterface *gpuDebug;
|
||||
GPUStatistics gpuStats;
|
||||
|
||||
template <typename T>
|
||||
static void SetGPU(T *obj) {
|
||||
gpu = obj;
|
||||
gpuDebug = obj;
|
||||
}
|
||||
|
||||
bool GPU_Init() {
|
||||
switch (PSP_CoreParameter().gpuCore) {
|
||||
case GPU_NULL:
|
||||
gpu = new NullGPU();
|
||||
SetGPU(new NullGPU());
|
||||
break;
|
||||
case GPU_GLES:
|
||||
#ifndef _XBOX
|
||||
gpu = new GLES_GPU();
|
||||
SetGPU(new GLES_GPU());
|
||||
#endif
|
||||
break;
|
||||
case GPU_SOFTWARE:
|
||||
#if !(defined(__SYMBIAN32__) || defined(_XBOX))
|
||||
gpu = new SoftGPU();
|
||||
SetGPU(new SoftGPU());
|
||||
#endif
|
||||
break;
|
||||
case GPU_DIRECTX9:
|
||||
#if defined(_XBOX)
|
||||
gpu = new DIRECTX9_GPU();
|
||||
#elif defined(_WIN32)
|
||||
gpu = new DIRECTX9_GPU();
|
||||
#if defined(_XBOX) || defined(_WIN32)
|
||||
SetGPU(new DIRECTX9_GPU());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -65,6 +70,7 @@ bool GPU_Init() {
|
||||
void GPU_Shutdown() {
|
||||
delete gpu;
|
||||
gpu = 0;
|
||||
gpuDebug = 0;
|
||||
}
|
||||
|
||||
void InitGfxState() {
|
||||
|
@ -516,10 +516,12 @@ void ShutdownGfxState();
|
||||
void ReapplyGfxState();
|
||||
|
||||
class GPUInterface;
|
||||
class GPUDebugInterface;
|
||||
|
||||
extern GPUgstate gstate;
|
||||
extern GPUStateCache gstate_c;
|
||||
extern GPUInterface *gpu;
|
||||
extern GPUDebugInterface *gpuDebug;
|
||||
extern GPUStatistics gpuStats;
|
||||
|
||||
inline u32 GPUStateCache::getRelativeAddress(u32 data) const {
|
||||
|
@ -54,7 +54,9 @@ public:
|
||||
virtual void ExecuteOp(u32 op, u32 diff);
|
||||
|
||||
virtual void BeginFrame() {}
|
||||
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {}
|
||||
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {
|
||||
host->GPUNotifyDisplay(framebuf, stride, format);
|
||||
}
|
||||
virtual void CopyDisplayToOutput();
|
||||
virtual void UpdateStats();
|
||||
virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type);
|
||||
|
@ -15,6 +15,7 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "Core/Host.h"
|
||||
#include "../GPUState.h"
|
||||
#include "../GLES/VertexDecoder.h"
|
||||
|
||||
@ -258,6 +259,7 @@ void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_
|
||||
}
|
||||
}
|
||||
delete[] patches;
|
||||
host->GPUNotifyDraw();
|
||||
}
|
||||
|
||||
void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type, int vertex_count, u32 vertex_type)
|
||||
@ -402,4 +404,6 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
host->GPUNotifyDraw();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/GeDisasm.h"
|
||||
#include "GPU/Common/GPUDebugInterface.h"
|
||||
#include "EmuThread.h"
|
||||
#include "Core/Host.h"
|
||||
|
||||
@ -546,8 +547,9 @@ void Debugger_Disasm::UpdateDisplayListGUI()
|
||||
EmuThread_LockDraw(true);
|
||||
const std::list<int>& dlQueue = gpu->GetDisplayLists();
|
||||
|
||||
DisplayList* dl = gpu->GetCurrentDisplayList();
|
||||
if(dl)
|
||||
DisplayList dlist;
|
||||
DisplayList* dl = &dlist;
|
||||
if(gpuDebug->GetCurrentDisplayList(dlist))
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
item->setText(0,QString::number(dl->id));
|
||||
|
94
Windows/Debugger/GEDebugger.cpp
Normal file
94
Windows/Debugger/GEDebugger.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "native/base/mutex.h"
|
||||
#include "Windows/Debugger/GEDebugger.h"
|
||||
#include "Windows/WindowsHost.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/Common/GPUDebugInterface.h"
|
||||
#include "GPU/GPUState.h"
|
||||
|
||||
static bool attached = false;
|
||||
// TODO
|
||||
static bool textureCaching = true;
|
||||
static recursive_mutex pauseLock;
|
||||
static condition_variable pauseWait;
|
||||
|
||||
static bool breakNext = false;
|
||||
|
||||
CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
|
||||
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent) {
|
||||
}
|
||||
|
||||
BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
return TRUE;
|
||||
|
||||
case WM_SIZE:
|
||||
// TODO
|
||||
return TRUE;
|
||||
|
||||
case WM_CLOSE:
|
||||
Show(false);
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDC_GEDBG_BREAK:
|
||||
attached = true;
|
||||
breakNext = true;
|
||||
break;
|
||||
|
||||
case IDC_GEDBG_RESUME:
|
||||
// TODO: detach? Should probably have separate UI, or just on activate?
|
||||
breakNext = false;
|
||||
pauseWait.notify_one();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// The below WindowsHost methods are called on the GPU thread.
|
||||
|
||||
bool WindowsHost::GPUDebuggingActive() {
|
||||
return attached;
|
||||
}
|
||||
|
||||
void WindowsHost::GPUNotifyCommand(u32 pc) {
|
||||
if (breakNext) {
|
||||
auto info = gpuDebug->DissassembleOp(pc);
|
||||
NOTICE_LOG(HLE, "waiting at %08x, %s", pc, info.desc.c_str());
|
||||
lock_guard guard(pauseLock);
|
||||
pauseWait.wait(pauseLock);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsHost::GPUNotifyDisplay(u32 framebuf, u32 stride, int format) {
|
||||
}
|
||||
|
||||
void WindowsHost::GPUNotifyDraw() {
|
||||
}
|
||||
|
||||
void WindowsHost::GPUNotifyTextureAttachment(u32 addr) {
|
||||
}
|
||||
|
||||
bool WindowsHost::GPUAllowTextureCache(u32 addr) {
|
||||
return textureCaching;
|
||||
}
|
31
Windows/Debugger/GEDebugger.h
Normal file
31
Windows/Debugger/GEDebugger.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "Globals.h"
|
||||
#include "Windows/resource.h"
|
||||
#include "Windows/W32Util/DialogManager.h"
|
||||
|
||||
class CGEDebugger : public Dialog {
|
||||
public:
|
||||
CGEDebugger(HINSTANCE _hInstance, HWND _hParent);
|
||||
|
||||
protected:
|
||||
BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
};
|
@ -279,6 +279,7 @@
|
||||
<ClCompile Include="Debugger\Debugger_Lists.cpp" />
|
||||
<ClCompile Include="Debugger\Debugger_MemoryDlg.cpp" />
|
||||
<ClCompile Include="Debugger\Debugger_VFPUDlg.cpp" />
|
||||
<ClCompile Include="Debugger\GEDebugger.cpp" />
|
||||
<ClCompile Include="DinputDevice.cpp" />
|
||||
<ClCompile Include="EmuThread.cpp" />
|
||||
<ClCompile Include="InputDevice.cpp" />
|
||||
@ -320,6 +321,7 @@
|
||||
<ClInclude Include="Debugger\Debugger_Lists.h" />
|
||||
<ClInclude Include="Debugger\Debugger_MemoryDlg.h" />
|
||||
<ClInclude Include="Debugger\Debugger_VFPUDlg.h" />
|
||||
<ClInclude Include="Debugger\GEDebugger.h" />
|
||||
<ClInclude Include="DinputDevice.h" />
|
||||
<ClInclude Include="EmuThread.h" />
|
||||
<ClInclude Include="InputDevice.h" />
|
||||
|
@ -110,6 +110,9 @@
|
||||
<ClCompile Include="Debugger\Debugger_Lists.cpp">
|
||||
<Filter>Windows\Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger\GEDebugger.cpp">
|
||||
<Filter>Windows\Debugger</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Debugger\CtrlDisAsmView.h">
|
||||
@ -197,6 +200,9 @@
|
||||
<ClInclude Include="Debugger\Debugger_Lists.h">
|
||||
<Filter>Windows\Debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debugger\GEDebugger.h">
|
||||
<Filter>Windows\Debugger</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="icon1.ico">
|
||||
|
@ -56,6 +56,13 @@ public:
|
||||
void SaveSymbolMap();
|
||||
void SetWindowTitle(const char *message);
|
||||
|
||||
virtual bool GPUDebuggingActive();
|
||||
virtual void GPUNotifyCommand(u32 pc);
|
||||
virtual void GPUNotifyDisplay(u32 framebuf, u32 stride, int format);
|
||||
virtual void GPUNotifyDraw();
|
||||
virtual void GPUNotifyTextureAttachment(u32 addr);
|
||||
virtual bool GPUAllowTextureCache(u32 addr);
|
||||
|
||||
virtual bool CanCreateShortcut() {return false;} // Turn on when fixed
|
||||
virtual bool CreateDesktopShortcut(std::string argumentPath, std::string title);
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "Windows/OpenGLBase.h"
|
||||
#include "Windows/Debugger/Debugger_Disasm.h"
|
||||
#include "Windows/Debugger/Debugger_MemoryDlg.h"
|
||||
#include "Windows/Debugger/GEDebugger.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "Core/Core.h"
|
||||
@ -499,6 +500,7 @@ namespace MainWindow
|
||||
TranslateMenuItem(ID_DEBUG_IGNOREILLEGALREADS);
|
||||
TranslateMenuItem(ID_DEBUG_RUNONLOAD);
|
||||
TranslateMenuItem(ID_DEBUG_DISASSEMBLY, L"\tCtrl+D");
|
||||
TranslateMenuItem(ID_DEBUG_GEDEBUGGER);
|
||||
TranslateMenuItem(ID_DEBUG_LOG, L"\tCtrl+L");
|
||||
TranslateMenuItem(ID_DEBUG_MEMORYVIEW, L"\tCtrl+M");
|
||||
|
||||
@ -739,6 +741,9 @@ namespace MainWindow
|
||||
DialogManager::AddDlg(disasmWindow[0]);
|
||||
disasmWindow[0]->Show(g_Config.bShowDebuggerOnLoad);
|
||||
|
||||
geDebuggerWindow = new CGEDebugger(MainWindow::GetHInstance(), MainWindow::GetHWND());
|
||||
DialogManager::AddDlg(geDebuggerWindow);
|
||||
|
||||
memoryWindow[0] = new CMemoryDlg(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS);
|
||||
DialogManager::AddDlg(memoryWindow[0]);
|
||||
}
|
||||
@ -1268,6 +1273,10 @@ namespace MainWindow
|
||||
disasmWindow[0]->Show(true);
|
||||
break;
|
||||
|
||||
case ID_DEBUG_GEDEBUGGER:
|
||||
geDebuggerWindow->Show(true);
|
||||
break;
|
||||
|
||||
case ID_DEBUG_MEMORYVIEW:
|
||||
memoryWindow[0]->Show(true);
|
||||
break;
|
||||
|
@ -37,8 +37,10 @@
|
||||
#include "Windows/resource.h"
|
||||
|
||||
#include "Windows/WndMainWindow.h"
|
||||
#include "Windows/Debugger/Debugger_Disasm.h"
|
||||
#include "Windows/Debugger/Debugger_MemoryDlg.h"
|
||||
#include "Windows/Debugger/Debugger_VFPUDlg.h"
|
||||
#include "Windows/Debugger/GEDebugger.h"
|
||||
|
||||
#include "Windows/W32Util/DialogManager.h"
|
||||
|
||||
@ -50,6 +52,7 @@
|
||||
#include "Windows/main.h"
|
||||
|
||||
CDisasm *disasmWindow[MAX_CPUCOUNT] = {0};
|
||||
CGEDebugger *geDebuggerWindow = 0;
|
||||
CMemoryDlg *memoryWindow[MAX_CPUCOUNT] = {0};
|
||||
|
||||
static std::string langRegion;
|
||||
|
@ -20,12 +20,14 @@
|
||||
|
||||
#include "Debugger/Debugger_Disasm.h"
|
||||
#include "Debugger/Debugger_MemoryDlg.h"
|
||||
#include "Windows/Debugger/GEDebugger.h"
|
||||
|
||||
#include "Common/CommonWindows.h"
|
||||
|
||||
#define MAX_CPUCOUNT 1
|
||||
|
||||
extern CDisasm *disasmWindow[MAX_CPUCOUNT];
|
||||
extern CGEDebugger *geDebuggerWindow ;
|
||||
extern CMemoryDlg *memoryWindow[MAX_CPUCOUNT];
|
||||
|
||||
extern HMENU g_hPopupMenus;
|
||||
|
@ -163,6 +163,17 @@ BEGIN
|
||||
CONTROL "",IDC_STACKFRAMES,"SysListView32",LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_REPORT | WS_BORDER,1,338,513,93
|
||||
END
|
||||
|
||||
IDD_GEDEBUGGER DIALOGEX 0, 0, 500, 400
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
EXSTYLE WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW
|
||||
CAPTION "GE"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x1
|
||||
BEGIN
|
||||
PUSHBUTTON "Break",IDC_GEDBG_BREAK,0,0,48,14
|
||||
PUSHBUTTON "Resume",IDC_GEDBG_RESUME,52,0,48,14
|
||||
CTEXT "Not yet implemented",IDC_STATIC,20,100,460,14
|
||||
END
|
||||
|
||||
#include "aboutbox.rc"
|
||||
|
||||
IDD_MEMORY DIALOGEX 0, 0, 566, 287
|
||||
@ -341,6 +352,7 @@ BEGIN
|
||||
MENUITEM "Run on Load", ID_DEBUG_RUNONLOAD
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Disassembly", ID_DEBUG_DISASSEMBLY
|
||||
MENUITEM "GE Debugger...", ID_DEBUG_GEDEBUGGER
|
||||
MENUITEM "Log Console", ID_DEBUG_LOG
|
||||
MENUITEM "Memory View...", ID_DEBUG_MEMORYVIEW
|
||||
END
|
||||
|
@ -76,6 +76,7 @@
|
||||
#define ID_DEBUG_DSIPLAYREGISTERLIST 247
|
||||
#define ID_DEBUG_DSIPLAYFUNCTIONLIST 248
|
||||
#define ID_MEMVIEW_COPYADDRESS 249
|
||||
#define IDD_GEDEBUGGER 250
|
||||
|
||||
#define IDC_STOPGO 1001
|
||||
#define IDC_ADDRESS 1002
|
||||
@ -257,6 +258,9 @@
|
||||
#define ID_OPTIONS_SCREEN8X 40113
|
||||
#define ID_OPTIONS_SCREEN9X 40114
|
||||
#define ID_OPTIONS_SCREEN10X 40115
|
||||
#define ID_DEBUG_GEDEBUGGER 40116
|
||||
#define IDC_GEDBG_BREAK 40117
|
||||
#define IDC_GEDBG_RESUME 40118
|
||||
|
||||
// Dummy option to let the buffered rendering hotkey cycle through all the options.
|
||||
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
|
||||
@ -268,8 +272,8 @@
|
||||
// Next default values for new objects
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 236
|
||||
#define _APS_NEXT_COMMAND_VALUE 40193
|
||||
#define _APS_NEXT_RESOURCE_VALUE 251
|
||||
#define _APS_NEXT_COMMAND_VALUE 40119
|
||||
#define _APS_NEXT_CONTROL_VALUE 1181
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user