diff --git a/src/include/86box/nv/classes/vid_nv3_classes.h b/src/include/86box/nv/classes/vid_nv3_classes.h index 85979dd45..15f4d37f1 100644 --- a/src/include/86box/nv/classes/vid_nv3_classes.h +++ b/src/include/86box/nv/classes/vid_nv3_classes.h @@ -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 diff --git a/src/qt/qt_gpudebug_visualnv.cpp b/src/qt/qt_gpudebug_visualnv.cpp index bbbd6c8ab..3b2ba8472 100644 --- a/src/qt/qt_gpudebug_visualnv.cpp +++ b/src/qt/qt_gpudebug_visualnv.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #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; + } + +} \ No newline at end of file diff --git a/src/qt/qt_gpudebug_visualnv.hpp b/src/qt/qt_gpudebug_visualnv.hpp index effbff67b..ee87dc0b3 100644 --- a/src/qt/qt_gpudebug_visualnv.hpp +++ b/src/qt/qt_gpudebug_visualnv.hpp @@ -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: diff --git a/src/qt/qt_gpudebug_visualnv.ui b/src/qt/qt_gpudebug_visualnv.ui index 3c7b7d659..ce45c4e44 100644 --- a/src/qt/qt_gpudebug_visualnv.ui +++ b/src/qt/qt_gpudebug_visualnv.ui @@ -29,7 +29,7 @@ - Nvidia GPU Realtime Debugger + RIVA 128 Realtime Debugger @@ -170,7 +170,7 @@ <html><head/><body><p>BPITCH[0]:</p></body></html> - + 460 @@ -180,7 +180,7 @@ - + 460 diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e5f52d0a7..11f6f2519 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -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(); } \ No newline at end of file diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 89db6f495..072a5a6a6 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -890,7 +890,7 @@ - GPU Realtime Debugger (NVIDIA ONLY) + RIVA 128 Realtime Debugger diff --git a/src/video/nv/nv3/render/nv3_render_blit.c b/src/video/nv/nv3/render/nv3_render_blit.c index c1b221648..0896bd199 100644 --- a/src/video/nv/nv3/render/nv3_render_blit.c +++ b/src/video/nv/nv3/render/nv3_render_blit.c @@ -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); + + } \ No newline at end of file diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index ac8789226..862d83371 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -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];