From 6ba3d8981067d500ae4c5584995c71a1055ac803 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 18 May 2025 17:34:39 +0100 Subject: [PATCH] big rendering refactor --- src/include/86box/nv/render/vid_nv3_render.h | 2 +- src/video/nv/nv3/nv3_core.c | 7 - src/video/nv/nv3/render/nv3_render_blit.c | 47 ------ src/video/nv/nv3/render/nv3_render_core.c | 162 +++++++------------ src/video/nv/nv3/subsystems/nv3_pramdac.c | 1 + 5 files changed, 64 insertions(+), 155 deletions(-) diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h index c3e6182e5..9c7af77ab 100644 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ b/src/include/86box/nv/render/vid_nv3_render.h @@ -18,7 +18,7 @@ #pragma once /* Core */ -void nv3_render_current_bpp(svga_t *svga, nv3_coord_16_t position, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer); +void nv3_render_current_bpp(); void nv3_render_current_bpp_dfb_8(uint32_t address); void nv3_render_current_bpp_dfb_16(uint32_t address); void nv3_render_current_bpp_dfb_32(uint32_t address); diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c index 824d96405..21810386e 100644 --- a/src/video/nv/nv3/nv3_core.c +++ b/src/video/nv/nv3/nv3_core.c @@ -957,13 +957,6 @@ void nv3_draw_cursor(svga_t* svga, int32_t drawline) // reset at the end of each line so we "jump" to the start x final_position = nv3_render_get_vram_address_for_buffer(start_position, 0); } - - nv3_coord_16_t size = {0}; - size.x = size.y = 32; - nv3_grobj_t dummy = {0}; // need to clean it up - - /* do we need to update here? */ - nv3_render_current_bpp(&nv3->nvbase.svga, start_position, size, dummy, false); } // MMIO 0x110000->0x111FFF is mapped to a mirror of the VBIOS. diff --git a/src/video/nv/nv3/render/nv3_render_blit.c b/src/video/nv/nv3/render/nv3_render_blit.c index da139b496..0b0cb1c31 100644 --- a/src/video/nv/nv3/render/nv3_render_blit.c +++ b/src/video/nv/nv3/render/nv3_render_blit.c @@ -176,51 +176,4 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj) memcpy(&nv3->nvbase.svga.vram[vram_position], &nv3_s2sb_line_buffer[buf_position], size_x); new_position.y++; } - - /* - We need to blit manually here because we don't go through nv3_render_write_pixel - We also need to update all of the areas of the screen that moved. - */ - - nv3_coord_16_t blit_position = {0}, blit_size = {0}; - - /* Change the smallest area of the screen that moved */ - - if (cross_buffer_blit) - { - blit_position = nv3->pgraph.blit.point_out; - blit_size = nv3->pgraph.blit.size; - } - else - { - if (nv3->pgraph.blit.point_out.x > nv3->pgraph.blit.point_in.x) - blit_size.x = (nv3->pgraph.blit.point_out.x - nv3->pgraph.blit.point_in.x) + nv3->pgraph.blit.size.x; - else if (nv3->pgraph.blit.point_out.x < nv3->pgraph.blit.point_in.x) - blit_size.x = (nv3->pgraph.blit.point_in.x - nv3->pgraph.blit.point_out.x) + nv3->pgraph.blit.size.x; - else - blit_size.x = nv3->pgraph.blit.size.x; - - if (nv3->pgraph.blit.point_out.y > nv3->pgraph.blit.point_in.y) - blit_size.y = (nv3->pgraph.blit.point_out.y - nv3->pgraph.blit.point_in.y) + nv3->pgraph.blit.size.y; - else if (nv3->pgraph.blit.point_out.y < nv3->pgraph.blit.point_in.y) - blit_size.y = (nv3->pgraph.blit.point_in.y - nv3->pgraph.blit.point_out.y) + nv3->pgraph.blit.size.y; - else - blit_size.y = nv3->pgraph.blit.size.y; - - if (nv3->pgraph.blit.point_out.x > nv3->pgraph.blit.point_in.x) - blit_position.x = nv3->pgraph.blit.point_in.x; - else if (nv3->pgraph.blit.point_out.x <= nv3->pgraph.blit.point_in.x) // equals case, just use out - blit_position.x = nv3->pgraph.blit.point_out.x; - - if (nv3->pgraph.blit.point_out.y > nv3->pgraph.blit.point_in.y) - blit_position.y = nv3->pgraph.blit.point_in.y; - else if (nv3->pgraph.blit.point_out.y <= nv3->pgraph.blit.point_in.y) // equals case, just use out - blit_position.y = nv3->pgraph.blit.point_out.y; - - } - - /* If the BUFFER_ADDRESS of the last buffer is not the DBA, we don't *actually* want to draw this, so let's not - Apply stupid hack */ - - nv3_render_current_bpp(&nv3->nvbase.svga, blit_position, blit_size, grobj, true); } \ 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 3491c8df3..72617c6aa 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -31,10 +31,10 @@ #include <86box/utils/video_stdlib.h> /* Functions only used in this translation unit */ -void nv3_render_8bpp(nv3_coord_16_t position, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer); -void nv3_render_15bpp(nv3_coord_16_t position, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer); -void nv3_render_16bpp(nv3_coord_16_t position, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer); -void nv3_render_32bpp(nv3_coord_16_t position, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer); +void nv3_render_8bpp(uint32_t vram_start, nv3_coord_16_t screen_size); +void nv3_render_15bpp(uint32_t vram_start, nv3_coord_16_t screen_size); +void nv3_render_16bpp(uint32_t vram_start, nv3_coord_16_t screen_size); +void nv3_render_32bpp(uint32_t vram_start, nv3_coord_16_t screen_size); /* Expand a colour. NOTE: THE GPU INTERNALLY OPERATES ON RGB10!!!!!!!!!!! @@ -494,11 +494,6 @@ void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t break; } } - - /* Go write the pixel */ - nv3_coord_16_t size = {0}; - size.x = size.y = 1; - nv3_render_current_bpp(&nv3->nvbase.svga, position, size, grobj, false); } /* Ensure the correct monitor size */ @@ -590,19 +585,16 @@ void nv3_render_current_bpp_dfb_32(uint32_t address) uint32_t data = *(uint32_t*)&(nv3->nvbase.svga.vram[address]); + uint32_t* p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; + if (nv3->nvbase.svga.bpp == 32) { - uint32_t* p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; *p = data; } /* Packed format */ else if (nv3->nvbase.svga.bpp == 15 || nv3->nvbase.svga.bpp == 16) { - //pos.x >>= 1; - - uint32_t* p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, nv3->nvbase.svga.bpp); *p++; *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, (data >> 16) & 0xFFFF, nv3->nvbase.svga.bpp); @@ -611,9 +603,20 @@ void nv3_render_current_bpp_dfb_32(uint32_t address) /* Blit to the monitor from GPU, current bpp */ -void nv3_render_current_bpp(svga_t *svga, nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer) +void nv3_render_current_bpp() { - /* Ensure that we are in the correct mode. Modified SVGA core code */ + /* Figure out the Display Buffer Address from the CRTC */ + + uint32_t dba = ((nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_RPC0] & 0x1F) << 16) + + (nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_STARTADDR_HIGH] << 8) + + nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_STARTADDR_LOW]; + + nv3_coord_16_t screen_size = {0}; + screen_size.x = nv3->nvbase.svga.hdisp; + screen_size.y = nv3->nvbase.svga.dispend; + + /* Ensure that we are + in the correct mode. Modified SVGA core code */ nv3_render_ensure_screen_size(); /* Don't try and draw stuff that is past the buffer, but, leave it in Video RAM, so it can be used for s2sb's etc */ @@ -625,16 +628,16 @@ void nv3_render_current_bpp(svga_t *svga, nv3_coord_16_t pos, nv3_coord_16_t siz fatal("NV3 - 4bpp not implemented (not even sure if it's SVGA only)"); break; case 8: - nv3_render_8bpp(pos, size, grobj, use_destination_buffer); + nv3_render_8bpp(dba, screen_size); break; case 15: - nv3_render_15bpp(pos, size, grobj, use_destination_buffer); + nv3_render_15bpp(dba, screen_size); break; case 16: - nv3_render_16bpp(pos, size, grobj, use_destination_buffer); + nv3_render_16bpp(dba, screen_size); break; - case 32: - nv3_render_32bpp(pos, size, grobj, use_destination_buffer); + case 32: + nv3_render_32bpp(dba, screen_size); break; } @@ -644,40 +647,29 @@ void nv3_render_current_bpp(svga_t *svga, nv3_coord_16_t pos, nv3_coord_16_t siz Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, indexed 8 bits per pixel format */ -void nv3_render_8bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer) +void nv3_render_8bpp(uint32_t vram_start, nv3_coord_16_t screen_size) { if (!nv3) return; - uint32_t vram_base; //acquired for the start of each line + uint32_t vram_current_position = vram_start; uint32_t* p; - uint32_t data; - uint32_t start_x = pos.x; + uint32_t data = 0; - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - for (uint32_t y = 0; y < size.y; y++) + for (uint32_t y = 0; y < screen_size.y; y++) { - /* re-set the vram address because we are basically "jumping" halfway across a line here */ - if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now - else - vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; - - for (uint32_t x = 0; x < size.x; x++) + for (uint32_t x = 0; x < screen_size.x; x++) { - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_base]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; + data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; /* should just "tip over" to the next line */ *p = nv3_render_get_palette_index(data & 0xFF); - vram_base++; - pos.x++; + vram_current_position++; } - - pos.x = start_x; - pos.y++; } } @@ -685,40 +677,30 @@ void nv3_render_8bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj, Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, 15 bits per pixel format */ -void nv3_render_15bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer) +void nv3_render_15bpp(uint32_t vram_start, nv3_coord_16_t screen_size) { if (!nv3) return; - uint32_t vram_base; //acquired for the start of each line + uint32_t vram_current_position = vram_start; uint32_t* p; - uint32_t data; - uint32_t start_x = pos.x; + uint32_t data = 0; - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - for (uint32_t y = 0; y < size.y; y++) + for (uint32_t y = 0; y < screen_size.y; y++) { - /* re-set the vram address because we are basically "jumping" halfway across a line here */ - if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now - else - vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; - - for (uint32_t x = 0; x < size.x; x++) + for (uint32_t x = 0; x < screen_size.x; x++) { - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_base]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; + data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; /* should just "tip over" to the next line */ *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, 15); - vram_base += 2; - pos.x++; + vram_current_position += 2; } - - pos.x = start_x; - pos.y++; + } } @@ -726,40 +708,31 @@ void nv3_render_15bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, 16 bits per pixel format */ -void nv3_render_16bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer) +void nv3_render_16bpp(uint32_t vram_start, nv3_coord_16_t screen_size) { if (!nv3) return; - uint32_t vram_base; //acquired for the start of each line + uint32_t vram_current_position = vram_start; uint32_t* p; - uint32_t data; - uint32_t start_x = pos.x; + uint32_t data = 0; - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - for (uint32_t y = 0; y < size.y; y++) + for (uint32_t y = 0; y < screen_size.y; y++) { - /* re-set the vram address because we are basically "jumping" halfway across a line here */ - if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now - else - vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; - - for (uint32_t x = 0; x < size.x; x++) + for (uint32_t x = 0; x < screen_size.x; x++) { - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_base]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; + data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; /* should just "tip over" to the next line */ *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, 15); - vram_base += 2; - pos.x++; + vram_current_position += 2; + } - pos.x = start_x; - pos.y++; } } @@ -767,39 +740,28 @@ void nv3_render_16bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, 32 bits per pixel format */ -void nv3_render_32bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj, bool use_destination_buffer) +void nv3_render_32bpp(uint32_t vram_start, nv3_coord_16_t screen_size) { if (!nv3) return; - uint32_t vram_base; + uint32_t vram_current_position = vram_start; uint32_t* p; - uint32_t data; - uint32_t start_x = pos.x; + uint32_t data = 0; - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - for (uint32_t y = 0; y < size.y; y++) + for (uint32_t y = 0; y < screen_size.y; y++) { - /* re-set the vram address because we are basically "jumping" halfway across a line here */ - if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now - else - vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; - - for (uint32_t x = 0; x < size.x; x++) + for (uint32_t x = 0; x < screen_size.x; x++) { - p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_base]; + p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; + data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; /* should just "tip over" to the next line */ *p = data; - vram_base += 4; - pos.x++; + vram_current_position += 4; } - - pos.y++; - pos.x = start_x; } } diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c index b7c984f26..f179c8136 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ b/src/video/nv/nv3/subsystems/nv3_pramdac.c @@ -64,6 +64,7 @@ void nv3_pramdac_pixel_clock_poll(double real_time) if (nv3->nvbase.refresh_clock > nv3->nvbase.refresh_time) { /* Update the screen because something changed */ + nv3_render_current_bpp(); video_blit_memtoscreen(0, 0, xsize, ysize); nv3->nvbase.refresh_clock = 0; }