Load VRAM savestates....

This commit is contained in:
starfrost013
2025-07-27 15:44:44 +01:00
parent 5fc903fb48
commit 97c9888b9c
8 changed files with 197 additions and 23 deletions

View File

@@ -239,9 +239,14 @@ typedef struct nv3_color_expanded_s
uint8_t a;
/* WARNING: The internal format is 10-bit RGB! */
uint16_t r : 10;
uint16_t g : 10;
uint16_t b : 10;
uint16_t r;
uint16_t g;
uint16_t b;
// YUV stuff
float y;
float u;
float v;
// Indexed colour
union

View File

@@ -33,6 +33,7 @@
#include <QLabel>
#include <QDir>
#include <QSettings>
#include <QFileDialog>
#include <qt_gpudebug_visualnv.hpp>
#include "ui_qt_gpudebug_visualnv.h"
@@ -55,8 +56,11 @@ VisualNVDialog::VisualNVDialog(QWidget *parent)
, ui(new Ui::VisualNVDialog)
{
ui->setupUi(this);
connect(ui->btnLoadSavestate, &QPushButton::clicked, this, &VisualNVDialog::on_btnLoadSavestate_clicked);
connect(ui->fbStartAddress, &QPlainTextEdit::textChanged, this, &VisualNVDialog::on_fbStartAddress_changed);
connect(ui->bPitch0Value, &QPlainTextEdit::textChanged, this, &VisualNVDialog::on_bPitch0Value_changed);
connect(ui->bPitch1Value, &QPlainTextEdit::textChanged, this, &VisualNVDialog::on_bPitch1Value_changed);
}
// VisualNV dialog destructor
@@ -67,7 +71,62 @@ VisualNVDialog::~VisualNVDialog()
void VisualNVDialog::on_btnLoadSavestate_clicked()
{
warning("THIS IS VisualNVDialog::on_btnLoadSavestate_clicked!!!! (throws into hole)");
if (!nv3)
return;
QString bar0_file_name = QFileDialog::getOpenFileName
(
this,
tr("Please provide NVPlay 0.3.0.7+ NV3BAR0.BIN file"),
".",
tr("NVPlay MMIO Dump Files (*.bin)")
);
QString bar1_file_name = QFileDialog::getOpenFileName
(
this,
tr("Please provide NVPlay 0.3.0.7+ NV3BAR1.BIN file"),
".",
tr("NVPlay VRAM/RAMIN Dump Files (*.bin)")
);
//
// Open both dump files
//
QFile bar0(bar0_file_name);
QFile bar1(bar1_file_name);
if (!bar0.open(QIODevice::ReadOnly))
{
warning("Failed to open NV3BAR0.bin!");
return;
}
if (!bar1.open(QIODevice::ReadOnly))
{
warning("Failed to open NV3BAR1.bin!");
return;
}
if (bar0.size() != NV3_MMIO_SIZE
|| bar1.size() != NV3_MMIO_SIZE)
{
warning("NV3BAR0.bin and NV3BAR1.bin must be 16MB!");
bar0.close();
bar1.close();
return;
}
// Load VRAM contents only for now. Todo: MMIO+RAMIN
QString oldTitle = this->windowTitle();
this->setWindowTitle(tr("RIVA 128 Realtime Debugger: Savestate Loading..."));
bar1.read((char*)nv3->nvbase.svga.vram, nv3->nvbase.vram_amount);
this->setWindowTitle(oldTitle);
}
void VisualNVDialog::on_fbStartAddress_changed()
@@ -84,3 +143,35 @@ void VisualNVDialog::on_fbStartAddress_changed()
nv3->nvbase.debug_dba_enabled = false;
}
}
void VisualNVDialog::on_bPitch0Value_changed()
{
if (nv3)
{
bool ok = true;
uint32_t old_bpitch = nv3->pgraph.bpitch[0];
nv3->pgraph.bpitch[0] = ui->bPitch0Value->toPlainText().toInt(&ok);
if (!ok)
nv3->pgraph.bpitch[0] = old_bpitch;
}
}
void VisualNVDialog::on_bPitch1Value_changed()
{
if (nv3)
{
bool ok = true;
uint32_t old_bpitch = nv3->pgraph.bpitch[1];
nv3->pgraph.bpitch[1] = ui->bPitch0Value->toPlainText().toInt(&ok);
if (!ok)
nv3->pgraph.bpitch[1] = old_bpitch;
}
}

View File

@@ -35,6 +35,8 @@ class VisualNVDialog : public QDialog
void on_btnLoadSavestate_clicked();
void on_fbStartAddress_changed();
void on_bPitch0Value_changed();
void on_bPitch1Value_changed();
protected:
private:

View File

@@ -29,7 +29,7 @@
</size>
</property>
<property name="windowTitle">
<string>Nvidia GPU Realtime Debugger</string>
<string>RIVA 128 Realtime Debugger</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
@@ -170,7 +170,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;BPITCH[0]:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QPlainTextEdit" name="plainTextEdit_3">
<widget class="QPlainTextEdit" name="bPitch0Value">
<property name="geometry">
<rect>
<x>460</x>
@@ -180,7 +180,7 @@
</rect>
</property>
</widget>
<widget class="QPlainTextEdit" name="plainTextEdit_4">
<widget class="QPlainTextEdit" name="bPitch1Value">
<property name="geometry">
<rect>
<x>460</x>

View File

@@ -2328,19 +2328,26 @@ void MainWindow::on_actionACPI_Shutdown_triggered()
void MainWindow::on_actionDebug_GPUDebug_VRAM_triggered()
{
debugVramDialog = new GPUDebugVRAMDialog;
debugVramDialog = new GPUDebugVRAMDialog(this);
debugVramDialog->setWindowFlag(Qt::CustomizeWindowHint, true);
debugVramDialog->setWindowFlag(Qt::WindowTitleHint, true);
debugVramDialog->setWindowFlag(Qt::WindowSystemMenuHint, false);
debugVramDialog->show();
// If I have this as a NON-MODAL dialog, input is just eaten without doing anything
// WTF?!?!?!?!?
//debugVramDialog->show();
debugVramDialog->exec();
}
void MainWindow::on_actionDebug_GPUDebug_VisualNv_triggered()
{
visualNvDialog = new VisualNVDialog;
visualNvDialog = new VisualNVDialog(this);
visualNvDialog->setWindowFlag(Qt::CustomizeWindowHint, true);
visualNvDialog->setWindowFlag(Qt::WindowTitleHint, true);
visualNvDialog->setWindowFlag(Qt::WindowSystemMenuHint, false);
visualNvDialog->show();
// If I have this as a NON-MODAL dialog, input is just eaten without doing anything
// WTF?!?!?!?!?
//visualNvDialog->show();
visualNvDialog->exec();
}

View File

@@ -890,7 +890,7 @@
</action>
<action name="actionDebug_GPUDebug_VisualNv">
<property name="text">
<string>GPU Realtime Debugger (NVIDIA ONLY)</string>
<string>RIVA 128 Realtime Debugger</string>
</property>
</action>
</widget>

View File

@@ -119,20 +119,14 @@ This is LUDICROUSLY INEFFICIENT (2*O(n^2)) and COMPLETELY TERRIBLE code, but it'
*/
uint32_t nv3_s2sb_line_buffer[NV3_MAX_HORIZONTAL_SIZE*NV3_MAX_VERTICAL_SIZE] = {0};
void nv3_render_blit_screen2screen(nv3_grobj_t grobj)
void nv3_render_blit_screen2screen_for_buffer(nv3_grobj_t grobj, uint32_t dst_buffer)
{
if (nv3->pgraph.blit.size.x < NV3_MAX_HORIZONTAL_SIZE
if (nv3->pgraph.blit.size.x < NV3_MAX_HORIZONTAL_SIZE
&& nv3->pgraph.blit.size.y < NV3_MAX_VERTICAL_SIZE)
memset(&nv3_s2sb_line_buffer, 0x00, (sizeof(uint32_t) * nv3->pgraph.blit.size.y) * (sizeof(uint32_t) * nv3->pgraph.blit.size.x));
/* First calculate our source and destination buffer */
uint32_t src_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03;
uint32_t dst_buffer = 0; // 5 = just use the source buffer
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER0_ENABLED) & 0x01) dst_buffer = 0;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER1_ENABLED) & 0x01) dst_buffer = 1;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER2_ENABLED) & 0x01) dst_buffer = 2;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER3_ENABLED) & 0x01) dst_buffer = 3;
nv3_coord_16_t in_position = nv3->pgraph.blit.point_in;
nv3_coord_16_t out_position = nv3->pgraph.blit.point_out;
@@ -175,4 +169,61 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj)
memcpy(&nv3->nvbase.svga.vram[vram_position], &nv3_s2sb_line_buffer[buf_position], size_x);
out_position.y++;
}
/*
//32bit only as a test
uint32_t* vram_32 = (uint32_t*)nv3->nvbase.svga.vram;
if (nv3->pgraph.boffset[src_buffer] != nv3->pgraph.boffset[dst_buffer])
{
// stretch out the position to the new one
nv3_coord_16_t current_pos_in;
nv3_coord_16_t current_pos_out;
current_pos_in.x = nv3->pgraph.blit.point_in.x;
current_pos_in.y = nv3->pgraph.blit.point_in.y;
current_pos_out.x = nv3->pgraph.blit.point_out.x;
current_pos_out.y = nv3->pgraph.blit.point_out.y;
for (uint32_t y = 0; y < nv3->pgraph.blit.size.y; y++)
{
current_pos_in.y = nv3->pgraph.blit.point_in.y + y;
current_pos_out.y = nv3->pgraph.blit.point_out.y + y;
for (uint32_t x = 0; x < nv3->pgraph.blit.size.x; x++)
{
current_pos_in.x = nv3->pgraph.blit.point_in.x + x;
current_pos_out.x = nv3->pgraph.blit.point_out.x + x;
uint32_t index = nv3_render_get_vram_address_for_buffer(current_pos_in, dst_buffer) >> 2;
uint32_t index_dst = nv3_render_get_vram_address_for_buffer(current_pos_out, src_buffer) >> 2;
vram_32[index_dst] = vram_32[index];
//nv3_render_write_pixel(current_pos, vram_32[index], grobj);
}
current_pos_in.x = nv3->pgraph.blit.point_in.x;
current_pos_out.x = nv3->pgraph.blit.point_out.x;
}
}
*/
}
void nv3_render_blit_screen2screen(nv3_grobj_t grobj)
{
uint32_t dst_buffer = (nv3_pgraph_destination_buffer)grobj.grobj_0; // 5 = just use the source buffer
if (dst_buffer & pgraph_dest_buffer0)
nv3_render_blit_screen2screen_for_buffer(grobj, 0);
if (dst_buffer & pgraph_dest_buffer1)
nv3_render_blit_screen2screen_for_buffer(grobj, 1);
if (dst_buffer & pgraph_dest_buffer2)
nv3_render_blit_screen2screen_for_buffer(grobj, 2);
if (dst_buffer & pgraph_dest_buffer3)
nv3_render_blit_screen2screen_for_buffer(grobj, 3);
}

View File

@@ -100,6 +100,9 @@ nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj)
// yuv
color_final.r = color_final.g = color_final.b = (color & 0xFFFF) * 4; // convert to rgb10
break;
case nv3_pgraph_pixel_format_y420:
warning("nv3_render_expand_color: YUV420 not implemented\n");
break;
default:
warning("nv3_render_expand_color unknown format %d", format);
break;
@@ -148,8 +151,11 @@ uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t co
packed_color = nv3_render_get_palette_index((color.r >> 2) & 0xFF);
break;
case nv3_pgraph_pixel_format_y16:
warning("nv3_render_downconvert: Y16 not implemented");
warning("nv3_render_downconvert_color: Y16 not implemented");
break;
case nv3_pgraph_pixel_format_y420:
warning("nv3_render_downconvert_color: YUV420 not implemented\n");
break;
default:
warning("nv3_render_downconvert_color unknown format %d", format);
break;
@@ -668,6 +674,9 @@ void nv3_render_8bpp(uint32_t vram_start, nv3_coord_16_t screen_size)
{
for (uint32_t x = 0; x < screen_size.x; x++)
{
if (vram_current_position >= nv3->nvbase.vram_amount)
return;
p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x];
data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position];
@@ -698,6 +707,9 @@ void nv3_render_15bpp(uint32_t vram_start, nv3_coord_16_t screen_size)
{
for (uint32_t x = 0; x < screen_size.x; x++)
{
if (vram_current_position >= nv3->nvbase.vram_amount)
return;
p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x];
data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position];
@@ -728,7 +740,10 @@ void nv3_render_16bpp(uint32_t vram_start, nv3_coord_16_t screen_size)
for (uint32_t y = 0; y < screen_size.y; y++)
{
for (uint32_t x = 0; x < screen_size.x; x++)
{
{
if (vram_current_position >= nv3->nvbase.vram_amount)
return;
p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x];
data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position];
@@ -760,7 +775,10 @@ void nv3_render_32bpp(uint32_t vram_start, nv3_coord_16_t screen_size)
for (uint32_t y = 0; y < screen_size.y; y++)
{
for (uint32_t x = 0; x < screen_size.x; x++)
{
{
if (vram_current_position >= nv3->nvbase.vram_amount)
return;
p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x];
data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position];