mirror of
https://github.com/PabloMK7/citra.git
synced 2025-09-10 21:00:06 +00:00
Miscallenious fixes to gl backend and qt frontend (#6834)
* renderer_gl: Make rasterizer normal class member * It doesn't need to be heap allocated anymore * gl_rasterizer: Remove default_texture * It's unused * gl_rasterizer: General cleanup * gl_rasterizer: Lower case lambdas * Match style with review comments from vulkan backend * rasterizer_cache: Prevent memory leak * Since the switch from shared_ptr these surfaces were no longer being destroyed properly. Use our garbage collector for that purpose to destroy it safely for both backends * rasterizer_cache: Make temp copy of old surface * The custom surface would override the memory region of the old region resulting in garbage data, this ensures the custom surface is constructed correctly * citra_qt: Manually create dialog tabs * Allows for custom constructors which is very useful. While at it, global state is now eliminated from configuration * citra_qt: Eliminate global system usage * core: Remove global system usage in memory and HIO * citra_qt: Use qOverload * tests: Run clang format * gl_texture_runtime: Fix surface scaling
This commit is contained in:
parent
970f2284d8
commit
88ea66053e
73 changed files with 594 additions and 555 deletions
|
@ -16,7 +16,6 @@
|
|||
#include "citra_qt/debugger/graphics/graphics_cmdlists.h"
|
||||
#include "citra_qt/util/util.h"
|
||||
#include "common/vector_math.h"
|
||||
#include "core/core.h"
|
||||
#include "core/memory.h"
|
||||
#include "video_core/debug_utils/debug_utils.h"
|
||||
#include "video_core/pica_state.h"
|
||||
|
@ -167,8 +166,7 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
|
|||
const auto format = texture.format;
|
||||
|
||||
const auto info = Pica::Texture::TextureInfo::FromPicaRegister(config, format);
|
||||
const u8* src =
|
||||
Core::System::GetInstance().Memory().GetPhysicalPointer(config.GetPhysicalAddress());
|
||||
const u8* src = memory.GetPhysicalPointer(config.GetPhysicalAddress());
|
||||
new_info_widget = new TextureInfoWidget(src, info);
|
||||
}
|
||||
if (command_info_widget) {
|
||||
|
@ -182,8 +180,8 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
|
|||
}
|
||||
#undef COMMAND_IN_RANGE
|
||||
|
||||
GPUCommandListWidget::GPUCommandListWidget(QWidget* parent)
|
||||
: QDockWidget(tr("Pica Command List"), parent) {
|
||||
GPUCommandListWidget::GPUCommandListWidget(Memory::MemorySystem& memory_, QWidget* parent)
|
||||
: QDockWidget(tr("Pica Command List"), parent), memory{memory_} {
|
||||
setObjectName(QStringLiteral("Pica Command List"));
|
||||
GPUCommandListModel* model = new GPUCommandListModel(this);
|
||||
|
||||
|
|
|
@ -7,11 +7,14 @@
|
|||
#include <QAbstractListModel>
|
||||
#include <QDockWidget>
|
||||
#include "video_core/debug_utils/debug_utils.h"
|
||||
#include "video_core/gpu_debugger.h"
|
||||
|
||||
class QPushButton;
|
||||
class QTreeView;
|
||||
|
||||
namespace Memory {
|
||||
class MemorySystem;
|
||||
}
|
||||
|
||||
class GPUCommandListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -39,7 +42,7 @@ class GPUCommandListWidget : public QDockWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GPUCommandListWidget(QWidget* parent = nullptr);
|
||||
explicit GPUCommandListWidget(Memory::MemorySystem& memory, QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void OnToggleTracing();
|
||||
|
@ -54,7 +57,7 @@ signals:
|
|||
|
||||
private:
|
||||
std::unique_ptr<Pica::DebugUtils::PicaTrace> pica_trace;
|
||||
|
||||
Memory::MemorySystem& memory;
|
||||
QTreeView* list_widget;
|
||||
QWidget* command_info_widget;
|
||||
QPushButton* toggle_tracing;
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
#include "citra_qt/debugger/graphics/graphics_surface.h"
|
||||
#include "citra_qt/util/spinbox.h"
|
||||
#include "common/color.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hw/gpu.h"
|
||||
#include "core/memory.h"
|
||||
#include "video_core/pica_state.h"
|
||||
#include "video_core/regs_framebuffer.h"
|
||||
|
@ -51,9 +49,10 @@ void SurfacePicture::mouseMoveEvent(QMouseEvent* event) {
|
|||
mousePressEvent(event);
|
||||
}
|
||||
|
||||
GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
|
||||
GraphicsSurfaceWidget::GraphicsSurfaceWidget(Memory::MemorySystem& memory_,
|
||||
std::shared_ptr<Pica::DebugContext> debug_context,
|
||||
QWidget* parent)
|
||||
: BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent),
|
||||
: BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent), memory{memory_},
|
||||
surface_source(Source::ColorBuffer) {
|
||||
setObjectName(QStringLiteral("PicaSurface"));
|
||||
|
||||
|
@ -290,57 +289,57 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||
return;
|
||||
}
|
||||
|
||||
u8* buffer = Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
|
||||
if (buffer == nullptr) {
|
||||
const u8* buffer = memory.GetPhysicalPointer(surface_address);
|
||||
if (!buffer) {
|
||||
surface_info_label->setText(tr("(unable to access pixel data)"));
|
||||
surface_info_label->setAlignment(Qt::AlignCenter);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format);
|
||||
unsigned stride = nibbles_per_pixel * surface_width / 2;
|
||||
|
||||
unsigned bytes_per_pixel;
|
||||
bool nibble_mode = (nibbles_per_pixel == 1);
|
||||
if (nibble_mode) {
|
||||
// As nibbles are contained in a byte we still need to access one byte per nibble
|
||||
bytes_per_pixel = 1;
|
||||
} else {
|
||||
bytes_per_pixel = nibbles_per_pixel / 2;
|
||||
}
|
||||
const u32 nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format);
|
||||
const u32 stride = nibbles_per_pixel * surface_width / 2;
|
||||
const bool nibble_mode = (nibbles_per_pixel == 1);
|
||||
const u32 bytes_per_pixel = [&] {
|
||||
if (nibble_mode) {
|
||||
// As nibbles are contained in a byte we still need to access one byte per nibble
|
||||
return 1u;
|
||||
} else {
|
||||
return nibbles_per_pixel / 2;
|
||||
}
|
||||
}();
|
||||
|
||||
const u32 coarse_y = y & ~7;
|
||||
u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
|
||||
const u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
|
||||
const u8* pixel = buffer + (nibble_mode ? (offset / 2) : offset);
|
||||
|
||||
auto GetText = [offset](Format format, const u8* pixel) {
|
||||
const auto get_text = [offset](Format format, const u8* pixel) {
|
||||
switch (format) {
|
||||
case Format::RGBA8: {
|
||||
auto value = Common::Color::DecodeRGBA8(pixel) / 255.0f;
|
||||
const auto value = Common::Color::DecodeRGBA8(pixel) / 255.0f;
|
||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||
}
|
||||
case Format::RGB8: {
|
||||
auto value = Common::Color::DecodeRGB8(pixel) / 255.0f;
|
||||
const auto value = Common::Color::DecodeRGB8(pixel) / 255.0f;
|
||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||
QString::number(value.b(), 'f', 2));
|
||||
}
|
||||
case Format::RGB5A1: {
|
||||
auto value = Common::Color::DecodeRGB5A1(pixel) / 255.0f;
|
||||
const auto value = Common::Color::DecodeRGB5A1(pixel) / 255.0f;
|
||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||
}
|
||||
case Format::RGB565: {
|
||||
auto value = Common::Color::DecodeRGB565(pixel) / 255.0f;
|
||||
const auto value = Common::Color::DecodeRGB565(pixel) / 255.0f;
|
||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||
QString::number(value.b(), 'f', 2));
|
||||
}
|
||||
case Format::RGBA4: {
|
||||
auto value = Common::Color::DecodeRGBA4(pixel) / 255.0f;
|
||||
const auto value = Common::Color::DecodeRGBA4(pixel) / 255.0f;
|
||||
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||
|
@ -348,7 +347,7 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||
case Format::IA8:
|
||||
return QStringLiteral("Index: %1, Alpha: %2").arg(pixel[0], pixel[1]);
|
||||
case Format::RG8: {
|
||||
auto value = Common::Color::DecodeRG8(pixel) / 255.0f;
|
||||
const auto value = Common::Color::DecodeRG8(pixel) / 255.0f;
|
||||
return QStringLiteral("Red: %1, Green: %2")
|
||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2));
|
||||
}
|
||||
|
@ -359,11 +358,11 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||
case Format::IA4:
|
||||
return QStringLiteral("Index: %1, Alpha: %2").arg(*pixel & 0xF, (*pixel & 0xF0) >> 4);
|
||||
case Format::I4: {
|
||||
u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
|
||||
const u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
|
||||
return QStringLiteral("Index: %1").arg(i);
|
||||
}
|
||||
case Format::A4: {
|
||||
u8 a = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
|
||||
const u8 a = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
|
||||
return QStringLiteral("Alpha: %1").arg(QString::number(a / 15.0f, 'f', 2));
|
||||
}
|
||||
case Format::ETC1:
|
||||
|
@ -371,17 +370,17 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||
// TODO: Display block information or channel values?
|
||||
return QStringLiteral("Compressed data");
|
||||
case Format::D16: {
|
||||
auto value = Common::Color::DecodeD16(pixel);
|
||||
const auto value = Common::Color::DecodeD16(pixel);
|
||||
return QStringLiteral("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4));
|
||||
}
|
||||
case Format::D24: {
|
||||
auto value = Common::Color::DecodeD24(pixel);
|
||||
const auto value = Common::Color::DecodeD24(pixel);
|
||||
return QStringLiteral("Depth: %1")
|
||||
.arg(QString::number(value / (float)0xFFFFFF, 'f', 4));
|
||||
}
|
||||
case Format::D24X8:
|
||||
case Format::X24S8: {
|
||||
auto values = Common::Color::DecodeD24S8(pixel);
|
||||
const auto values = Common::Color::DecodeD24S8(pixel);
|
||||
return QStringLiteral("Depth: %1, Stencil: %2")
|
||||
.arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4), values[1]);
|
||||
}
|
||||
|
@ -398,13 +397,13 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||
if (nibble_mode) {
|
||||
nibble_index += (offset % 2) ? 0 : 1;
|
||||
}
|
||||
u8 byte = pixel[nibble_index / 2];
|
||||
u8 nibble = (byte >> ((nibble_index % 2) ? 0 : 4)) & 0xF;
|
||||
const u8 byte = pixel[nibble_index / 2];
|
||||
const u8 nibble = (byte >> ((nibble_index % 2) ? 0 : 4)) & 0xF;
|
||||
nibbles.append(QString::number(nibble, 16).toUpper());
|
||||
}
|
||||
|
||||
surface_info_label->setText(
|
||||
QStringLiteral("Raw: 0x%3\n(%4)").arg(nibbles, GetText(surface_format, pixel)));
|
||||
QStringLiteral("Raw: 0x%3\n(%4)").arg(nibbles, get_text(surface_format, pixel)));
|
||||
surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
|
@ -546,9 +545,9 @@ void GraphicsSurfaceWidget::OnUpdate() {
|
|||
// TODO: Implement a good way to visualize alpha components!
|
||||
|
||||
QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
|
||||
u8* buffer = Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
|
||||
const u8* buffer = memory.GetPhysicalPointer(surface_address);
|
||||
|
||||
if (buffer == nullptr) {
|
||||
if (!buffer) {
|
||||
surface_picture_label->hide();
|
||||
surface_info_label->setText(tr("(invalid surface address)"));
|
||||
surface_info_label->setAlignment(Qt::AlignCenter);
|
||||
|
@ -682,9 +681,8 @@ void GraphicsSurfaceWidget::SaveSurface() {
|
|||
tr("Failed to save surface data to file '%1'").arg(filename));
|
||||
}
|
||||
} else if (selected_filter == bin_filter) {
|
||||
const u8* const buffer =
|
||||
Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
|
||||
ASSERT_MSG(buffer != nullptr, "Memory not accessible");
|
||||
const u8* const buffer = memory.GetPhysicalPointer(surface_address);
|
||||
ASSERT_MSG(buffer, "Memory not accessible");
|
||||
|
||||
QFile file{filename};
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
|
|
|
@ -14,6 +14,10 @@ class CSpinBox;
|
|||
|
||||
class GraphicsSurfaceWidget;
|
||||
|
||||
namespace Memory {
|
||||
class MemorySystem;
|
||||
}
|
||||
|
||||
class SurfacePicture : public QLabel {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -72,7 +76,8 @@ class GraphicsSurfaceWidget : public BreakPointObserverDock {
|
|||
static unsigned int NibblesPerPixel(Format format);
|
||||
|
||||
public:
|
||||
explicit GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
|
||||
explicit GraphicsSurfaceWidget(Memory::MemorySystem& memory,
|
||||
std::shared_ptr<Pica::DebugContext> debug_context,
|
||||
QWidget* parent = nullptr);
|
||||
void Pick(int x, int y);
|
||||
|
||||
|
@ -95,6 +100,7 @@ private:
|
|||
|
||||
void SaveSurface();
|
||||
|
||||
Memory::MemorySystem& memory;
|
||||
QComboBox* surface_source_list;
|
||||
CSpinBox* surface_address_control;
|
||||
QSpinBox* surface_width_control;
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
#include "core/hle/service/sm/sm.h"
|
||||
#include "ui_recorder.h"
|
||||
|
||||
IPCRecorderWidget::IPCRecorderWidget(QWidget* parent)
|
||||
: QDockWidget(parent), ui(std::make_unique<Ui::IPCRecorder>()) {
|
||||
IPCRecorderWidget::IPCRecorderWidget(Core::System& system_, QWidget* parent)
|
||||
: QDockWidget(parent), ui(std::make_unique<Ui::IPCRecorder>()), system{system_} {
|
||||
|
||||
ui->setupUi(this);
|
||||
qRegisterMetaType<IPCDebugger::RequestRecord>();
|
||||
|
||||
connect(ui->enabled, &QCheckBox::stateChanged,
|
||||
connect(ui->enabled, &QCheckBox::stateChanged, this,
|
||||
[this](int new_state) { SetEnabled(new_state == Qt::Checked); });
|
||||
connect(ui->clearButton, &QPushButton::clicked, this, &IPCRecorderWidget::Clear);
|
||||
connect(ui->filter, &QLineEdit::textChanged, this, &IPCRecorderWidget::ApplyFilterToAll);
|
||||
|
@ -90,7 +90,7 @@ void IPCRecorderWidget::OnEntryUpdated(IPCDebugger::RequestRecord record) {
|
|||
(record.status == IPCDebugger::RequestStatus::Handled &&
|
||||
record.translated_reply_cmdbuf[1] != RESULT_SUCCESS.raw)) { // Unimplemented / Error
|
||||
|
||||
auto* item = ui->main->invisibleRootItem()->child(row_id);
|
||||
auto item = ui->main->invisibleRootItem()->child(row_id);
|
||||
for (int column = 0; column < item->columnCount(); ++column) {
|
||||
item->setBackground(column, QBrush(QColor::fromRgb(255, 0, 0)));
|
||||
}
|
||||
|
@ -100,11 +100,11 @@ void IPCRecorderWidget::OnEntryUpdated(IPCDebugger::RequestRecord record) {
|
|||
}
|
||||
|
||||
void IPCRecorderWidget::SetEnabled(bool enabled) {
|
||||
if (!Core::System::GetInstance().IsPoweredOn()) {
|
||||
if (!system.IsPoweredOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& ipc_recorder = Core::System::GetInstance().Kernel().GetIPCRecorder();
|
||||
auto& ipc_recorder = system.Kernel().GetIPCRecorder();
|
||||
ipc_recorder.SetEnabled(enabled);
|
||||
|
||||
if (enabled) {
|
||||
|
@ -123,10 +123,10 @@ void IPCRecorderWidget::Clear() {
|
|||
}
|
||||
|
||||
QString IPCRecorderWidget::GetServiceName(const IPCDebugger::RequestRecord& record) const {
|
||||
if (Core::System::GetInstance().IsPoweredOn() && record.client_port.id != -1) {
|
||||
const auto service_name =
|
||||
Core::System::GetInstance().ServiceManager().GetServiceNameByPortId(
|
||||
static_cast<u32>(record.client_port.id));
|
||||
if (system.IsPoweredOn() && record.client_port.id != -1) {
|
||||
const Service::SM::ServiceManager& sm = system.ServiceManager();
|
||||
const u32 port_id = static_cast<u32>(record.client_port.id);
|
||||
const auto service_name = sm.GetServiceNameByPortId(port_id);
|
||||
|
||||
if (!service_name.empty()) {
|
||||
return QString::fromStdString(service_name);
|
||||
|
|
|
@ -14,11 +14,15 @@ namespace Ui {
|
|||
class IPCRecorder;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
class IPCRecorderWidget : public QDockWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit IPCRecorderWidget(QWidget* parent = nullptr);
|
||||
explicit IPCRecorderWidget(Core::System& system, QWidget* parent = nullptr);
|
||||
~IPCRecorderWidget();
|
||||
|
||||
void OnEmulationStarting();
|
||||
|
@ -37,9 +41,10 @@ private:
|
|||
QString GetFunctionName(const IPCDebugger::RequestRecord& record) const;
|
||||
void OpenRecordDialog(QTreeWidgetItem* item, int column);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::IPCRecorder> ui;
|
||||
IPCDebugger::CallbackHandle handle;
|
||||
|
||||
Core::System& system;
|
||||
// The offset between record id and row id, assuming record ids are assigned
|
||||
// continuously and only the 'Clear' action can be performed, this is enough.
|
||||
// The initial value is 1, which means record 1 = row 0.
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include "core/core.h"
|
||||
#include "ui_registers.h"
|
||||
|
||||
RegistersWidget::RegistersWidget(QWidget* parent)
|
||||
: QDockWidget(parent), cpu_regs_ui(std::make_unique<Ui::ARMRegisters>()) {
|
||||
RegistersWidget::RegistersWidget(const Core::System& system_, QWidget* parent)
|
||||
: QDockWidget(parent), cpu_regs_ui(std::make_unique<Ui::ARMRegisters>()), system{system_} {
|
||||
cpu_regs_ui->setupUi(this);
|
||||
|
||||
tree = cpu_regs_ui->treeWidget;
|
||||
|
@ -62,17 +62,21 @@ RegistersWidget::RegistersWidget(QWidget* parent)
|
|||
RegistersWidget::~RegistersWidget() = default;
|
||||
|
||||
void RegistersWidget::OnDebugModeEntered() {
|
||||
if (!Core::System::GetInstance().IsPoweredOn())
|
||||
if (!system.IsPoweredOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Todo: Handle all cores
|
||||
for (int i = 0; i < core_registers->childCount(); ++i)
|
||||
// TODO: Handle all cores
|
||||
const ARM_Interface& core = system.GetCore(0);
|
||||
for (int i = 0; i < core_registers->childCount(); ++i) {
|
||||
core_registers->child(i)->setText(
|
||||
1, QStringLiteral("0x%1").arg(Core::GetCore(0).GetReg(i), 8, 16, QLatin1Char('0')));
|
||||
1, QStringLiteral("0x%1").arg(core.GetReg(i), 8, 16, QLatin1Char('0')));
|
||||
}
|
||||
|
||||
for (int i = 0; i < vfp_registers->childCount(); ++i)
|
||||
for (int i = 0; i < vfp_registers->childCount(); ++i) {
|
||||
vfp_registers->child(i)->setText(
|
||||
1, QStringLiteral("0x%1").arg(Core::GetCore(0).GetVFPReg(i), 8, 16, QLatin1Char('0')));
|
||||
1, QStringLiteral("0x%1").arg(core.GetVFPReg(i), 8, 16, QLatin1Char('0')));
|
||||
}
|
||||
|
||||
UpdateCPSRValues();
|
||||
UpdateVFPSystemRegisterValues();
|
||||
|
@ -86,24 +90,29 @@ void RegistersWidget::OnEmulationStarting(EmuThread* emu_thread) {
|
|||
|
||||
void RegistersWidget::OnEmulationStopping() {
|
||||
// Reset widget text
|
||||
for (int i = 0; i < core_registers->childCount(); ++i)
|
||||
for (int i = 0; i < core_registers->childCount(); ++i) {
|
||||
core_registers->child(i)->setText(1, QString{});
|
||||
}
|
||||
|
||||
for (int i = 0; i < vfp_registers->childCount(); ++i)
|
||||
for (int i = 0; i < vfp_registers->childCount(); ++i) {
|
||||
vfp_registers->child(i)->setText(1, QString{});
|
||||
}
|
||||
|
||||
for (int i = 0; i < cpsr->childCount(); ++i)
|
||||
for (int i = 0; i < cpsr->childCount(); ++i) {
|
||||
cpsr->child(i)->setText(1, QString{});
|
||||
}
|
||||
|
||||
cpsr->setText(1, QString{});
|
||||
|
||||
// FPSCR
|
||||
for (int i = 0; i < vfp_system_registers->child(0)->childCount(); ++i)
|
||||
for (int i = 0; i < vfp_system_registers->child(0)->childCount(); ++i) {
|
||||
vfp_system_registers->child(0)->child(i)->setText(1, QString{});
|
||||
}
|
||||
|
||||
// FPEXC
|
||||
for (int i = 0; i < vfp_system_registers->child(1)->childCount(); ++i)
|
||||
for (int i = 0; i < vfp_system_registers->child(1)->childCount(); ++i) {
|
||||
vfp_system_registers->child(1)->child(i)->setText(1, QString{});
|
||||
}
|
||||
|
||||
vfp_system_registers->child(0)->setText(1, QString{});
|
||||
vfp_system_registers->child(1)->setText(1, QString{});
|
||||
|
@ -130,8 +139,8 @@ void RegistersWidget::CreateCPSRChildren() {
|
|||
}
|
||||
|
||||
void RegistersWidget::UpdateCPSRValues() {
|
||||
// Todo: Handle all cores
|
||||
const u32 cpsr_val = Core::GetCore(0).GetCPSR();
|
||||
// TODO: Handle all cores
|
||||
const u32 cpsr_val = system.GetCore(0).GetCPSR();
|
||||
|
||||
cpsr->setText(1, QStringLiteral("0x%1").arg(cpsr_val, 8, 16, QLatin1Char('0')));
|
||||
cpsr->child(0)->setText(
|
||||
|
@ -193,9 +202,10 @@ void RegistersWidget::CreateVFPSystemRegisterChildren() {
|
|||
}
|
||||
|
||||
void RegistersWidget::UpdateVFPSystemRegisterValues() {
|
||||
// Todo: handle all cores
|
||||
const u32 fpscr_val = Core::GetCore(0).GetVFPSystemReg(VFP_FPSCR);
|
||||
const u32 fpexc_val = Core::GetCore(0).GetVFPSystemReg(VFP_FPEXC);
|
||||
// TODO: handle all cores
|
||||
const ARM_Interface& core = system.GetCore(0);
|
||||
const u32 fpscr_val = core.GetVFPSystemReg(VFP_FPSCR);
|
||||
const u32 fpexc_val = core.GetVFPSystemReg(VFP_FPEXC);
|
||||
|
||||
QTreeWidgetItem* const fpscr = vfp_system_registers->child(0);
|
||||
fpscr->setText(1, QStringLiteral("0x%1").arg(fpscr_val, 8, 16, QLatin1Char('0')));
|
||||
|
|
|
@ -15,11 +15,15 @@ namespace Ui {
|
|||
class ARMRegisters;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
class RegistersWidget : public QDockWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RegistersWidget(QWidget* parent = nullptr);
|
||||
explicit RegistersWidget(const Core::System& system, QWidget* parent = nullptr);
|
||||
~RegistersWidget();
|
||||
|
||||
public slots:
|
||||
|
@ -37,7 +41,7 @@ private:
|
|||
void UpdateVFPSystemRegisterValues();
|
||||
|
||||
std::unique_ptr<Ui::ARMRegisters> cpu_regs_ui;
|
||||
|
||||
const Core::System& system;
|
||||
QTreeWidget* tree;
|
||||
|
||||
QTreeWidgetItem* core_registers;
|
||||
|
|
|
@ -75,13 +75,13 @@ std::size_t WaitTreeItem::Row() const {
|
|||
return row;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList() {
|
||||
const u32 num_cores = Core::GetNumCores();
|
||||
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList(
|
||||
Core::System& system) {
|
||||
const u32 num_cores = system.GetNumCores();
|
||||
std::vector<std::unique_ptr<WaitTreeThread>> item_list;
|
||||
item_list.reserve(num_cores);
|
||||
for (u32 i = 0; i < num_cores; ++i) {
|
||||
const auto& threads =
|
||||
Core::System::GetInstance().Kernel().GetThreadManager(i).GetThreadList();
|
||||
const auto threads = system.Kernel().GetThreadManager(i).GetThreadList();
|
||||
item_list.reserve(item_list.size() + threads.size());
|
||||
for (std::size_t j = 0; j < threads.size(); ++j) {
|
||||
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[j]));
|
||||
|
@ -435,11 +435,12 @@ void WaitTreeModel::ClearItems() {
|
|||
thread_items.clear();
|
||||
}
|
||||
|
||||
void WaitTreeModel::InitItems() {
|
||||
thread_items = WaitTreeItem::MakeThreadItemList();
|
||||
void WaitTreeModel::InitItems(Core::System& system) {
|
||||
thread_items = WaitTreeItem::MakeThreadItemList(system);
|
||||
}
|
||||
|
||||
WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), parent) {
|
||||
WaitTreeWidget::WaitTreeWidget(Core::System& system_, QWidget* parent)
|
||||
: QDockWidget(tr("Wait Tree"), parent), system{system_} {
|
||||
setObjectName(QStringLiteral("WaitTreeWidget"));
|
||||
view = new QTreeView(this);
|
||||
view->setHeaderHidden(true);
|
||||
|
@ -448,9 +449,10 @@ WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), p
|
|||
}
|
||||
|
||||
void WaitTreeWidget::OnDebugModeEntered() {
|
||||
if (!Core::System::GetInstance().IsPoweredOn())
|
||||
if (!system.IsPoweredOn()) {
|
||||
return;
|
||||
model->InitItems();
|
||||
}
|
||||
model->InitItems(system);
|
||||
view->setModel(model);
|
||||
setEnabled(true);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ class Thread;
|
|||
class Timer;
|
||||
} // namespace Kernel
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
class WaitTreeThread;
|
||||
|
||||
class WaitTreeItem : public QObject {
|
||||
|
@ -39,7 +43,7 @@ public:
|
|||
WaitTreeItem* Parent() const;
|
||||
std::span<const std::unique_ptr<WaitTreeItem>> Children() const;
|
||||
std::size_t Row() const;
|
||||
static std::vector<std::unique_ptr<WaitTreeThread>> MakeThreadItemList();
|
||||
static std::vector<std::unique_ptr<WaitTreeThread>> MakeThreadItemList(Core::System& system);
|
||||
|
||||
private:
|
||||
std::size_t row;
|
||||
|
@ -166,7 +170,7 @@ public:
|
|||
int columnCount(const QModelIndex& parent) const override;
|
||||
|
||||
void ClearItems();
|
||||
void InitItems();
|
||||
void InitItems(Core::System& system);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<WaitTreeThread>> thread_items;
|
||||
|
@ -176,7 +180,7 @@ class WaitTreeWidget : public QDockWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WaitTreeWidget(QWidget* parent = nullptr);
|
||||
explicit WaitTreeWidget(Core::System& system, QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void OnDebugModeEntered();
|
||||
|
@ -188,4 +192,5 @@ public slots:
|
|||
private:
|
||||
QTreeView* view;
|
||||
WaitTreeModel* model;
|
||||
Core::System& system;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue