mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 02:18:20 -07:00
Load VRAM savestates....
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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><html><head/><body><p>BPITCH[0]:</p></body></html></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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
@@ -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];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user