Split src/destination buffers, use grobj

This commit is contained in:
starfrost013
2025-04-05 14:44:01 +01:00
parent 7c4e2c82d4
commit 041dc28492
6 changed files with 58 additions and 67 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -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:

View File

@@ -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)
{

View File

@@ -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);
}
}
}

View File

@@ -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;