mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 01:48:21 -07:00
fix crossbuffer blit, use custom render functions
This commit is contained in:
@@ -270,8 +270,8 @@ typedef struct nv3_color_argb_s
|
||||
/* Generic 16-bit position*/
|
||||
typedef struct nv3_position_16_s
|
||||
{
|
||||
uint16_t y;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} nv3_position_16_t;
|
||||
|
||||
/* A big position format with 30:16 = y, 15:11 = nothing, 10:0 = x */
|
||||
@@ -287,8 +287,8 @@ typedef struct nv3_position_16_bigy_s
|
||||
/* Generic 16-bit size */
|
||||
typedef struct nv3_size_16_s
|
||||
{
|
||||
uint16_t h;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
} nv3_size_16_t;
|
||||
|
||||
/* Generic 32-bit colour + 16-bit position */
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
#pragma once
|
||||
|
||||
/* Core */
|
||||
void nv3_render_15bpp(svga_t *svga);
|
||||
void nv3_render_16bpp(svga_t *svga);
|
||||
void nv3_render_32bpp(svga_t *svga);
|
||||
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, bool use_destination);
|
||||
uint16_t nv3_render_read_pixel_16(nv3_position_16_t position, nv3_grobj_t grobj, bool use_destination);
|
||||
|
||||
@@ -121,6 +121,7 @@ typedef struct nv_base_s
|
||||
bool memory_clock_enabled; // Memory Clock Enabled - stupid crap used to prevent us eanbling the timer multiple times
|
||||
void* i2c; // I2C for monitor EDID
|
||||
void* ddc; // Display Data Channel for EDID
|
||||
uint32_t last_buffer_address; // Last buffer address.
|
||||
} nv_base_t;
|
||||
|
||||
#define NV_REG_LIST_END 0xD15EA5E
|
||||
|
||||
@@ -1194,8 +1194,8 @@ typedef struct nv3_pgraph_s
|
||||
nv3_pgraph_dma_settings_t dma_settings;
|
||||
uint8_t rop; // Current GDI Ternary Render Operation
|
||||
// SURFACE STUFF - PGRAPH CAN OPERATE ON 4 SURFACES/BUFFERS AT A TIME
|
||||
uint32_t boffset[NV3_PGRAPH_MAX_BUFFERS]; // 22-bit linear VRAM offset for the start of a surface.
|
||||
uint16_t bpitch[NV3_PGRAPH_MAX_BUFFERS]; // 12-bit linear VRAM offset for the pitch of a surfac.e
|
||||
uint32_t boffset[NV3_PGRAPH_MAX_BUFFERS]; // 22-bit linear VRAM offset for the start of a buffer.
|
||||
uint16_t bpitch[NV3_PGRAPH_MAX_BUFFERS]; // 12-bit linear VRAM offset for the pitch of a buffer
|
||||
uint32_t bpixel[NV3_PGRAPH_MAX_BUFFERS]; // Pixel format for each possible surfaces.
|
||||
// CLIP
|
||||
nv3_pgraph_clip_misc_settings_t clip_misc_settings;
|
||||
|
||||
@@ -77,8 +77,13 @@ void nv3_class_01c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_
|
||||
break;
|
||||
/* Byte offset in GPU VRAM of top left pixel (22:0) */
|
||||
case NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET:
|
||||
nv3->pgraph.boffset[src_buffer_id] = param & ((1 << NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET_END) - 0x10);
|
||||
|
||||
if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) // RIVA 128ZX
|
||||
nv3->pgraph.boffset[src_buffer_id] = param & 0x7FFFFF;
|
||||
else
|
||||
nv3->pgraph.boffset[src_buffer_id] = param & 0x3FFFFF;
|
||||
|
||||
nv3->nvbase.last_buffer_address = nv3->pgraph.boffset[src_buffer_id];
|
||||
|
||||
nv_log("Method Execution: Image in Memory BUF%d TOP_LEFT_OFFSET=0x%08x\n", src_buffer_id, nv3->pgraph.boffset[src_buffer_id]);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -523,30 +523,27 @@ void nv3_recalc_timings(svga_t* svga)
|
||||
break;
|
||||
case NV3_CRTC_REGISTER_PIXELMODE_16BPP:
|
||||
/* This is some sketchy shit that is an attempt at an educated guess
|
||||
at pixel clock differences between 9x and NT only in 16bpp. If there is ever an error on 9x with "interlaced" looking graphics, this is what's causing it */
|
||||
at pixel clock differences between 9x and NT only in 16bpp. If there is ever an error on 9x with "interlaced" looking graphics,
|
||||
this is what's causing it. Possibly fucking *ReactOS* of all things */
|
||||
if ((svga->crtc[NV3_CRTC_REGISTER_VRETRACESTART] >> 1) & 0x01)
|
||||
{
|
||||
svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 3;
|
||||
}
|
||||
|
||||
|
||||
/* sometimes it really renders in 15bpp, so you need to do this */
|
||||
if ((nv3->pramdac.general_control >> NV3_PRAMDAC_GENERAL_CONTROL_565_MODE) & 0x01)
|
||||
{
|
||||
svga->bpp = 16;
|
||||
svga->lowres = 0;
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
svga->render = nv3_render_16bpp;
|
||||
}
|
||||
else
|
||||
{
|
||||
svga->bpp = 15;
|
||||
svga->lowres = 0;
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->render = nv3_render_15bpp;
|
||||
|
||||
// fixes win2000, but breaks 9x?!
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -555,7 +552,7 @@ void nv3_recalc_timings(svga_t* svga)
|
||||
|
||||
svga->bpp = 32;
|
||||
svga->lowres = 0;
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
svga->render = nv3_render_32bpp;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,12 +164,13 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj)
|
||||
|
||||
memcpy(&nv3_s2sb_line_buffer[buf_position], &nv3->nvbase.svga.vram[vram_position], size_x);
|
||||
}
|
||||
|
||||
/* simply write it all back to vram */
|
||||
for (int32_t y = 0; y < nv3->pgraph.blit.size.h; y++)
|
||||
{
|
||||
buf_position = (nv3->pgraph.blit.size.w * y);
|
||||
new_position.y = nv3->pgraph.blit.point_out.y + y;
|
||||
vram_position = nv3_render_get_vram_address(new_position, grobj, false);
|
||||
vram_position = nv3_render_get_vram_address(new_position, grobj, true);
|
||||
memcpy(&nv3->nvbase.svga.vram[vram_position], &nv3_s2sb_line_buffer[buf_position], size_x);
|
||||
}
|
||||
}
|
||||
@@ -436,3 +436,164 @@ void nv3_render_write_pixel(nv3_position_16_t position, uint32_t color, nv3_grob
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Modified SVGA Core functions
|
||||
Done, to facilitate the buffer changing around stuff.
|
||||
|
||||
TODO: Do we need a custom 8bpp function?
|
||||
*/
|
||||
|
||||
void nv3_render_15bpp(svga_t *svga)
|
||||
{
|
||||
int x;
|
||||
uint32_t *p;
|
||||
uint32_t dat;
|
||||
uint32_t changed_addr;
|
||||
uint32_t addr;
|
||||
|
||||
/* "force_old_addr" code path removed, since we don't need it */
|
||||
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
changed_addr = svga->remap_func(svga, svga->ma);
|
||||
|
||||
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
|
||||
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
if (!svga->remap_required) {
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 15);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 15);
|
||||
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 15);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 15);
|
||||
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 15);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 15);
|
||||
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 15);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 15);
|
||||
}
|
||||
svga->ma += x << 1;
|
||||
} else {
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
|
||||
addr = svga->remap_func(svga, svga->ma);
|
||||
dat = *(uint32_t *) (&svga->vram[(addr) & svga->vram_display_mask]);
|
||||
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 15);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 15);
|
||||
svga->ma += 4;
|
||||
}
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nv3_render_16bpp(svga_t *svga)
|
||||
{
|
||||
int x;
|
||||
uint32_t *p;
|
||||
uint32_t dat;
|
||||
uint32_t changed_addr;
|
||||
uint32_t addr;
|
||||
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
changed_addr = svga->remap_func(svga, svga->ma);
|
||||
|
||||
/* "force_old_addr" code path removed, since we don't need it */
|
||||
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
|
||||
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
if (!svga->remap_required) {
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 16);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 16);
|
||||
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 16);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 16);
|
||||
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 16);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 16);
|
||||
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 16);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 16);
|
||||
}
|
||||
svga->ma += x << 1;
|
||||
} else {
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
|
||||
addr = svga->remap_func(svga, svga->ma);
|
||||
dat = *(uint32_t *) (&svga->vram[(addr) & svga->vram_display_mask]);
|
||||
|
||||
*p++ = svga->conv_16to32(svga, dat & 0xffff, 16);
|
||||
*p++ = svga->conv_16to32(svga, dat >> 16, 16);
|
||||
|
||||
svga->ma += 4;
|
||||
}
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nv3_render_32bpp(svga_t *svga)
|
||||
{
|
||||
int x;
|
||||
uint32_t *p;
|
||||
uint32_t dat;
|
||||
uint32_t changed_addr;
|
||||
uint32_t addr;
|
||||
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
/* "force_old_addr" code path removed, since we don't need it */
|
||||
|
||||
changed_addr = svga->remap_func(svga, svga->ma);
|
||||
|
||||
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
|
||||
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
if (!svga->remap_required) {
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
|
||||
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
||||
*p++ = svga_lookup_lut_ram(svga, dat & 0xffffff);
|
||||
}
|
||||
svga->ma += (x * 4);
|
||||
} else {
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
|
||||
addr = svga->remap_func(svga, svga->ma);
|
||||
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
|
||||
*p++ = svga_lookup_lut_ram(svga, dat & 0xffffff);
|
||||
|
||||
svga->ma += 4;
|
||||
}
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -873,7 +873,7 @@ void nv3_pfifo_cache1_push(uint32_t addr, uint32_t param)
|
||||
uint32_t next_put_address = nv3_pfifo_cache1_gray2normal(current_put_index);
|
||||
next_put_address++;
|
||||
|
||||
if (nv3->nvbase.gpu_revision >= NV3_BOOT_REG_REV_C00) // RIVA 128ZX#
|
||||
if (nv3->nvbase.gpu_revision >= NV3_PCI_CFG_REVISION_C00) // RIVA 128ZX#
|
||||
next_put_address &= (NV3_PFIFO_CACHE1_SIZE_REV_C - 1);
|
||||
else
|
||||
next_put_address &= (NV3_PFIFO_CACHE1_SIZE_REV_AB - 1);
|
||||
@@ -931,7 +931,7 @@ void nv3_pfifo_cache1_pull()
|
||||
// start by incrementing
|
||||
uint32_t next_get_address = nv3_pfifo_cache1_gray2normal(get_index) + 1;
|
||||
|
||||
if (nv3->nvbase.gpu_revision >= NV3_BOOT_REG_REV_C00) // RIVA 128ZX#
|
||||
if (nv3->nvbase.gpu_revision >= NV3_PCI_CFG_REVISION_C00) // RIVA 128ZX
|
||||
next_get_address &= (NV3_PFIFO_CACHE1_SIZE_REV_C - 1);
|
||||
else
|
||||
next_get_address &= (NV3_PFIFO_CACHE1_SIZE_REV_AB - 1);
|
||||
|
||||
Reference in New Issue
Block a user