committed by
bunnei
4 changed files with 108 additions and 3 deletions
-
6src/core/hle/service/gsp.cpp
-
97src/video_core/gpu_debugger.h
-
5src/video_core/video_core.vcxproj
-
3src/video_core/video_core.vcxproj.filters
@ -0,0 +1,97 @@ |
|||
// Copyright 2014 Citra Emulator Project |
|||
// Licensed under GPLv2 |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <algorithm> |
|||
#include <functional> |
|||
#include <vector> |
|||
|
|||
#include "common/log.h" |
|||
|
|||
#include "core/hle/service/gsp.h" |
|||
|
|||
|
|||
class GraphicsDebugger |
|||
{ |
|||
public: |
|||
// Base class for all objects which need to be notified about GPU events |
|||
class DebuggerObserver |
|||
{ |
|||
public: |
|||
DebuggerObserver() : observed(nullptr) { } |
|||
|
|||
virtual ~DebuggerObserver() |
|||
{ |
|||
if (observed) |
|||
observed->UnregisterObserver(this); |
|||
} |
|||
|
|||
/** |
|||
* Called when a GX command has been processed and is ready for being |
|||
* read via GraphicsDebugger::ReadGXCommandHistory. |
|||
* @param total_command_count Total number of commands in the GX history |
|||
* @note All methods in this class are called from the GSP thread |
|||
*/ |
|||
virtual void GXCommandProcessed(int total_command_count) |
|||
{ |
|||
const GSP_GPU::GXCommand& cmd = observed->ReadGXCommandHistory(total_command_count-1); |
|||
ERROR_LOG(GSP, "Received command: id=%x", cmd.id); |
|||
} |
|||
|
|||
protected: |
|||
GraphicsDebugger* GetDebugger() |
|||
{ |
|||
return observed; |
|||
} |
|||
|
|||
private: |
|||
GraphicsDebugger* observed; |
|||
bool in_destruction; |
|||
|
|||
friend class GraphicsDebugger; |
|||
}; |
|||
|
|||
void GXCommandProcessed(u8* command_data) |
|||
{ |
|||
gx_command_history.push_back(GSP_GPU::GXCommand()); |
|||
GSP_GPU::GXCommand& cmd = gx_command_history[gx_command_history.size()-1]; |
|||
|
|||
const int cmd_length = sizeof(GSP_GPU::GXCommand); |
|||
memcpy(cmd.data, command_data, cmd_length); |
|||
|
|||
ForEachObserver([this](DebuggerObserver* observer) { |
|||
observer->GXCommandProcessed(this->gx_command_history.size()); |
|||
} ); |
|||
} |
|||
|
|||
const GSP_GPU::GXCommand& ReadGXCommandHistory(int index) const |
|||
{ |
|||
// TODO: Is this thread-safe? |
|||
return gx_command_history[index]; |
|||
} |
|||
|
|||
void RegisterObserver(DebuggerObserver* observer) |
|||
{ |
|||
// TODO: Check for duplicates |
|||
observers.push_back(observer); |
|||
observer->observed = this; |
|||
} |
|||
|
|||
void UnregisterObserver(DebuggerObserver* observer) |
|||
{ |
|||
std::remove(observers.begin(), observers.end(), observer); |
|||
observer->observed = nullptr; |
|||
} |
|||
|
|||
private: |
|||
void ForEachObserver(std::function<void (DebuggerObserver*)> func) |
|||
{ |
|||
std::for_each(observers.begin(),observers.end(), func); |
|||
} |
|||
|
|||
std::vector<DebuggerObserver*> observers; |
|||
|
|||
std::vector<GSP_GPU::GXCommand> gx_command_history; |
|||
}; |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue