mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-05 15:56:49 +00:00
memory viewer: Implement SPU mode, fix address GOTO
This commit is contained in:
parent
7fc26b1fab
commit
c4c6dc19a5
@ -320,22 +320,7 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
case Qt::Key_M:
|
||||
{
|
||||
// Memory viewer
|
||||
|
||||
u32 addr = pc;
|
||||
|
||||
if (auto spu = static_cast<const spu_thread*>(cpu->id_type() == 2 ? cpu.get() : nullptr))
|
||||
{
|
||||
if (spu->get_type() != spu_type::threaded)
|
||||
{
|
||||
addr += RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * spu->index;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr += SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (spu->id & 0xffffff);
|
||||
}
|
||||
}
|
||||
|
||||
auto mvp = new memory_viewer_panel(this, addr);
|
||||
auto mvp = new memory_viewer_panel(this, pc, cpu);
|
||||
mvp->show();
|
||||
return;
|
||||
}
|
||||
|
@ -16,19 +16,23 @@
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "util/asm.hpp"
|
||||
#include "util/vm.hpp"
|
||||
|
||||
constexpr auto qstr = QString::fromStdString;
|
||||
|
||||
memory_viewer_panel::memory_viewer_panel(QWidget* parent, u32 addr)
|
||||
memory_viewer_panel::memory_viewer_panel(QWidget* parent, u32 addr, const std::shared_ptr<cpu_thread>& cpu)
|
||||
: QDialog(parent)
|
||||
, m_addr(addr)
|
||||
, m_type(!cpu || cpu->id_type() != 2 ? thread_type::ppu : thread_type::spu)
|
||||
, m_spu_shm(m_type == thread_type::spu ? static_cast<spu_thread*>(cpu.get())->shm : nullptr)
|
||||
, m_addr_mask(m_type == thread_type::spu ? SPU_LS_SIZE - 1 : ~0)
|
||||
{
|
||||
setWindowTitle(tr("Memory Viewer"));
|
||||
setWindowTitle(m_type != thread_type::spu ? tr("Memory Viewer") : tr("Memory Viewer Of %0").arg(qstr(cpu->get_name())));
|
||||
|
||||
setObjectName("memory_viewer");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
m_colcount = 4;
|
||||
m_rowcount = 16;
|
||||
m_addr -= m_addr % (m_colcount * 4); // Align by amount of bytes in a row
|
||||
int pSize = 10;
|
||||
|
||||
// Font
|
||||
@ -51,12 +55,11 @@ memory_viewer_panel::memory_viewer_panel(QWidget* parent, u32 addr)
|
||||
QHBoxLayout* hbox_tools_mem_addr = new QHBoxLayout();
|
||||
m_addr_line = new QLineEdit(this);
|
||||
m_addr_line->setPlaceholderText("00000000");
|
||||
m_addr_line->setText(qstr(fmt::format("%08x", m_addr)));
|
||||
m_addr_line->setFont(mono);
|
||||
m_addr_line->setMaxLength(18);
|
||||
m_addr_line->setFixedWidth(75);
|
||||
m_addr_line->setFocus();
|
||||
m_addr_line->setValidator(new QRegExpValidator(QRegExp("^(0[xX])?0*[a-fA-F0-9]{0,8}$")));
|
||||
m_addr_line->setValidator(new QRegExpValidator(QRegExp(m_type == thread_type::spu ? "^(0[xX])?0*[a-fA-F0-9]{0,5}$" : "^(0[xX])?0*[a-fA-F0-9]{0,8}$")));
|
||||
hbox_tools_mem_addr->addWidget(m_addr_line);
|
||||
tools_mem_addr->setLayout(hbox_tools_mem_addr);
|
||||
|
||||
@ -125,8 +128,8 @@ memory_viewer_panel::memory_viewer_panel(QWidget* parent, u32 addr)
|
||||
QLabel* l_x = new QLabel(" x ");
|
||||
QSpinBox* sb_img_size_x = new QSpinBox(this);
|
||||
QSpinBox* sb_img_size_y = new QSpinBox(this);
|
||||
sb_img_size_x->setRange(1, 8192);
|
||||
sb_img_size_y->setRange(1, 8192);
|
||||
sb_img_size_x->setRange(1, m_type == thread_type::spu ? 256 : 4096);
|
||||
sb_img_size_y->setRange(1, m_type == thread_type::spu ? 256 : 4096);
|
||||
sb_img_size_x->setValue(256);
|
||||
sb_img_size_y->setValue(256);
|
||||
hbox_tools_img_size->addWidget(sb_img_size_x);
|
||||
@ -225,17 +228,18 @@ memory_viewer_panel::memory_viewer_panel(QWidget* parent, u32 addr)
|
||||
vbox_panel->setSizeConstraint(QLayout::SetNoConstraint);
|
||||
setLayout(vbox_panel);
|
||||
|
||||
// Fill the QTextEdits
|
||||
scroll(0);
|
||||
|
||||
// Events
|
||||
connect(m_addr_line, &QLineEdit::returnPressed, [this]()
|
||||
{
|
||||
bool ok = false;
|
||||
const QString text = m_addr_line->text();
|
||||
const u32 addr = (text.startsWith("0x", Qt::CaseInsensitive) ? text.right(text.size() - 2) : text).toULong(&ok, 16);
|
||||
if (!ok) return;
|
||||
if (ok) m_addr = addr;
|
||||
|
||||
m_addr -= m_addr % (m_colcount * 4); // Align by amount of bytes in a row
|
||||
m_addr_line->setText(QString("%1").arg(m_addr, 8, 16, QChar('0'))); // get 8 digits in input line
|
||||
ShowMemory();
|
||||
scroll(0); // Refresh
|
||||
});
|
||||
connect(sb_words, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=, this]()
|
||||
{
|
||||
@ -255,9 +259,6 @@ memory_viewer_panel::memory_viewer_panel(QWidget* parent, u32 addr)
|
||||
ShowImage(this, m_addr, format, sizex, sizey, false);
|
||||
});
|
||||
|
||||
// Fill the QTextEdits
|
||||
ShowMemory();
|
||||
|
||||
setFixedWidth(sizeHint().width());
|
||||
}
|
||||
|
||||
@ -279,9 +280,10 @@ void memory_viewer_panel::wheelEvent(QWheelEvent *event)
|
||||
|
||||
void memory_viewer_panel::scroll(s32 steps)
|
||||
{
|
||||
if (steps == 0) return;
|
||||
m_addr += m_colcount * 4 * steps; // Add steps
|
||||
m_addr &= m_addr_mask; // Mask it
|
||||
m_addr -= m_addr % (m_colcount * 4); // Align by amount of bytes in a row
|
||||
|
||||
m_addr += m_colcount * 4 * steps;
|
||||
m_addr_line->setText(qstr(fmt::format("%08x", m_addr)));
|
||||
ShowMemory();
|
||||
}
|
||||
@ -314,6 +316,8 @@ void memory_viewer_panel::resizeEvent(QResizeEvent *event)
|
||||
|
||||
std::string memory_viewer_panel::getHeaderAtAddr(u32 addr)
|
||||
{
|
||||
if (m_type == thread_type::spu) return {};
|
||||
|
||||
// Check if its an SPU Local Storage beginning
|
||||
const u32 spu_boundary = utils::align<u32>(addr, SPU_LS_SIZE);
|
||||
|
||||
@ -366,7 +370,7 @@ void memory_viewer_panel::ShowMemory()
|
||||
|
||||
{
|
||||
// Check if this address contains potential header
|
||||
const u32 addr = m_addr + (row - spu_passed) * m_colcount * 4;
|
||||
const u32 addr = (m_addr + (row - spu_passed) * m_colcount * 4) & m_addr_mask;
|
||||
const std::string header = getHeaderAtAddr(addr);
|
||||
if (!header.empty())
|
||||
{
|
||||
@ -412,7 +416,7 @@ void memory_viewer_panel::ShowMemory()
|
||||
}
|
||||
}
|
||||
|
||||
t_mem_addr_str += qstr(fmt::format("%08x", m_addr + (row - spu_passed) * m_colcount * 4));
|
||||
t_mem_addr_str += qstr(fmt::format("%08x", (m_addr + (row - spu_passed) * m_colcount * 4) & m_addr_mask));
|
||||
}
|
||||
|
||||
for (u32 col = 0; col < m_colcount; col++)
|
||||
@ -422,11 +426,11 @@ void memory_viewer_panel::ShowMemory()
|
||||
t_mem_hex_str += " ";
|
||||
}
|
||||
|
||||
u32 addr = m_addr + (row - spu_passed) * m_colcount * 4 + col * 4;
|
||||
u32 addr = (m_addr + (row - spu_passed) * m_colcount * 4 + col * 4) & m_addr_mask;
|
||||
|
||||
if (vm::check_addr(addr, 0, 4))
|
||||
if (m_spu_shm || vm::check_addr(addr, 0, 4))
|
||||
{
|
||||
const be_t<u32> rmem = *vm::get_super_ptr<u32>(addr);
|
||||
const be_t<u32> rmem = m_spu_shm ? *reinterpret_cast<be_t<u32>*>(m_spu_shm->map_self() + addr) : *vm::get_super_ptr<u32>(addr);
|
||||
t_mem_hex_str += qstr(fmt::format("%02x %02x %02x %02x",
|
||||
static_cast<u8>(rmem >> 24),
|
||||
static_cast<u8>(rmem >> 16),
|
||||
@ -472,20 +476,28 @@ void memory_viewer_panel::SetPC(const uint pc)
|
||||
|
||||
void memory_viewer_panel::ShowImage(QWidget* parent, u32 addr, color_format format, u32 width, u32 height, bool flipv)
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
const u64 memsize = 4ull * width * height;
|
||||
|
||||
if (!memsize || memsize > m_addr_mask)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_lock rlock(vm::g_mutex);
|
||||
|
||||
if (!vm::check_addr(addr, 0, width * height * 4))
|
||||
if (!m_spu_shm && !vm::check_addr(addr, 0, static_cast<u32>(memsize)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto originalBuffer = vm::get_super_ptr<const uchar>(addr);
|
||||
const auto convertedBuffer = static_cast<uchar*>(std::malloc(4ULL * width * height));
|
||||
const auto originalBuffer = m_spu_shm ? (m_spu_shm->map_self() + addr) : vm::get_super_ptr<const u8>(addr);
|
||||
const auto convertedBuffer = new (std::nothrow) u8[static_cast<u32>(memsize)];
|
||||
|
||||
if (!convertedBuffer)
|
||||
{
|
||||
// OOM, give up
|
||||
return;
|
||||
}
|
||||
|
||||
switch (format)
|
||||
{
|
||||
@ -576,7 +588,7 @@ void memory_viewer_panel::ShowImage(QWidget* parent, u32 addr, color_format form
|
||||
}
|
||||
}
|
||||
|
||||
QImage image(convertedBuffer, width, height, QImage::Format_ARGB32, [](void* buffer){ std::free(buffer); }, convertedBuffer);
|
||||
QImage image(convertedBuffer, width, height, QImage::Format_ARGB32, [](void* buffer){ delete[] static_cast<u8*>(buffer); }, convertedBuffer);
|
||||
if (image.isNull()) return;
|
||||
|
||||
QLabel* canvas = new QLabel();
|
||||
|
@ -10,12 +10,19 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
class cpu_thread;
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class shm;
|
||||
}
|
||||
|
||||
class memory_viewer_panel : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
memory_viewer_panel(QWidget* parent, u32 addr = 0);
|
||||
memory_viewer_panel(QWidget* parent, u32 addr = 0, const std::shared_ptr<cpu_thread>& cpu = nullptr);
|
||||
~memory_viewer_panel();
|
||||
|
||||
enum class color_format : int
|
||||
@ -44,11 +51,22 @@ private:
|
||||
|
||||
QFontMetrics* m_fontMetrics;
|
||||
|
||||
enum class thread_type
|
||||
{
|
||||
ppu,
|
||||
spu,
|
||||
//rsx
|
||||
};
|
||||
|
||||
const thread_type m_type;
|
||||
const std::shared_ptr<utils::shm> m_spu_shm;
|
||||
const u32 m_addr_mask;
|
||||
|
||||
std::string getHeaderAtAddr(u32 addr);
|
||||
void scroll(s32 steps);
|
||||
void SetPC(const uint pc);
|
||||
|
||||
virtual void ShowMemory();
|
||||
|
||||
static void ShowImage(QWidget* parent, u32 addr, color_format format, u32 sizex, u32 sizey, bool flipv);
|
||||
void ShowImage(QWidget* parent, u32 addr, color_format format, u32 sizex, u32 sizey, bool flipv);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user