From 041dc284929b1bf5431011920493f1d723dec68e Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sat, 5 Apr 2025 14:44:01 +0100 Subject: [PATCH] Split src/destination buffers, use grobj --- CMakeLists.txt | 2 +- src/include/86box/nv/render/vid_nv3_render.h | 6 +- src/video/nv/nv3/classes/nv3_class_010_blit.c | 2 +- .../classes/nv3_class_01c_image_in_memory.c | 2 +- src/video/nv/nv3/render/nv3_render_blit.c | 77 ++++++------------- src/video/nv/nv3/render/nv3_render_core.c | 36 +++++++-- 6 files changed, 58 insertions(+), 67 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1adcf4740..52f24f4b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,7 +138,7 @@ option(DEV_BRANCH "Development branch" option(DISCORD "Discord Rich Presence support" ON) option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF) # Remove when merged, should just be -D -option(NV_LOG "NVidia RIVA 128 debug logging" OFF) +option(NV_LOG "NVidia RIVA 128 debug logging" ON) option(NV_LOG_ULTRA "Even more NVidia RIVA 128 debug logging" OFF) if (NV_LOG) diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h index 9b5acd06d..00591e342 100644 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ b/src/include/86box/nv/render/vid_nv3_render.h @@ -19,9 +19,9 @@ /* Core */ void nv3_render_write_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t grobj); -uint8_t nv3_render_read_pixel_8(nv3_position_16_t position, nv3_grobj_t grobj); -uint16_t nv3_render_read_pixel_16(nv3_position_16_t position, nv3_grobj_t grobj); -uint32_t nv3_render_read_pixel_32(nv3_position_16_t position, nv3_grobj_t grobj); +uint8_t nv3_render_read_pixel_8(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination); +uint16_t nv3_render_read_pixel_16(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination); +uint32_t nv3_render_read_pixel_32(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination); uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded); nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj); // Convert a colour to full RGB10 format from the current working format. diff --git a/src/video/nv/nv3/classes/nv3_class_010_blit.c b/src/video/nv/nv3/classes/nv3_class_010_blit.c index 7bae42184..57184054d 100644 --- a/src/video/nv/nv3/classes/nv3_class_010_blit.c +++ b/src/video/nv/nv3/classes/nv3_class_010_blit.c @@ -54,7 +54,7 @@ void nv3_class_010_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ && nv3->pgraph.blit.point_in.y == nv3->pgraph.blit.point_out.y) return; - //nv3_render_blit_screen2screen(grobj); + nv3_render_blit_screen2screen(grobj); break; default: diff --git a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c b/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c index dd5768103..af488dc09 100644 --- a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c +++ b/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c @@ -31,7 +31,7 @@ void nv3_class_01c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) { /* We need this for a lot of methods, so may as well store it here. */ - uint32_t src_buffer_id = (nv3->pgraph.context_switch >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03; + uint32_t src_buffer_id = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03; switch (method_id) { diff --git a/src/video/nv/nv3/render/nv3_render_blit.c b/src/video/nv/nv3/render/nv3_render_blit.c index 032b23b47..3059aeccd 100644 --- a/src/video/nv/nv3/render/nv3_render_blit.c +++ b/src/video/nv/nv3/render/nv3_render_blit.c @@ -113,66 +113,37 @@ void nv3_render_blit_image(uint32_t color, nv3_grobj_t grobj) void nv3_render_blit_screen2screen(nv3_grobj_t grobj) { - //nv3_position_16_t old_position = nv3->pgraph.blit.point_in + nv3->pgraph.blit.size.w; - nv3_position_16_t old_position = {0}; - old_position.x = nv3->pgraph.blit.point_in.x + nv3->pgraph.blit.size.w; - old_position.y = nv3->pgraph.blit.point_in.y + nv3->pgraph.blit.size.h; + nv3_position_16_t old_position = nv3->pgraph.blit.point_in; nv3_position_16_t new_position = nv3->pgraph.blit.point_out; uint16_t end_x = (nv3->pgraph.blit.point_out.x + nv3->pgraph.blit.size.w); uint16_t end_y = (nv3->pgraph.blit.point_out.y + nv3->pgraph.blit.size.h); - /* Read the old pixel */ - switch (nv3->nvbase.svga.bpp) + uint32_t pixel_to_copy = 0x00; + + /* Read the old pixel and rewrite it to the new position */ + for (int32_t y = nv3->pgraph.blit.point_out.y; y <= end_y; y++) { - case 8: //8bpp - for (int32_t y = nv3->pgraph.blit.point_out.y; y < end_y; y++) + old_position.y = new_position.y = y; + + for (int32_t x = nv3->pgraph.blit.point_out.x; x <= end_x; x++) + { + old_position.x = new_position.x = x; + + switch (nv3->nvbase.svga.bpp) { - old_position.y++; - new_position.y++; - - for (int32_t x = nv3->pgraph.blit.point_out.x; x < end_x; x++) - { - old_position.x++; - new_position.x++; - - uint32_t pixel_to_copy = nv3_render_read_pixel_8(old_position, grobj) & 0xFF; - nv3_render_write_pixel(new_position, pixel_to_copy, grobj); - } + case 8: + pixel_to_copy = nv3_render_read_pixel_8(old_position, grobj, false) & 0xFF; + break; + case 15 ... 16: //15bpp and 16bpp modes are considered as identical + pixel_to_copy = nv3_render_read_pixel_16(old_position, grobj, false) & 0xFFFF; + break; + case 32: + pixel_to_copy = nv3_render_read_pixel_32(old_position, grobj, false); + break; } - break; - case 15: - case 16: //16bpp - for (int32_t y = nv3->pgraph.blit.point_out.y; y < end_y; y++) - { - old_position.y++; - new_position.y++; - for (int32_t x = nv3->pgraph.blit.point_out.x; x >= end_x; x++) - { - old_position.x++; - new_position.x++; - - uint32_t pixel_to_copy = nv3_render_read_pixel_16(old_position, grobj) & 0xFFFF; - nv3_render_write_pixel(new_position, pixel_to_copy, grobj); - } - } - break; - case 32: //32bpp - for (int32_t y = nv3->pgraph.blit.point_out.y; y < end_y; y++) - { - old_position.y++; - new_position.y++; - - for (int32_t x = nv3->pgraph.blit.point_out.x; x >= end_x; x++) - { - old_position.x++; - new_position.x++; - - uint32_t pixel_to_copy = nv3_render_read_pixel_32(old_position, grobj); - nv3_render_write_pixel(new_position, pixel_to_copy, grobj); - } - } - break; - } + nv3_render_write_pixel(new_position, pixel_to_copy, grobj); + } + } } \ 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 66ee170bc..9781259ad 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -213,11 +213,31 @@ uint32_t nv3_render_set_pattern_color(nv3_color_expanded_t pattern_colour, bool } /* /* Combine the current buffer with the pitch to get the address in the framebuffer to draw from for a given position. */ -uint32_t nv3_render_get_vram_address(nv3_position_16_t position, nv3_grobj_t grobj) +uint32_t nv3_render_get_vram_address(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination) { uint32_t vram_x = position.x; uint32_t vram_y = position.y; uint32_t current_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03; + + /* test DST_BUFFER code + I assume for 2d at least only one is allowed at a time + */ + + if (use_destination) + { + uint32_t destination_buffer = 5; // 5 = just use the source buffer + + if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER0_ENABLED) & 0x01) destination_buffer = 0; + if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER1_ENABLED) & 0x01) destination_buffer = 1; + if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER2_ENABLED) & 0x01) destination_buffer = 2; + if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER3_ENABLED) & 0x01) destination_buffer = 3; + + if (destination_buffer != current_buffer + && destination_buffer != 5) + current_buffer = destination_buffer; + + } + uint32_t framebuffer_bpp = nv3->nvbase.svga.bpp; // we have to multiply the x position by the number of bytes per pixel @@ -242,19 +262,19 @@ uint32_t nv3_render_get_vram_address(nv3_position_16_t position, nv3_grobj_t gro } /* Read an 8bpp pixel from the framebuffer. */ -uint8_t nv3_render_read_pixel_8(nv3_position_16_t position, nv3_grobj_t grobj) +uint8_t nv3_render_read_pixel_8(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination) { // hope you call it with the right bit - uint32_t vram_address = nv3_render_get_vram_address(position, grobj); + uint32_t vram_address = nv3_render_get_vram_address(position, grobj, use_destination); return nv3->nvbase.svga.vram[vram_address]; } /* Read an 16bpp pixel from the framebuffer. */ -uint16_t nv3_render_read_pixel_16(nv3_position_16_t position, nv3_grobj_t grobj) +uint16_t nv3_render_read_pixel_16(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination) { // hope you call it with the right bit - uint32_t vram_address = nv3_render_get_vram_address(position, grobj); + uint32_t vram_address = nv3_render_get_vram_address(position, grobj, use_destination); uint16_t* vram_16 = (uint16_t*)(nv3->nvbase.svga.vram); vram_address >>= 1; //convert to 16bit pointer @@ -263,10 +283,10 @@ uint16_t nv3_render_read_pixel_16(nv3_position_16_t position, nv3_grobj_t grobj) } /* Read an 16bpp pixel from the framebuffer. */ -uint32_t nv3_render_read_pixel_32(nv3_position_16_t position, nv3_grobj_t grobj) +uint32_t nv3_render_read_pixel_32(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination) { // hope you call it with the right bit - uint32_t vram_address = nv3_render_get_vram_address(position, grobj); + uint32_t vram_address = nv3_render_get_vram_address(position, grobj, use_destination); uint32_t* vram_32 = (uint32_t*)(nv3->nvbase.svga.vram); vram_address >>= 1; //convert to 16bit pointer @@ -315,7 +335,7 @@ void nv3_render_write_pixel(nv3_position_16_t position, uint32_t color, nv3_grob if (!nv3_render_chroma_test(color, grobj)) return; - uint32_t pixel_addr_vram = nv3_render_get_vram_address(position, grobj); + uint32_t pixel_addr_vram = nv3_render_get_vram_address(position, grobj, true); uint32_t rop_src = 0, rop_dst = 0, rop_pattern = 0; uint8_t bit = 0x00;