big rendering refactor

This commit is contained in:
starfrost013
2025-05-18 17:34:39 +01:00
parent aaaa4db881
commit 6ba3d89810
5 changed files with 64 additions and 155 deletions

View File

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

View File

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

View File

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

View File

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

View File

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