Browse Source
yuzu: Remove Maxwell debugger
yuzu: Remove Maxwell debugger
This was carried from Citra and wasn't really used on yuzu. It also adds some runtime overhead. This commit removes it from yuzu's codebase.nce_cpp
14 changed files with 0 additions and 640 deletions
-
10src/core/core.cpp
-
4src/core/core.h
-
2src/video_core/CMakeLists.txt
-
49src/video_core/debug_utils/debug_utils.cpp
-
157src/video_core/debug_utils/debug_utils.h
-
31src/video_core/engines/maxwell_3d.cpp
-
5src/yuzu/CMakeLists.txt
-
27src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp
-
33src/yuzu/debugger/graphics/graphics_breakpoint_observer.h
-
221src/yuzu/debugger/graphics/graphics_breakpoints.cpp
-
45src/yuzu/debugger/graphics/graphics_breakpoints.h
-
37src/yuzu/debugger/graphics/graphics_breakpoints_p.h
-
11src/yuzu/main.cpp
-
8src/yuzu/main.h
@ -1,49 +0,0 @@ |
|||
// Copyright 2014 Citra Emulator Project
|
|||
// Licensed under GPLv2
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <mutex>
|
|||
|
|||
#include "video_core/debug_utils/debug_utils.h"
|
|||
|
|||
namespace Tegra { |
|||
|
|||
void DebugContext::DoOnEvent(Event event, void* data) { |
|||
{ |
|||
std::unique_lock lock{breakpoint_mutex}; |
|||
|
|||
// TODO(Subv): Commit the rasterizer's caches so framebuffers, render targets, etc. will
|
|||
// show on debug widgets
|
|||
|
|||
// TODO: Should stop the CPU thread here once we multithread emulation.
|
|||
|
|||
active_breakpoint = event; |
|||
at_breakpoint = true; |
|||
|
|||
// Tell all observers that we hit a breakpoint
|
|||
for (auto& breakpoint_observer : breakpoint_observers) { |
|||
breakpoint_observer->OnMaxwellBreakPointHit(event, data); |
|||
} |
|||
|
|||
// Wait until another thread tells us to Resume()
|
|||
resume_from_breakpoint.wait(lock, [&] { return !at_breakpoint; }); |
|||
} |
|||
} |
|||
|
|||
void DebugContext::Resume() { |
|||
{ |
|||
std::lock_guard lock{breakpoint_mutex}; |
|||
|
|||
// Tell all observers that we are about to resume
|
|||
for (auto& breakpoint_observer : breakpoint_observers) { |
|||
breakpoint_observer->OnMaxwellResume(); |
|||
} |
|||
|
|||
// Resume the waiting thread (i.e. OnEvent())
|
|||
at_breakpoint = false; |
|||
} |
|||
|
|||
resume_from_breakpoint.notify_one(); |
|||
} |
|||
|
|||
} // namespace Tegra
|
|||
@ -1,157 +0,0 @@ |
|||
// Copyright 2014 Citra Emulator Project |
|||
// Licensed under GPLv2 |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <condition_variable> |
|||
#include <list> |
|||
#include <memory> |
|||
#include <mutex> |
|||
|
|||
namespace Tegra { |
|||
|
|||
class DebugContext { |
|||
public: |
|||
enum class Event { |
|||
FirstEvent = 0, |
|||
|
|||
MaxwellCommandLoaded = FirstEvent, |
|||
MaxwellCommandProcessed, |
|||
IncomingPrimitiveBatch, |
|||
FinishedPrimitiveBatch, |
|||
|
|||
NumEvents |
|||
}; |
|||
|
|||
/** |
|||
* Inherit from this class to be notified of events registered to some debug context. |
|||
* Most importantly this is used for our debugger GUI. |
|||
* |
|||
* To implement event handling, override the OnMaxwellBreakPointHit and OnMaxwellResume methods. |
|||
* @warning All BreakPointObservers need to be on the same thread to guarantee thread-safe state |
|||
* access |
|||
* @todo Evaluate an alternative interface, in which there is only one managing observer and |
|||
* multiple child observers running (by design) on the same thread. |
|||
*/ |
|||
class BreakPointObserver { |
|||
public: |
|||
/// Constructs the object such that it observes events of the given DebugContext. |
|||
explicit BreakPointObserver(std::shared_ptr<DebugContext> debug_context) |
|||
: context_weak(debug_context) { |
|||
std::unique_lock lock{debug_context->breakpoint_mutex}; |
|||
debug_context->breakpoint_observers.push_back(this); |
|||
} |
|||
|
|||
virtual ~BreakPointObserver() { |
|||
auto context = context_weak.lock(); |
|||
if (context) { |
|||
{ |
|||
std::unique_lock lock{context->breakpoint_mutex}; |
|||
context->breakpoint_observers.remove(this); |
|||
} |
|||
|
|||
// If we are the last observer to be destroyed, tell the debugger context that |
|||
// it is free to continue. In particular, this is required for a proper yuzu |
|||
// shutdown, when the emulation thread is waiting at a breakpoint. |
|||
if (context->breakpoint_observers.empty()) |
|||
context->Resume(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Action to perform when a breakpoint was reached. |
|||
* @param event Type of event which triggered the breakpoint |
|||
* @param data Optional data pointer (if unused, this is a nullptr) |
|||
* @note This function will perform nothing unless it is overridden in the child class. |
|||
*/ |
|||
virtual void OnMaxwellBreakPointHit(Event event, void* data) {} |
|||
|
|||
/** |
|||
* Action to perform when emulation is resumed from a breakpoint. |
|||
* @note This function will perform nothing unless it is overridden in the child class. |
|||
*/ |
|||
virtual void OnMaxwellResume() {} |
|||
|
|||
protected: |
|||
/** |
|||
* Weak context pointer. This need not be valid, so when requesting a shared_ptr via |
|||
* context_weak.lock(), always compare the result against nullptr. |
|||
*/ |
|||
std::weak_ptr<DebugContext> context_weak; |
|||
}; |
|||
|
|||
/** |
|||
* Simple structure defining a breakpoint state |
|||
*/ |
|||
struct BreakPoint { |
|||
bool enabled = false; |
|||
}; |
|||
|
|||
/** |
|||
* Static constructor used to create a shared_ptr of a DebugContext. |
|||
*/ |
|||
static std::shared_ptr<DebugContext> Construct() { |
|||
return std::shared_ptr<DebugContext>(new DebugContext); |
|||
} |
|||
|
|||
/** |
|||
* Used by the emulation core when a given event has happened. If a breakpoint has been set |
|||
* for this event, OnEvent calls the event handlers of the registered breakpoint observers. |
|||
* The current thread then is halted until Resume() is called from another thread (or until |
|||
* emulation is stopped). |
|||
* @param event Event which has happened |
|||
* @param data Optional data pointer (pass nullptr if unused). Needs to remain valid until |
|||
* Resume() is called. |
|||
*/ |
|||
void OnEvent(Event event, void* data) { |
|||
// This check is left in the header to allow the compiler to inline it. |
|||
if (!breakpoints[(int)event].enabled) |
|||
return; |
|||
// For the rest of event handling, call a separate function. |
|||
DoOnEvent(event, data); |
|||
} |
|||
|
|||
void DoOnEvent(Event event, void* data); |
|||
|
|||
/** |
|||
* Resume from the current breakpoint. |
|||
* @warning Calling this from the same thread that OnEvent was called in will cause a deadlock. |
|||
* Calling from any other thread is safe. |
|||
*/ |
|||
void Resume(); |
|||
|
|||
/** |
|||
* Delete all set breakpoints and resume emulation. |
|||
*/ |
|||
void ClearBreakpoints() { |
|||
for (auto& bp : breakpoints) { |
|||
bp.enabled = false; |
|||
} |
|||
Resume(); |
|||
} |
|||
|
|||
// TODO: Evaluate if access to these members should be hidden behind a public interface. |
|||
std::array<BreakPoint, static_cast<int>(Event::NumEvents)> breakpoints; |
|||
Event active_breakpoint{}; |
|||
bool at_breakpoint = false; |
|||
|
|||
private: |
|||
/** |
|||
* Private default constructor to make sure people always construct this through Construct() |
|||
* instead. |
|||
*/ |
|||
DebugContext() = default; |
|||
|
|||
/// Mutex protecting current breakpoint state and the observer list. |
|||
std::mutex breakpoint_mutex; |
|||
|
|||
/// Used by OnEvent to wait for resumption. |
|||
std::condition_variable resume_from_breakpoint; |
|||
|
|||
/// List of registered observers |
|||
std::list<BreakPointObserver*> breakpoint_observers; |
|||
}; |
|||
|
|||
} // namespace Tegra |
|||
@ -1,27 +0,0 @@ |
|||
// Copyright 2014 Citra Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <QMetaType>
|
|||
#include "yuzu/debugger/graphics/graphics_breakpoint_observer.h"
|
|||
|
|||
BreakPointObserverDock::BreakPointObserverDock(std::shared_ptr<Tegra::DebugContext> debug_context, |
|||
const QString& title, QWidget* parent) |
|||
: QDockWidget(title, parent), BreakPointObserver(debug_context) { |
|||
qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); |
|||
|
|||
connect(this, &BreakPointObserverDock::Resumed, this, &BreakPointObserverDock::OnResumed); |
|||
|
|||
// NOTE: This signal is emitted from a non-GUI thread, but connect() takes
|
|||
// care of delaying its handling to the GUI thread.
|
|||
connect(this, &BreakPointObserverDock::BreakPointHit, this, |
|||
&BreakPointObserverDock::OnBreakPointHit, Qt::BlockingQueuedConnection); |
|||
} |
|||
|
|||
void BreakPointObserverDock::OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) { |
|||
emit BreakPointHit(event, data); |
|||
} |
|||
|
|||
void BreakPointObserverDock::OnMaxwellResume() { |
|||
emit Resumed(); |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
// Copyright 2014 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <QDockWidget> |
|||
#include "video_core/debug_utils/debug_utils.h" |
|||
|
|||
/** |
|||
* Utility class which forwards calls to OnMaxwellBreakPointHit and OnMaxwellResume to public slots. |
|||
* This is because the Maxwell breakpoint callbacks are called from a non-GUI thread, while |
|||
* the widget usually wants to perform reactions in the GUI thread. |
|||
*/ |
|||
class BreakPointObserverDock : public QDockWidget, |
|||
protected Tegra::DebugContext::BreakPointObserver { |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
BreakPointObserverDock(std::shared_ptr<Tegra::DebugContext> debug_context, const QString& title, |
|||
QWidget* parent = nullptr); |
|||
|
|||
void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; |
|||
void OnMaxwellResume() override; |
|||
|
|||
signals: |
|||
void Resumed(); |
|||
void BreakPointHit(Tegra::DebugContext::Event event, void* data); |
|||
|
|||
private: |
|||
virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0; |
|||
virtual void OnResumed() = 0; |
|||
}; |
|||
@ -1,221 +0,0 @@ |
|||
// Copyright 2014 Citra Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <QLabel>
|
|||
#include <QMetaType>
|
|||
#include <QPushButton>
|
|||
#include <QTreeView>
|
|||
#include <QVBoxLayout>
|
|||
#include "common/assert.h"
|
|||
#include "yuzu/debugger/graphics/graphics_breakpoints.h"
|
|||
#include "yuzu/debugger/graphics/graphics_breakpoints_p.h"
|
|||
|
|||
BreakPointModel::BreakPointModel(std::shared_ptr<Tegra::DebugContext> debug_context, |
|||
QObject* parent) |
|||
: QAbstractListModel(parent), context_weak(debug_context), |
|||
at_breakpoint(debug_context->at_breakpoint), |
|||
active_breakpoint(debug_context->active_breakpoint) {} |
|||
|
|||
int BreakPointModel::columnCount(const QModelIndex& parent) const { |
|||
return 1; |
|||
} |
|||
|
|||
int BreakPointModel::rowCount(const QModelIndex& parent) const { |
|||
return static_cast<int>(Tegra::DebugContext::Event::NumEvents); |
|||
} |
|||
|
|||
QVariant BreakPointModel::data(const QModelIndex& index, int role) const { |
|||
const auto event = static_cast<Tegra::DebugContext::Event>(index.row()); |
|||
|
|||
switch (role) { |
|||
case Qt::DisplayRole: { |
|||
if (index.column() == 0) { |
|||
return DebugContextEventToString(event); |
|||
} |
|||
break; |
|||
} |
|||
|
|||
case Qt::CheckStateRole: { |
|||
if (index.column() == 0) |
|||
return data(index, Role_IsEnabled).toBool() ? Qt::Checked : Qt::Unchecked; |
|||
break; |
|||
} |
|||
|
|||
case Qt::BackgroundRole: { |
|||
if (at_breakpoint && index.row() == static_cast<int>(active_breakpoint)) { |
|||
return QBrush(QColor(0xE0, 0xE0, 0x10)); |
|||
} |
|||
break; |
|||
} |
|||
|
|||
case Role_IsEnabled: { |
|||
auto context = context_weak.lock(); |
|||
return context && context->breakpoints[(int)event].enabled; |
|||
} |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
return QVariant(); |
|||
} |
|||
|
|||
Qt::ItemFlags BreakPointModel::flags(const QModelIndex& index) const { |
|||
if (!index.isValid()) |
|||
return 0; |
|||
|
|||
Qt::ItemFlags flags = Qt::ItemIsEnabled; |
|||
if (index.column() == 0) |
|||
flags |= Qt::ItemIsUserCheckable; |
|||
return flags; |
|||
} |
|||
|
|||
bool BreakPointModel::setData(const QModelIndex& index, const QVariant& value, int role) { |
|||
const auto event = static_cast<Tegra::DebugContext::Event>(index.row()); |
|||
|
|||
switch (role) { |
|||
case Qt::CheckStateRole: { |
|||
if (index.column() != 0) |
|||
return false; |
|||
|
|||
auto context = context_weak.lock(); |
|||
if (!context) |
|||
return false; |
|||
|
|||
context->breakpoints[(int)event].enabled = value == Qt::Checked; |
|||
QModelIndex changed_index = createIndex(index.row(), 0); |
|||
emit dataChanged(changed_index, changed_index); |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
void BreakPointModel::OnBreakPointHit(Tegra::DebugContext::Event event) { |
|||
auto context = context_weak.lock(); |
|||
if (!context) |
|||
return; |
|||
|
|||
active_breakpoint = context->active_breakpoint; |
|||
at_breakpoint = context->at_breakpoint; |
|||
emit dataChanged(createIndex(static_cast<int>(event), 0), |
|||
createIndex(static_cast<int>(event), 0)); |
|||
} |
|||
|
|||
void BreakPointModel::OnResumed() { |
|||
auto context = context_weak.lock(); |
|||
if (!context) |
|||
return; |
|||
|
|||
at_breakpoint = context->at_breakpoint; |
|||
emit dataChanged(createIndex(static_cast<int>(active_breakpoint), 0), |
|||
createIndex(static_cast<int>(active_breakpoint), 0)); |
|||
active_breakpoint = context->active_breakpoint; |
|||
} |
|||
|
|||
QString BreakPointModel::DebugContextEventToString(Tegra::DebugContext::Event event) { |
|||
switch (event) { |
|||
case Tegra::DebugContext::Event::MaxwellCommandLoaded: |
|||
return tr("Maxwell command loaded"); |
|||
case Tegra::DebugContext::Event::MaxwellCommandProcessed: |
|||
return tr("Maxwell command processed"); |
|||
case Tegra::DebugContext::Event::IncomingPrimitiveBatch: |
|||
return tr("Incoming primitive batch"); |
|||
case Tegra::DebugContext::Event::FinishedPrimitiveBatch: |
|||
return tr("Finished primitive batch"); |
|||
case Tegra::DebugContext::Event::NumEvents: |
|||
break; |
|||
} |
|||
|
|||
return tr("Unknown debug context event"); |
|||
} |
|||
|
|||
GraphicsBreakPointsWidget::GraphicsBreakPointsWidget( |
|||
std::shared_ptr<Tegra::DebugContext> debug_context, QWidget* parent) |
|||
: QDockWidget(tr("Maxwell Breakpoints"), parent), Tegra::DebugContext::BreakPointObserver( |
|||
debug_context) { |
|||
setObjectName(QStringLiteral("TegraBreakPointsWidget")); |
|||
|
|||
status_text = new QLabel(tr("Emulation running")); |
|||
resume_button = new QPushButton(tr("Resume")); |
|||
resume_button->setEnabled(false); |
|||
|
|||
breakpoint_model = new BreakPointModel(debug_context, this); |
|||
breakpoint_list = new QTreeView; |
|||
breakpoint_list->setRootIsDecorated(false); |
|||
breakpoint_list->setHeaderHidden(true); |
|||
breakpoint_list->setModel(breakpoint_model); |
|||
|
|||
qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); |
|||
|
|||
connect(breakpoint_list, &QTreeView::doubleClicked, this, |
|||
&GraphicsBreakPointsWidget::OnItemDoubleClicked); |
|||
|
|||
connect(resume_button, &QPushButton::clicked, this, |
|||
&GraphicsBreakPointsWidget::OnResumeRequested); |
|||
|
|||
connect(this, &GraphicsBreakPointsWidget::BreakPointHit, this, |
|||
&GraphicsBreakPointsWidget::OnBreakPointHit, Qt::BlockingQueuedConnection); |
|||
connect(this, &GraphicsBreakPointsWidget::Resumed, this, &GraphicsBreakPointsWidget::OnResumed); |
|||
|
|||
connect(this, &GraphicsBreakPointsWidget::BreakPointHit, breakpoint_model, |
|||
&BreakPointModel::OnBreakPointHit, Qt::BlockingQueuedConnection); |
|||
connect(this, &GraphicsBreakPointsWidget::Resumed, breakpoint_model, |
|||
&BreakPointModel::OnResumed); |
|||
|
|||
connect(this, &GraphicsBreakPointsWidget::BreakPointsChanged, |
|||
[this](const QModelIndex& top_left, const QModelIndex& bottom_right) { |
|||
breakpoint_model->dataChanged(top_left, bottom_right); |
|||
}); |
|||
|
|||
QWidget* main_widget = new QWidget; |
|||
auto main_layout = new QVBoxLayout; |
|||
{ |
|||
auto sub_layout = new QHBoxLayout; |
|||
sub_layout->addWidget(status_text); |
|||
sub_layout->addWidget(resume_button); |
|||
main_layout->addLayout(sub_layout); |
|||
} |
|||
main_layout->addWidget(breakpoint_list); |
|||
main_widget->setLayout(main_layout); |
|||
|
|||
setWidget(main_widget); |
|||
} |
|||
|
|||
void GraphicsBreakPointsWidget::OnMaxwellBreakPointHit(Event event, void* data) { |
|||
// Process in GUI thread
|
|||
emit BreakPointHit(event, data); |
|||
} |
|||
|
|||
void GraphicsBreakPointsWidget::OnBreakPointHit(Tegra::DebugContext::Event event, void* data) { |
|||
status_text->setText(tr("Emulation halted at breakpoint")); |
|||
resume_button->setEnabled(true); |
|||
} |
|||
|
|||
void GraphicsBreakPointsWidget::OnMaxwellResume() { |
|||
// Process in GUI thread
|
|||
emit Resumed(); |
|||
} |
|||
|
|||
void GraphicsBreakPointsWidget::OnResumed() { |
|||
status_text->setText(tr("Emulation running")); |
|||
resume_button->setEnabled(false); |
|||
} |
|||
|
|||
void GraphicsBreakPointsWidget::OnResumeRequested() { |
|||
if (auto context = context_weak.lock()) |
|||
context->Resume(); |
|||
} |
|||
|
|||
void GraphicsBreakPointsWidget::OnItemDoubleClicked(const QModelIndex& index) { |
|||
if (!index.isValid()) |
|||
return; |
|||
|
|||
QModelIndex check_index = breakpoint_list->model()->index(index.row(), 0); |
|||
QVariant enabled = breakpoint_list->model()->data(check_index, Qt::CheckStateRole); |
|||
QVariant new_state = Qt::Unchecked; |
|||
if (enabled == Qt::Unchecked) |
|||
new_state = Qt::Checked; |
|||
breakpoint_list->model()->setData(check_index, new_state, Qt::CheckStateRole); |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
// Copyright 2014 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <QDockWidget> |
|||
#include "video_core/debug_utils/debug_utils.h" |
|||
|
|||
class QLabel; |
|||
class QPushButton; |
|||
class QTreeView; |
|||
|
|||
class BreakPointModel; |
|||
|
|||
class GraphicsBreakPointsWidget : public QDockWidget, Tegra::DebugContext::BreakPointObserver { |
|||
Q_OBJECT |
|||
|
|||
using Event = Tegra::DebugContext::Event; |
|||
|
|||
public: |
|||
explicit GraphicsBreakPointsWidget(std::shared_ptr<Tegra::DebugContext> debug_context, |
|||
QWidget* parent = nullptr); |
|||
|
|||
void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; |
|||
void OnMaxwellResume() override; |
|||
|
|||
signals: |
|||
void Resumed(); |
|||
void BreakPointHit(Tegra::DebugContext::Event event, void* data); |
|||
void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); |
|||
|
|||
private: |
|||
void OnBreakPointHit(Tegra::DebugContext::Event event, void* data); |
|||
void OnItemDoubleClicked(const QModelIndex&); |
|||
void OnResumeRequested(); |
|||
void OnResumed(); |
|||
|
|||
QLabel* status_text; |
|||
QPushButton* resume_button; |
|||
|
|||
BreakPointModel* breakpoint_model; |
|||
QTreeView* breakpoint_list; |
|||
}; |
|||
@ -1,37 +0,0 @@ |
|||
// Copyright 2014 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <QAbstractListModel> |
|||
#include "video_core/debug_utils/debug_utils.h" |
|||
|
|||
class BreakPointModel : public QAbstractListModel { |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
enum { |
|||
Role_IsEnabled = Qt::UserRole, |
|||
}; |
|||
|
|||
BreakPointModel(std::shared_ptr<Tegra::DebugContext> context, QObject* parent); |
|||
|
|||
int columnCount(const QModelIndex& parent = QModelIndex()) const override; |
|||
int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
|||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
|||
Qt::ItemFlags flags(const QModelIndex& index) const override; |
|||
|
|||
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; |
|||
|
|||
void OnBreakPointHit(Tegra::DebugContext::Event event); |
|||
void OnResumed(); |
|||
|
|||
private: |
|||
static QString DebugContextEventToString(Tegra::DebugContext::Event event); |
|||
|
|||
std::weak_ptr<Tegra::DebugContext> context_weak; |
|||
bool at_breakpoint; |
|||
Tegra::DebugContext::Event active_breakpoint; |
|||
}; |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue