Fix various minor bugs; correctly use bpixel for rendering instead of svga->bpp. remove incorrect DBA check

This commit is contained in:
starfrost013
2025-05-18 16:45:24 +01:00
parent 3f6be875d4
commit aaaa4db881
8 changed files with 54 additions and 56 deletions

View File

@@ -36,8 +36,7 @@
"name": "debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"NV_LOG": "ON",
"NV_LOG_ULTRA": "ON"
"NV_LOG": "ON"
},
"inherits": "base"
},

Binary file not shown.

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 run_render_check, bool use_destination_buffer);
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_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

@@ -32,13 +32,28 @@
<string>VRAM Viewer</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QLabel" name="GPUDebugVRAMDialog_LabelHeader">
<property name="text">
<string>VRAM Viewer</string>
</property>
</widget>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>VRAM</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignBottom|Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -963,7 +963,7 @@ void nv3_draw_cursor(svga_t* svga, int32_t drawline)
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, false);
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

@@ -57,7 +57,7 @@ void nv3_render_blit_image(uint32_t color, nv3_grobj_t grobj)
/* the reverse order is due to the endianness */
switch (nv3->nvbase.svga.bpp)
{
// 4pixels packed into one color
// 4 pixels packed into one color in 8bpp
case 8:
//pixel3
@@ -82,7 +82,7 @@ void nv3_render_blit_image(uint32_t color, nv3_grobj_t grobj)
nv3_class_011_check_line_bounds();
break;
//2pixels packed into one color
// 2 pixels packed into one color in 15/16bpp
case 15:
case 16:
pixel1 = (color) & 0xFFFF;
@@ -98,8 +98,7 @@ void nv3_render_blit_image(uint32_t color, nv3_grobj_t grobj)
break;
// just one pixel in 32bpp
case 32:
pixel0 = color;
if (nv3->pgraph.image_current_position.x < clip_x) nv3_render_write_pixel(nv3->pgraph.image_current_position, pixel0, grobj);
if (nv3->pgraph.image_current_position.x < clip_x) nv3_render_write_pixel(nv3->pgraph.image_current_position, color, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
@@ -183,8 +182,7 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj)
We also need to update all of the areas of the screen that moved.
*/
nv3_coord_16_t blit_position = {0};
nv3_coord_16_t blit_size = {0};
nv3_coord_16_t blit_position = {0}, blit_size = {0};
/* Change the smallest area of the screen that moved */
@@ -223,7 +221,6 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj)
/* 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, false, true);
nv3_render_current_bpp(&nv3->nvbase.svga, blit_position, blit_size, grobj, true);
}

View File

@@ -81,10 +81,10 @@ nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj)
break;
case nv3_pgraph_pixel_format_r10g10b10:
color_final.a = (color << 31) & 0x01;
color_final.r = (color << 30) & 0x3FF;
color_final.g = (color << 20) & 0x1FF;
color_final.b = (color << 10);
color_final.a = (color >> 31) & 0x01;
color_final.r = (color >> 30) & 0x3FF;
color_final.g = (color >> 20) & 0x1FF;
color_final.b = (color >> 10);
break;
case nv3_pgraph_pixel_format_y8:
@@ -138,7 +138,7 @@ uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t co
break;
case nv3_pgraph_pixel_format_r10g10b10:
/* sometimes alpha isn't used but we should incorporate it anyway */
if (color.a > 0x00) packed_color | (1 << 31);
if (color.a > 0x00) packed_color |= (1 << 31);
packed_color |= (color.r << 30);
packed_color |= (color.g << 20);
@@ -187,7 +187,7 @@ bool nv3_render_chroma_test(uint32_t color, nv3_grobj_t grobj)
uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded)
{
// convert the alpha to 1 bit. then return packed rgb10
return !!expanded.a | (expanded.r << 30) | (expanded.b << 20) | (expanded.a << 10);
return !!expanded.a | (expanded.r << 30) | (expanded.b << 20) | (expanded.b << 10);
}
/* Get a colour for a palette index. (The colours are 24 bit RGB888 with a 0xFF alpha added for some purposes.) */
@@ -360,6 +360,14 @@ void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t
bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_ALPHA) & 0x01;
uint32_t dst_buffer = 0; // 5 = just use the source buffer
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER0_ENABLED) & 0x01) dst_buffer = 0;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER1_ENABLED) & 0x01) dst_buffer = 1;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER2_ENABLED) & 0x01) dst_buffer = 2;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER3_ENABLED) & 0x01) dst_buffer = 3;
uint32_t framebuffer_bpp = nv3->nvbase.svga.bpp; // maybe y16 too?z
int32_t clip_end_x = nv3->pgraph.clip_start.x + nv3->pgraph.clip_size.x;
@@ -426,12 +434,14 @@ void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t
It seems we can skip the downconversion step *for now*, since (framebuffer bits per pixel) == (object bits per pixel)
I'm not sure how games will react. But it depends on how the D3D drivers operate, we may need ro convert texture formats to the current bpp internally.
TODO: MOVE TO BPIXEL DEPTH or GROBJ0 to determine this, once we figure out how to get the bpixel depth.
We use the pixel format of the destination buffer to achieve this (thanks frostbite2000)
*/
switch (framebuffer_bpp)
uint32_t destination_format = (nv3->pgraph.bpixel[dst_buffer]) & 0x03;
switch (destination_format)
{
case 8:
case bpixel_fmt_8bit:
rop_src = color & 0xFF;
rop_dst = nv3->nvbase.svga.vram[pixel_addr_vram];
nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern) & 0xFF;
@@ -439,8 +449,7 @@ void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t
nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount;
break;
case 15:
case 16:
case bpixel_fmt_16bit:
{
uint16_t* vram_16 = (uint16_t*)(nv3->nvbase.svga.vram);
pixel_addr_vram >>= 1;
@@ -471,7 +480,7 @@ void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t
break;
}
case 32:
case bpixel_fmt_32bit:
{
uint32_t* vram_32 = (uint32_t*)(nv3->nvbase.svga.vram);
pixel_addr_vram >>= 2;
@@ -489,7 +498,7 @@ void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t
/* 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, true, false);
nv3_render_current_bpp(&nv3->nvbase.svga, position, size, grobj, false);
}
/* Ensure the correct monitor size */
@@ -602,35 +611,13 @@ 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 run_render_check, bool use_destination_buffer)
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)
{
/* 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 */
/* Not needed for s2sb*/
if (run_render_check)
{
/* Figure out the Display Buffer Address from the CRTCs */
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];
/* Check our destination(?) buffer */
uint32_t dst_buffer = 0; // 5 = just use the source buffer
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER0_ENABLED) & 0x01) dst_buffer = 0;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER1_ENABLED) & 0x01) dst_buffer = 1;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER2_ENABLED) & 0x01) dst_buffer = 2;
if ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER3_ENABLED) & 0x01) dst_buffer = 3;
/* If the BUFFER_ADDRESS of the last buffer is not the DBA, we don't *actually* want to draw this, so let's not */
if (nv3->pgraph.boffset[dst_buffer] != dba)
return;
}
switch (nv3->nvbase.svga.bpp)
{
case 4:

View File

@@ -39,7 +39,7 @@ nv_register_t pfb_registers[] = {
{ NV3_PFB_GREEN_0, "PFB Green / Power Saving", NULL, NULL,},
{ NV3_PFB_CONFIG_0, "PFB Framebuffer Config 0", nv3_pfb_config0_read, nv3_pfb_config0_write },
{ NV3_PFB_CONFIG_1, "PFB Framebuffer Config 1", NULL, NULL },
{ NV3_PFB_RTL, "PFB RTL (Part of memory timings?)", NULL, NULL },
{ NV3_PFB_RTL, "PFB RTL (Part of memory timings)", NULL, NULL },
{ NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value
};