|
|
@ -1,7 +1,6 @@
|
|
|
|
#include "rsx_debugger.h"
|
|
|
|
#include "rsx_debugger.h"
|
|
|
|
#include "gui_settings.h"
|
|
|
|
#include "gui_settings.h"
|
|
|
|
#include "qt_utils.h"
|
|
|
|
#include "qt_utils.h"
|
|
|
|
#include "memory_viewer_panel.h"
|
|
|
|
|
|
|
|
#include "table_item_delegate.h"
|
|
|
|
#include "table_item_delegate.h"
|
|
|
|
#include "Emu/RSX/RSXThread.h"
|
|
|
|
#include "Emu/RSX/RSXThread.h"
|
|
|
|
#include "Emu/RSX/gcm_printing.h"
|
|
|
|
#include "Emu/RSX/gcm_printing.h"
|
|
|
@ -9,6 +8,7 @@
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include <QHeaderView>
|
|
|
|
#include <QHeaderView>
|
|
|
|
#include <QFont>
|
|
|
|
#include <QFont>
|
|
|
|
|
|
|
|
#include <QFontDatabase>
|
|
|
|
#include <QPixmap>
|
|
|
|
#include <QPixmap>
|
|
|
|
#include <QPushButton>
|
|
|
|
#include <QPushButton>
|
|
|
|
#include <QKeyEvent>
|
|
|
|
#include <QKeyEvent>
|
|
|
@ -38,7 +38,7 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
|
|
|
|
setObjectName("rsx_debugger");
|
|
|
|
setObjectName("rsx_debugger");
|
|
|
|
setWindowFlags(Qt::Window);
|
|
|
|
setWindowFlags(Qt::Window);
|
|
|
|
|
|
|
|
|
|
|
|
//Fonts and Colors
|
|
|
|
// Fonts and Colors
|
|
|
|
QFont mono = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
|
|
|
QFont mono = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
|
|
|
mono.setPointSize(8);
|
|
|
|
mono.setPointSize(8);
|
|
|
|
QLabel l("000000000"); // hacky way to get the lineedit to resize properly
|
|
|
|
QLabel l("000000000"); // hacky way to get the lineedit to resize properly
|
|
|
@ -109,7 +109,7 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
|
|
|
|
m_tw_rsx = new QTabWidget();
|
|
|
|
m_tw_rsx = new QTabWidget();
|
|
|
|
|
|
|
|
|
|
|
|
// adds a tab containing a list to the tabwidget
|
|
|
|
// adds a tab containing a list to the tabwidget
|
|
|
|
auto l_addRSXTab = [=, this](QTableWidget* table, const QString& tabname, int columns)
|
|
|
|
const auto add_rsx_tab = [this, &mono](QTableWidget* table, const QString& tabname, int columns)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
table = new QTableWidget();
|
|
|
|
table = new QTableWidget();
|
|
|
|
table->setItemDelegate(new table_item_delegate);
|
|
|
|
table->setItemDelegate(new table_item_delegate);
|
|
|
@ -134,9 +134,9 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
|
|
|
|
m_addr = render->ctrl->get;
|
|
|
|
m_addr = render->ctrl->get;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_list_commands = l_addRSXTab(m_list_commands, tr("RSX Commands"), 4);
|
|
|
|
m_list_commands = add_rsx_tab(m_list_commands, tr("RSX Commands"), 4);
|
|
|
|
m_list_captured_frame = l_addRSXTab(m_list_captured_frame, tr("Captured Frame"), 1);
|
|
|
|
m_list_captured_frame = add_rsx_tab(m_list_captured_frame, tr("Captured Frame"), 1);
|
|
|
|
m_list_captured_draw_calls = l_addRSXTab(m_list_captured_draw_calls, tr("Captured Draw Calls"), 1);
|
|
|
|
m_list_captured_draw_calls = add_rsx_tab(m_list_captured_draw_calls, tr("Captured Draw Calls"), 1);
|
|
|
|
|
|
|
|
|
|
|
|
// Tabs: List Columns
|
|
|
|
// Tabs: List Columns
|
|
|
|
m_list_commands->viewport()->installEventFilter(this);
|
|
|
|
m_list_commands->viewport()->installEventFilter(this);
|
|
|
@ -171,7 +171,7 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
|
|
|
|
m_list_index_buffer = new QListWidget();
|
|
|
|
m_list_index_buffer = new QListWidget();
|
|
|
|
m_list_index_buffer->setFont(mono);
|
|
|
|
m_list_index_buffer->setFont(mono);
|
|
|
|
|
|
|
|
|
|
|
|
//Panels for displaying the buffers
|
|
|
|
// Panels for displaying the buffers
|
|
|
|
m_buffer_colorA = new Buffer(false, 0, tr("Color Buffer A"), this);
|
|
|
|
m_buffer_colorA = new Buffer(false, 0, tr("Color Buffer A"), this);
|
|
|
|
m_buffer_colorB = new Buffer(false, 1, tr("Color Buffer B"), this);
|
|
|
|
m_buffer_colorB = new Buffer(false, 1, tr("Color Buffer B"), this);
|
|
|
|
m_buffer_colorC = new Buffer(false, 2, tr("Color Buffer C"), this);
|
|
|
|
m_buffer_colorC = new Buffer(false, 2, tr("Color Buffer C"), this);
|
|
|
@ -180,7 +180,7 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
|
|
|
|
m_buffer_stencil = new Buffer(false, 4, tr("Stencil Buffer"), this);
|
|
|
|
m_buffer_stencil = new Buffer(false, 4, tr("Stencil Buffer"), this);
|
|
|
|
m_buffer_tex = new Buffer(true, 4, tr("Texture"), this);
|
|
|
|
m_buffer_tex = new Buffer(true, 4, tr("Texture"), this);
|
|
|
|
|
|
|
|
|
|
|
|
//Merge and display everything
|
|
|
|
// Merge and display everything
|
|
|
|
QVBoxLayout* vbox_buffers1 = new QVBoxLayout();
|
|
|
|
QVBoxLayout* vbox_buffers1 = new QVBoxLayout();
|
|
|
|
vbox_buffers1->addWidget(m_buffer_colorA);
|
|
|
|
vbox_buffers1->addWidget(m_buffer_colorA);
|
|
|
|
vbox_buffers1->addWidget(m_buffer_colorC);
|
|
|
|
vbox_buffers1->addWidget(m_buffer_colorC);
|
|
|
@ -213,7 +213,7 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
|
|
|
|
main_layout->addWidget(state_rsx, 1);
|
|
|
|
main_layout->addWidget(state_rsx, 1);
|
|
|
|
setLayout(main_layout);
|
|
|
|
setLayout(main_layout);
|
|
|
|
|
|
|
|
|
|
|
|
//Events
|
|
|
|
// Events
|
|
|
|
connect(b_goto_get, &QAbstractButton::clicked, [this]()
|
|
|
|
connect(b_goto_get, &QAbstractButton::clicked, [this]()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (const auto render = rsx::get_current_renderer(); render && render->ctrl &&
|
|
|
|
if (const auto render = rsx::get_current_renderer(); render && render->ctrl &&
|
|
|
@ -255,7 +255,6 @@ rsx_debugger::rsx_debugger(std::shared_ptr<gui_settings> gui_settings, QWidget*
|
|
|
|
|
|
|
|
|
|
|
|
rsx_debugger::~rsx_debugger()
|
|
|
|
rsx_debugger::~rsx_debugger()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
exit = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void rsx_debugger::closeEvent(QCloseEvent* event)
|
|
|
|
void rsx_debugger::closeEvent(QCloseEvent* event)
|
|
|
@ -273,11 +272,12 @@ void rsx_debugger::closeEvent(QCloseEvent* event)
|
|
|
|
|
|
|
|
|
|
|
|
void rsx_debugger::keyPressEvent(QKeyEvent* event)
|
|
|
|
void rsx_debugger::keyPressEvent(QKeyEvent* event)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(isActiveWindow())
|
|
|
|
if (isActiveWindow())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
switch(event->key())
|
|
|
|
switch (event->key())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case Qt::Key_F5: UpdateInformation(); break;
|
|
|
|
case Qt::Key_F5: UpdateInformation(); break;
|
|
|
|
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -304,12 +304,13 @@ bool rsx_debugger::eventFilter(QObject* object, QEvent* event)
|
|
|
|
case QEvent::Wheel:
|
|
|
|
case QEvent::Wheel:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
|
|
|
|
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
|
|
|
|
QPoint numSteps = wheelEvent->angleDelta() / 8 / 15; // http://doc.qt.io/qt-5/qwheelevent.html#pixelDelta
|
|
|
|
const QPoint numSteps = wheelEvent->angleDelta() / 8 / 15; // http://doc.qt.io/qt-5/qwheelevent.html#pixelDelta
|
|
|
|
int steps = numSteps.y();
|
|
|
|
const int steps = numSteps.y();
|
|
|
|
int item_count = m_list_commands->rowCount();
|
|
|
|
const int item_count = m_list_commands->rowCount();
|
|
|
|
int step_size = wheelEvent->modifiers() & Qt::ControlModifier ? item_count : 1;
|
|
|
|
const int step_size = wheelEvent->modifiers() & Qt::ControlModifier ? item_count : 1;
|
|
|
|
m_addr -= step_size * 4 * steps;
|
|
|
|
m_addr -= step_size * 4 * steps;
|
|
|
|
UpdateInformation();
|
|
|
|
UpdateInformation();
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -357,7 +358,7 @@ void Buffer::showImage(const QImage& image)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
m_image = image;
|
|
|
|
m_image = image;
|
|
|
|
QImage scaled = m_image.scaled(m_image_size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
|
const QImage scaled = m_image.scaled(m_image_size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
|
m_canvas->setPixmap(QPixmap::fromImage(scaled));
|
|
|
|
m_canvas->setPixmap(QPixmap::fromImage(scaled));
|
|
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* new_layout = new QHBoxLayout();
|
|
|
|
QHBoxLayout* new_layout = new QHBoxLayout();
|
|
|
@ -385,16 +386,16 @@ void Buffer::ShowWindowed()
|
|
|
|
|
|
|
|
|
|
|
|
gui::utils::show_windowed_image(m_image, title());
|
|
|
|
gui::utils::show_windowed_image(m_image, title());
|
|
|
|
|
|
|
|
|
|
|
|
if (m_isTex)
|
|
|
|
//if (m_isTex)
|
|
|
|
{
|
|
|
|
//{
|
|
|
|
/* u8 location = render->textures[m_cur_texture].location();
|
|
|
|
// u8 location = render->textures[m_cur_texture].location();
|
|
|
|
if(location <= 1 && vm::check_addr(rsx::get_address(render->textures[m_cur_texture].offset(), location))
|
|
|
|
// if (location <= 1 && vm::check_addr(rsx::get_address(render->textures[m_cur_texture].offset(), location))
|
|
|
|
&& render->textures[m_cur_texture].width() && render->textures[m_cur_texture].height())
|
|
|
|
// && render->textures[m_cur_texture].width() && render->textures[m_cur_texture].height())
|
|
|
|
memory_viewer_panel::ShowImage(this,
|
|
|
|
// memory_viewer_panel::ShowImage(this,
|
|
|
|
rsx::get_address(render->textures[m_cur_texture].offset(), location), 1,
|
|
|
|
// rsx::get_address(render->textures[m_cur_texture].offset(), location), 1,
|
|
|
|
render->textures[m_cur_texture].width(),
|
|
|
|
// render->textures[m_cur_texture].width(),
|
|
|
|
render->textures[m_cur_texture].height(), false);*/
|
|
|
|
// render->textures[m_cur_texture].height(), false);
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -406,44 +407,44 @@ namespace
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case rsx::surface_color_format::b8:
|
|
|
|
case rsx::surface_color_format::b8:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
u8 value = as_const_span<const u8>(orig_buffer)[idx];
|
|
|
|
const u8 value = as_const_span<const u8>(orig_buffer)[idx];
|
|
|
|
return{ value, value, value };
|
|
|
|
return{ value, value, value };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case rsx::surface_color_format::x32:
|
|
|
|
case rsx::surface_color_format::x32:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
be_t<u32> stored_val = as_const_span<const be_t<u32>>(orig_buffer)[idx];
|
|
|
|
const be_t<u32> stored_val = as_const_span<const be_t<u32>>(orig_buffer)[idx];
|
|
|
|
u32 swapped_val = stored_val;
|
|
|
|
const u32 swapped_val = stored_val;
|
|
|
|
f32 float_val = std::bit_cast<f32>(swapped_val);
|
|
|
|
const f32 float_val = std::bit_cast<f32>(swapped_val);
|
|
|
|
u8 val = float_val * 255.f;
|
|
|
|
const u8 val = float_val * 255.f;
|
|
|
|
return{ val, val, val };
|
|
|
|
return{ val, val, val };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case rsx::surface_color_format::a8b8g8r8:
|
|
|
|
case rsx::surface_color_format::a8b8g8r8:
|
|
|
|
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
|
|
|
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
|
|
|
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
|
|
|
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
auto ptr = as_const_span<const u8>(orig_buffer);
|
|
|
|
const auto ptr = as_const_span<const u8>(orig_buffer);
|
|
|
|
return{ ptr[1 + idx * 4], ptr[2 + idx * 4], ptr[3 + idx * 4] };
|
|
|
|
return{ ptr[1 + idx * 4], ptr[2 + idx * 4], ptr[3 + idx * 4] };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case rsx::surface_color_format::a8r8g8b8:
|
|
|
|
case rsx::surface_color_format::a8r8g8b8:
|
|
|
|
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
|
|
|
|
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
|
|
|
|
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
|
|
|
|
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
auto ptr = as_const_span<const u8>(orig_buffer);
|
|
|
|
const auto ptr = as_const_span<const u8>(orig_buffer);
|
|
|
|
return{ ptr[3 + idx * 4], ptr[2 + idx * 4], ptr[1 + idx * 4] };
|
|
|
|
return{ ptr[3 + idx * 4], ptr[2 + idx * 4], ptr[1 + idx * 4] };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case rsx::surface_color_format::w16z16y16x16:
|
|
|
|
case rsx::surface_color_format::w16z16y16x16:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
auto ptr = as_const_span<const u16>(orig_buffer);
|
|
|
|
const auto ptr = as_const_span<const u16>(orig_buffer);
|
|
|
|
f16 h0 = f16(ptr[4 * idx]);
|
|
|
|
const f16 h0 = f16(ptr[4 * idx]);
|
|
|
|
f16 h1 = f16(ptr[4 * idx + 1]);
|
|
|
|
const f16 h1 = f16(ptr[4 * idx + 1]);
|
|
|
|
f16 h2 = f16(ptr[4 * idx + 2]);
|
|
|
|
const f16 h2 = f16(ptr[4 * idx + 2]);
|
|
|
|
f32 f0 = float(h0);
|
|
|
|
const f32 f0 = float(h0);
|
|
|
|
f32 f1 = float(h1);
|
|
|
|
const f32 f1 = float(h1);
|
|
|
|
f32 f2 = float(h2);
|
|
|
|
const f32 f2 = float(h2);
|
|
|
|
|
|
|
|
|
|
|
|
u8 val0 = f0 * 255.;
|
|
|
|
const u8 val0 = f0 * 255.;
|
|
|
|
u8 val1 = f1 * 255.;
|
|
|
|
const u8 val1 = f1 * 255.;
|
|
|
|
u8 val2 = f2 * 255.;
|
|
|
|
const u8 val2 = f2 * 255.;
|
|
|
|
return{ val0, val1, val2 };
|
|
|
|
return{ val0, val1, val2 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case rsx::surface_color_format::g8b8:
|
|
|
|
case rsx::surface_color_format::g8b8:
|
|
|
@ -477,7 +478,7 @@ namespace
|
|
|
|
|
|
|
|
|
|
|
|
void rsx_debugger::OnClickDrawCalls()
|
|
|
|
void rsx_debugger::OnClickDrawCalls()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
usz draw_id = m_list_captured_draw_calls->currentRow();
|
|
|
|
const usz draw_id = m_list_captured_draw_calls->currentRow();
|
|
|
|
|
|
|
|
|
|
|
|
const auto& draw_call = frame_debug.draw_calls[draw_id];
|
|
|
|
const auto& draw_call = frame_debug.draw_calls[draw_id];
|
|
|
|
|
|
|
|
|
|
|
@ -489,8 +490,8 @@ void rsx_debugger::OnClickDrawCalls()
|
|
|
|
m_buffer_colorD,
|
|
|
|
m_buffer_colorD,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
u32 width = draw_call.state.surface_clip_width();
|
|
|
|
const u32 width = draw_call.state.surface_clip_width();
|
|
|
|
u32 height = draw_call.state.surface_clip_height();
|
|
|
|
const u32 height = draw_call.state.surface_clip_height();
|
|
|
|
|
|
|
|
|
|
|
|
for (usz i = 0; i < 4; i++)
|
|
|
|
for (usz i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -506,7 +507,7 @@ void rsx_debugger::OnClickDrawCalls()
|
|
|
|
if (width && height && !draw_call.depth_stencil[0].empty())
|
|
|
|
if (width && height && !draw_call.depth_stencil[0].empty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
gsl::span<const std::byte> orig_buffer = draw_call.depth_stencil[0];
|
|
|
|
gsl::span<const std::byte> orig_buffer = draw_call.depth_stencil[0];
|
|
|
|
u8* buffer = static_cast<u8*>(std::malloc(width * height * 4));
|
|
|
|
u8* buffer = static_cast<u8*>(std::malloc(4ULL * width * height));
|
|
|
|
|
|
|
|
|
|
|
|
if (draw_call.state.surface_depth_fmt() == rsx::surface_depth_format::z24s8)
|
|
|
|
if (draw_call.state.surface_depth_fmt() == rsx::surface_depth_format::z24s8)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -514,8 +515,8 @@ void rsx_debugger::OnClickDrawCalls()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (u32 col = 0; col < width; col++)
|
|
|
|
for (u32 col = 0; col < width; col++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
u32 depth_val = as_const_span<const u32>(orig_buffer)[row * width + col];
|
|
|
|
const u32 depth_val = as_const_span<const u32>(orig_buffer)[row * width + col];
|
|
|
|
u8 displayed_depth_val = 255 * depth_val / 0xFFFFFF;
|
|
|
|
const u8 displayed_depth_val = 255 * depth_val / 0xFFFFFF;
|
|
|
|
buffer[4 * col + 0 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 0 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 1 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 1 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 2 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 2 + width * row * 4] = displayed_depth_val;
|
|
|
@ -529,8 +530,8 @@ void rsx_debugger::OnClickDrawCalls()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (u32 col = 0; col < width; col++)
|
|
|
|
for (u32 col = 0; col < width; col++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
u16 depth_val = as_const_span<const u16>(orig_buffer)[row * width + col];
|
|
|
|
const u16 depth_val = as_const_span<const u16>(orig_buffer)[row * width + col];
|
|
|
|
u8 displayed_depth_val = 255 * depth_val / 0xFFFF;
|
|
|
|
const u8 displayed_depth_val = 255 * depth_val / 0xFFFF;
|
|
|
|
buffer[4 * col + 0 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 0 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 1 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 1 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 2 + width * row * 4] = displayed_depth_val;
|
|
|
|
buffer[4 * col + 2 + width * row * 4] = displayed_depth_val;
|
|
|
@ -547,13 +548,13 @@ void rsx_debugger::OnClickDrawCalls()
|
|
|
|
if (width && height && !draw_call.depth_stencil[1].empty())
|
|
|
|
if (width && height && !draw_call.depth_stencil[1].empty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
gsl::span<const std::byte> orig_buffer = draw_call.depth_stencil[1];
|
|
|
|
gsl::span<const std::byte> orig_buffer = draw_call.depth_stencil[1];
|
|
|
|
u8* buffer = static_cast<u8*>(std::malloc(width * height * 4));
|
|
|
|
u8* buffer = static_cast<u8*>(std::malloc(4ULL * width * height));
|
|
|
|
|
|
|
|
|
|
|
|
for (u32 row = 0; row < height; row++)
|
|
|
|
for (u32 row = 0; row < height; row++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (u32 col = 0; col < width; col++)
|
|
|
|
for (u32 col = 0; col < width; col++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
u8 stencil_val = as_const_span<const u8>(orig_buffer)[row * width + col];
|
|
|
|
const u8 stencil_val = as_const_span<const u8>(orig_buffer)[row * width + col];
|
|
|
|
buffer[4 * col + 0 + width * row * 4] = stencil_val;
|
|
|
|
buffer[4 * col + 0 + width * row * 4] = stencil_val;
|
|
|
|
buffer[4 * col + 1 + width * row * 4] = stencil_val;
|
|
|
|
buffer[4 * col + 1 + width * row * 4] = stencil_val;
|
|
|
|
buffer[4 * col + 2 + width * row * 4] = stencil_val;
|
|
|
|
buffer[4 * col + 2 + width * row * 4] = stencil_val;
|
|
|
@ -657,27 +658,27 @@ void rsx_debugger::GetBuffers()
|
|
|
|
for (u32 bufferId=0; bufferId < render->display_buffers_count; bufferId++)
|
|
|
|
for (u32 bufferId=0; bufferId < render->display_buffers_count; bufferId++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
auto buffers = render->display_buffers;
|
|
|
|
auto buffers = render->display_buffers;
|
|
|
|
u32 RSXbuffer_addr = rsx::constants::local_mem_base + buffers[bufferId].offset;
|
|
|
|
const u32 rsx_buffer_addr = rsx::constants::local_mem_base + buffers[bufferId].offset;
|
|
|
|
|
|
|
|
|
|
|
|
const u32 width = buffers[bufferId].width;
|
|
|
|
const u32 width = buffers[bufferId].width;
|
|
|
|
const u32 height = buffers[bufferId].height;
|
|
|
|
const u32 height = buffers[bufferId].height;
|
|
|
|
|
|
|
|
|
|
|
|
if (!vm::check_addr(RSXbuffer_addr, vm::page_readable, width * height * 4))
|
|
|
|
if (!vm::check_addr(rsx_buffer_addr, vm::page_readable, width * height * 4))
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
const auto RSXbuffer = vm::get_super_ptr<const u8>(RSXbuffer_addr);
|
|
|
|
const auto rsx_buffer = vm::get_super_ptr<const u8>(rsx_buffer_addr);
|
|
|
|
|
|
|
|
|
|
|
|
u8* buffer = static_cast<u8*>(std::malloc(width * height * 4));
|
|
|
|
u8* buffer = static_cast<u8*>(std::malloc(4ULL * width * height));
|
|
|
|
|
|
|
|
|
|
|
|
// ABGR to ARGB and flip vertically
|
|
|
|
// ABGR to ARGB and flip vertically
|
|
|
|
for (u32 y=0; y<height; y++)
|
|
|
|
for (u32 y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (u32 i=0, j=0; j<width*4; i+=4, j+=4)
|
|
|
|
for (u32 i = 0, j = 0; j < width * 4; i += 4, j += 4)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
buffer[i+0 + y*width*4] = RSXbuffer[j+1 + (height-y-1)*width*4]; //B
|
|
|
|
buffer[i + 0 + y * width * 4] = rsx_buffer[j + 1 + (height - y - 1) * width * 4]; // B
|
|
|
|
buffer[i+1 + y*width*4] = RSXbuffer[j+2 + (height-y-1)*width*4]; //G
|
|
|
|
buffer[i + 1 + y * width * 4] = rsx_buffer[j + 2 + (height - y - 1) * width * 4]; // G
|
|
|
|
buffer[i+2 + y*width*4] = RSXbuffer[j+3 + (height-y-1)*width*4]; //R
|
|
|
|
buffer[i + 2 + y * width * 4] = rsx_buffer[j + 3 + (height - y - 1) * width * 4]; // R
|
|
|
|
buffer[i+3 + y*width*4] = RSXbuffer[j+0 + (height-y-1)*width*4]; //A
|
|
|
|
buffer[i + 3 + y * width * 4] = rsx_buffer[j + 0 + (height - y - 1) * width * 4]; // A
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -694,32 +695,32 @@ void rsx_debugger::GetBuffers()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Draw Texture
|
|
|
|
// Draw Texture
|
|
|
|
/* if(!render->textures[m_cur_texture].enabled())
|
|
|
|
//if (!render->textures[m_cur_texture].enabled())
|
|
|
|
return;
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
|
|
u32 offset = render->textures[m_cur_texture].offset();
|
|
|
|
//u32 offset = render->textures[m_cur_texture].offset();
|
|
|
|
|
|
|
|
|
|
|
|
if(!offset)
|
|
|
|
//if(!offset)
|
|
|
|
return;
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
|
|
u8 location = render->textures[m_cur_texture].location();
|
|
|
|
//u8 location = render->textures[m_cur_texture].location();
|
|
|
|
|
|
|
|
|
|
|
|
if(location > 1)
|
|
|
|
//if(location > 1)
|
|
|
|
return;
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
|
|
u32 TexBuffer_addr = rsx::get_address(offset, location);
|
|
|
|
//u32 TexBuffer_addr = rsx::get_address(offset, location);
|
|
|
|
|
|
|
|
|
|
|
|
if(!vm::check_addr(TexBuffer_addr))
|
|
|
|
//if(!vm::check_addr(TexBuffer_addr))
|
|
|
|
return;
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
|
|
unsigned char* TexBuffer = vm::get_super_ptr<u8>(TexBuffer_addr);
|
|
|
|
//unsigned char* TexBuffer = vm::get_super_ptr<u8>(TexBuffer_addr);
|
|
|
|
|
|
|
|
|
|
|
|
u32 width = render->textures[m_cur_texture].width();
|
|
|
|
//const u32 width = render->textures[m_cur_texture].width();
|
|
|
|
u32 height = render->textures[m_cur_texture].height();
|
|
|
|
//const u32 height = render->textures[m_cur_texture].height();
|
|
|
|
unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
|
|
|
|
//unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
|
|
|
|
std::memcpy(buffer, vm::base(TexBuffer_addr), width * height * 3);
|
|
|
|
//std::memcpy(buffer, vm::base(TexBuffer_addr), width * height * 3);
|
|
|
|
|
|
|
|
|
|
|
|
m_buffer_tex->showImage(QImage(buffer, m_text_width, m_text_height, QImage::Format_RGB32));*/
|
|
|
|
//m_buffer_tex->showImage(QImage(buffer, m_text_width, m_text_height, QImage::Format_RGB32));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char* rsx_debugger::ParseGCMEnum(u32 value, u32 type)
|
|
|
|
const char* rsx_debugger::ParseGCMEnum(u32 value, u32 type)
|
|
|
@ -817,22 +818,22 @@ QString rsx_debugger::DisAsmCommand(u32 cmd, u32 count, u32 ioAddr)
|
|
|
|
|
|
|
|
|
|
|
|
if (cmd & RSX_METHOD_NON_METHOD_CMD_MASK)
|
|
|
|
if (cmd & RSX_METHOD_NON_METHOD_CMD_MASK)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD)
|
|
|
|
if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
u32 jumpAddr = cmd & RSX_METHOD_OLD_JUMP_OFFSET_MASK;
|
|
|
|
u32 jumpAddr = cmd & RSX_METHOD_OLD_JUMP_OFFSET_MASK;
|
|
|
|
DISASM("JUMP to 0x%07x", jumpAddr);
|
|
|
|
DISASM("JUMP to 0x%07x", jumpAddr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD)
|
|
|
|
else if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
u32 jumpAddr = cmd & RSX_METHOD_NEW_JUMP_OFFSET_MASK;
|
|
|
|
u32 jumpAddr = cmd & RSX_METHOD_NEW_JUMP_OFFSET_MASK;
|
|
|
|
DISASM("JUMP to 0x%07x", jumpAddr);
|
|
|
|
DISASM("JUMP to 0x%07x", jumpAddr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD)
|
|
|
|
else if ((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
u32 callAddr = cmd & RSX_METHOD_CALL_OFFSET_MASK;
|
|
|
|
u32 callAddr = cmd & RSX_METHOD_CALL_OFFSET_MASK;
|
|
|
|
DISASM("CALL to 0x%07x", callAddr);
|
|
|
|
DISASM("CALL to 0x%07x", callAddr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if((cmd & RSX_METHOD_RETURN_MASK) == RSX_METHOD_RETURN_CMD)
|
|
|
|
else if ((cmd & RSX_METHOD_RETURN_MASK) == RSX_METHOD_RETURN_CMD)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
DISASM("RETURN");
|
|
|
|
DISASM("RETURN");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -853,10 +854,12 @@ QString rsx_debugger::DisAsmCommand(u32 cmd, u32 count, u32 ioAddr)
|
|
|
|
switch((cmd & 0x3ffff) >> 2)
|
|
|
|
switch((cmd & 0x3ffff) >> 2)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case 0x3fead:
|
|
|
|
case 0x3fead:
|
|
|
|
|
|
|
|
{
|
|
|
|
DISASM("Flip and change current buffer: %d", args[0]);
|
|
|
|
DISASM("Flip and change current buffer: %d", args[0]);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
|
|
|
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
|
|
|
|
|
|
|
{
|
|
|
|
DISASM("Texture Offset[%d]: %07x", index, args[0]);
|
|
|
|
DISASM("Texture Offset[%d]: %07x", index, args[0]);
|
|
|
|
switch ((args[1] & 0x3) - 1)
|
|
|
|
switch ((args[1] & 0x3) - 1)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -870,27 +873,30 @@ QString rsx_debugger::DisAsmCommand(u32 cmd, u32 count, u32 ioAddr)
|
|
|
|
((args[1] >> 8) & 0xff),
|
|
|
|
((args[1] >> 8) & 0xff),
|
|
|
|
((args[1] >> 16) & 0xffff));
|
|
|
|
((args[1] >> 16) & 0xffff));
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE:
|
|
|
|
case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE:
|
|
|
|
|
|
|
|
{
|
|
|
|
DISASM("Depth bounds test: %s", args[0] ? "Enable" : "Disable");
|
|
|
|
DISASM("Depth bounds test: %s", args[0] ? "Enable" : "Disable");
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::string str = rsx::get_pretty_printing_function((cmd & 0x3ffff) >> 2)(args[0]);
|
|
|
|
std::string str = rsx::get_pretty_printing_function((cmd & 0x3ffff) >> 2)(args[0]);
|
|
|
|
DISASM("%s", str.c_str());
|
|
|
|
DISASM("%s", str.c_str());
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD && count > 1)
|
|
|
|
if ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD && count > 1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
DISASM("Non Increment cmd");
|
|
|
|
DISASM("Non Increment cmd");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DISASM("(");
|
|
|
|
DISASM("(");
|
|
|
|
|
|
|
|
|
|
|
|
for(uint i=0; i<count; ++i)
|
|
|
|
for (uint i=0; i<count; ++i)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(i != 0) disasm += ", ";
|
|
|
|
if (i != 0) disasm += ", ";
|
|
|
|
disasm += fmt::format("0x%x", args[i]);
|
|
|
|
disasm += fmt::format("0x%x", args[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -911,8 +917,8 @@ void rsx_debugger::PerformJump(u32 address)
|
|
|
|
if (!vm::check_addr(address))
|
|
|
|
if (!vm::check_addr(address))
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
u32 cmd = *vm::get_super_ptr<u32>(address);
|
|
|
|
const u32 cmd = *vm::get_super_ptr<u32>(address);
|
|
|
|
u32 count = cmd & RSX_METHOD_NON_METHOD_CMD_MASK ? 0 : (cmd >> 18) & 0x7ff;
|
|
|
|
const u32 count = cmd & RSX_METHOD_NON_METHOD_CMD_MASK ? 0 : (cmd >> 18) & 0x7ff;
|
|
|
|
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
if (count == 0)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|