From 160e8a8071c7ba3de0843d887378080aed28fba0 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 23 Mar 2025 17:06:53 +0000 Subject: [PATCH] Clean up stupid colour structs and implement patterns (class 0x06). Now, you can select taskbar items and some lines draw. Replace some multiplications with shifts. --- doc/nvidia_notes/status.xlsx | Bin 15227 -> 15356 bytes .../86box/nv/classes/vid_nv3_classes.h | 61 +++---- src/include/86box/nv/render/vid_nv3_render.h | 6 +- src/include/86box/nv/vid_nv3.h | 21 ++- src/video/CMakeLists.txt | 3 +- .../nv3/classes/nv3_class_001_beta_factor.c | 2 +- src/video/nv/nv3/classes/nv3_class_002_rop.c | 2 +- .../nv/nv3/classes/nv3_class_003_chroma_key.c | 7 +- .../nv/nv3/classes/nv3_class_006_pattern.c | 41 ++++- .../classes/nv3_class_01c_image_in_memory.c | 2 +- .../nv/nv3/classes/nv3_class_shared_methods.c | 2 +- src/video/nv/nv3/render/nv3_render_core.c | 154 ++++++++++++++---- src/video/nv/nv3/subsystems/nv3_pgraph.c | 50 +++--- 13 files changed, 227 insertions(+), 124 deletions(-) diff --git a/doc/nvidia_notes/status.xlsx b/doc/nvidia_notes/status.xlsx index a301eba64e4f3c03a76698c87a828d2365c86b89..4118b2c5609b86ddcf989d9b715effdc97ee38e4 100644 GIT binary patch delta 6313 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 A>i_@% delta 6187 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.chroma_key = *(nv3_color_x2a10g10b10_t*)&color; + + nv3->pgraph.chroma_key = nv3_render_to_chroma(expanded_color); break; default: nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; + break; } } \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_006_pattern.c b/src/video/nv/nv3/classes/nv3_class_006_pattern.c index 2c2174447..36ce70e19 100644 --- a/src/video/nv/nv3/classes/nv3_class_006_pattern.c +++ b/src/video/nv/nv3/classes/nv3_class_006_pattern.c @@ -32,9 +32,48 @@ void nv3_class_006_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ { switch (method_id) { + /* Valid software method, suppress logging */ + case NV3_PATTERN_FORMAT: + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); + break; + case NV3_PATTERN_SHAPE: + /* If the shape is not valid, tell the software that it's invalid */ + + /* + Technically you are meant to do this: + + But in practice, I don't know, because it always submits 0x20 or 0x40, which are valid when param & 0x03, + and appear to be deliberate behaviour in the drivers rather than bugs. What + if (param > NV3_PATTERN_SHAPE_LAST_VALID) + { + warning("NV3 class 0x06 (Pattern) invalid shape %d (This is a bug)", param); + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_INVALID_DATA); + return; + } + + */ + nv3->pgraph.pattern_shape = param & 0x03; + + break; + case NV3_PATTERN_COLOR0: + nv3_color_expanded_t expanded_colour0 = nv3_render_expand_color(grobj, param); + nv3_render_set_pattern_color(expanded_colour0, false); + break; + case NV3_PATTERN_COLOR1: + nv3_color_expanded_t expanded_colour1 = nv3_render_expand_color(grobj, param); + nv3_render_set_pattern_color(expanded_colour1, true); + break; + case NV3_PATTERN_BITMAP_HIGH: + nv3->pgraph.pattern_bitmap = 0; //reset + nv3->pgraph.pattern_bitmap |= ((uint64_t)param << 32); + break; + case NV3_PATTERN_BITMAP_LOW: + nv3->pgraph.pattern_bitmap |= param; + + break; default: nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; + break; } } \ No newline at end of file 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 9ba86c0eb..a6cb52fbf 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 @@ -85,6 +85,6 @@ void nv3_class_01c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ default: nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; + break; } } \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_shared_methods.c b/src/video/nv/nv3/classes/nv3_class_shared_methods.c index 0bb12a2eb..9985845cf 100644 --- a/src/video/nv/nv3/classes/nv3_class_shared_methods.c +++ b/src/video/nv/nv3/classes/nv3_class_shared_methods.c @@ -35,7 +35,7 @@ void nv3_generic_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t { /* mthdCreate in software(?)*/ case NV3_ROOT_HI_IM_OBJECT_MCOBJECTYFACE: - nv_log("mthdCreate\n"); + nv_log("mthdCreate obj_name=0x%08x\n", param); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); break; // set up the current notification request/object diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index 8ccca2e6f..741f8e422 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -57,14 +57,12 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) // 555 case nv3_pgraph_pixel_format_r5g5b5: - nv3_color_16_a1r5g5b5_t new_color = *(nv3_color_16_a1r5g5b5_t*)&color; // "stretch out" the colour - color_final.r = new_color.r * 0x20; - color_final.g = new_color.g * 0x20; - color_final.b = new_color.b * 0x20; - if (alpha_enabled) - color_final.a = new_color.a; + color_final.a = (color >> 15) & 0x01; // will be ignored if alpha_enabled isn't used + color_final.r = ((color >> 10) & 0x1F) << 5; + color_final.g = ((color >> 5) & 0x1F) << 5; + color_final.b = (color & 0x1F) << 5; break; // 888 (standard colour + 8-bit alpha) @@ -76,18 +74,12 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) color_final.g = ((color >> 8) & 0xFF) * 4; color_final.b = (color & 0xFF) * 4; - if (alpha_enabled) - color_final.a = new_color.a; break; case nv3_pgraph_pixel_format_r10g10b10: - nv3_color_x2a10g10b10_t new_color_rgb10 = *(nv3_color_x2a10g10b10_t*)&color; - - color_final.r = new_color_rgb10.r; - color_final.g = new_color_rgb10.g; - color_final.b = new_color_rgb10.b; - - if (alpha_enabled) - color_final.a = new_color.a; + 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: @@ -115,7 +107,7 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) } /* Used for chroma test */ -uint32_t nv3_render_downconvert(nv3_grobj_t grobj, nv3_color_expanded_t color) +uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t color) { uint8_t format = (grobj.grobj_0 & 0x07); bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_ALPHA) & 0x01; @@ -129,18 +121,30 @@ uint32_t nv3_render_downconvert(nv3_grobj_t grobj, nv3_color_expanded_t color) switch (format) { case nv3_pgraph_pixel_format_r5g5b5: - packed_color = (color.r / 0x20) << 10 | - (color.g / 0x20) << 5 | - (color.b / 0x20); + packed_color = (color.r >> 5) << 10 | + (color.g >> 5) << 5 | + (color.b >> 5); break; case nv3_pgraph_pixel_format_r8g8b8: + packed_color = (color.a) << 24 | // is this a thing? + (color.r >> 2) << 16 | + (color.g >> 2) << 8 | + color.b; 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); + + packed_color |= (color.r << 30); + packed_color |= (color.g << 20); + packed_color |= (color.b << 10); break; case nv3_pgraph_pixel_format_y8: + nv_log("nv3_render_downconvert: Y8 not implemented"); break; case nv3_pgraph_pixel_format_y16: + nv_log("nv3_render_downconvert: Y16 not implemented"); break; default: warning("nv3_render_downconvert_color unknown format %d", format); @@ -164,6 +168,37 @@ uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded) return !!expanded.a | (expanded.r << 30) | (expanded.b << 20) | (expanded.a << 10); } +/* Convert a rgb10 colour to a pattern colour */ +uint32_t nv3_render_set_pattern_color(nv3_color_expanded_t pattern_colour, bool use_color1) +{ + /* reset the colour */ + if (!use_color1) + nv3->pgraph.pattern_color_0_rgb.r = nv3->pgraph.pattern_color_0_rgb.g = nv3->pgraph.pattern_color_0_rgb.b = 0x00; + else + nv3->pgraph.pattern_color_1_rgb.r = nv3->pgraph.pattern_color_1_rgb.g = nv3->pgraph.pattern_color_1_rgb.b = 0x00; + + /* select the right pattern colour, _rgb is already in RGB10 format, so we don't need to do any conversion */ + + if (!use_color1) + { + nv3->pgraph.pattern_color_0_alpha = (pattern_colour.a) & 0xFF; + nv3->pgraph.pattern_color_0_rgb.r = pattern_colour.r; + nv3->pgraph.pattern_color_0_rgb.g = pattern_colour.g; + nv3->pgraph.pattern_color_0_rgb.b = pattern_colour.b; + + } + else + { + nv3->pgraph.pattern_color_1_alpha = (pattern_colour.a) & 0xFF; + nv3->pgraph.pattern_color_1_rgb.r = pattern_colour.r; + nv3->pgraph.pattern_color_1_rgb.g = pattern_colour.g; + nv3->pgraph.pattern_color_1_rgb.b = pattern_colour.b; + } + + + +} + /* Plots a pixel. */ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t grobj) { @@ -224,6 +259,46 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr pixel_addr_vram &= nv3->nvbase.svga.vram_mask; + uint32_t rop_src = 0, rop_dst = 0, rop_pattern = 0; + uint8_t bit = 0x00; + + /* Get our pattern data, may move to another function */ + switch (nv3->pgraph.pattern.shape) + { + + /* This logic is from NV1 envytoos docs, but seems to be same on NV3*/ + case NV3_PATTERN_SHAPE_8X8: + bit = (position.x & 7) | (position.y & 7) << 3; + break; + case NV3_PATTERN_SHAPE_1X64: + bit = (position.x & 0x3f); + break; + case NV3_PATTERN_SHAPE_64X1: + bit = (position.y & 0x3f); + break; + } + + // pull out the actual bit and see which colour we need to use + + bool use_color1 = (nv3->pgraph.pattern_bitmap >> bit) & 0x01; + + if (!use_color1) + { + if (!nv3->pgraph.pattern_color_0_alpha) + return; + + /* This is stupid */ + rop_pattern = nv3_render_downconvert_color(grobj, nv3->pgraph.pattern_color_0_rgb); + } + else + { + if (!nv3->pgraph.pattern_color_1_alpha) + return; + + rop_pattern = nv3_render_downconvert_color(grobj, nv3->pgraph.pattern_color_1_rgb); + } + + /* Go to vram and do the final ROP for a basic bitblit. 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. @@ -231,14 +306,12 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr TODO: MOVE TO BPIXEL DEPTH or GROBJ0 to determine this, once we figure out how to get the bpixel depth. */ - uint32_t src = 0, dst = 0; - switch (framebuffer_bpp) { case 8: - src = color & 0xFF; - dst = nv3->nvbase.svga.vram[pixel_addr_vram]; - nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00) & 0xFF; + 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; nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount; @@ -246,19 +319,28 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr case 16: uint16_t* vram_16 = (uint16_t*)(nv3->nvbase.svga.vram); pixel_addr_vram >>= 1; + + // mask to 16bit - // mask off the alpha bit. Even though the drivers should send this. What! - if (!alpha_enabled) - src = ((color & (~0x8000)) & 0xFFFF); - else - src = color & 0xFFFF; + rop_src = color & 0xFFFF; + + /* if alpha is turned on and we aren't in 565 mode, reject transparent pixels */ + bool is_16bpp = (nv3->pramdac.general_control >> NV3_PRAMDAC_GENERAL_CONTROL_565_MODE) & 0x01; + + // a1r5g5b5 + if (!is_16bpp) + { + if (alpha_enabled && + !(color & 0x8000)) + return; + } // convert to 16bpp // forcing it to render in 15bpp fixes it, - - dst = vram_16[pixel_addr_vram]; - vram_16[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00) & 0xFFFF; + rop_dst = vram_16[pixel_addr_vram]; + + vram_16[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern) & 0xFFFF; nv3->nvbase.svga.changedvram[pixel_addr_vram >> 11] = changeframecount; @@ -267,9 +349,9 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr uint32_t* vram_32 = (uint32_t*)(nv3->nvbase.svga.vram); pixel_addr_vram >>= 2; - src = color; - dst = vram_32[pixel_addr_vram]; - vram_32[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + rop_src = color; + rop_dst = vram_32[pixel_addr_vram]; + vram_32[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern); nv3->nvbase.svga.changedvram[pixel_addr_vram >> 10] = changeframecount; diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c index 993232c9d..70aef4270 100644 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ b/src/video/nv/nv3/subsystems/nv3_pgraph.c @@ -63,10 +63,10 @@ nv_register_t pgraph_registers[] = { { NV3_PGRAPH_SRC_CANVAS_MAX, "PGRAPH Source Canvas Maximum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, { NV3_PGRAPH_DST_CANVAS_MIN, "PGRAPH Destination Canvas Minimum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, { NV3_PGRAPH_DST_CANVAS_MAX, "PGRAPH Destination Canvas Maximum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, - { NV3_PGRAPH_PATTERN_COLOR_0_0, "PGRAPH Pattern Color 0_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_0_1, "PGRAPH Pattern Color 0_1 (Bits 7:0 = Alpha)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_1_0, "PGRAPH Pattern Color 1_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_1_1, "PGRAPH Pattern Color 1_1 (Bits 7:0 = Alpha)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_0_rgb, "PGRAPH Pattern Color 0_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_0_alpha, "PGRAPH Pattern Color 0_1 (Bits 7:0 = Alpha)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_1_rgb, "PGRAPH Pattern Color 1_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_1_alpha, "PGRAPH Pattern Color 1_1 (Bits 7:0 = Alpha)", NULL, NULL, }, { NV3_PGRAPH_PATTERN_BITMAP_HIGH, "PGRAPH Pattern Bitmap (High 32bits)", NULL, NULL}, { NV3_PGRAPH_PATTERN_BITMAP_LOW, "PGRAPH Pattern Bitmap (Low 32bits)", NULL, NULL}, { NV3_PGRAPH_PATTERN_SHAPE, "PGRAPH Pattern Shape (1:0 - 0=8x8, 1=64x1, 2=1x64)", NULL, NULL}, @@ -185,23 +185,23 @@ uint32_t nv3_pgraph_read(uint32_t address) ret = *(uint32_t*)&nv3->pgraph.src_canvas_max; break; // Pattern - case NV3_PGRAPH_PATTERN_COLOR_0_0: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_0; + case NV3_PGRAPH_pattern_color_0_rgb: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_rgb; break; - case NV3_PGRAPH_PATTERN_COLOR_0_1: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_1; + case NV3_PGRAPH_pattern_color_0_alpha: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_alpha; break; - case NV3_PGRAPH_PATTERN_COLOR_1_0: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_0; + case NV3_PGRAPH_pattern_color_1_rgb: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_rgb; break; - case NV3_PGRAPH_PATTERN_COLOR_1_1: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_1; + case NV3_PGRAPH_pattern_color_1_alpha: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_alpha; break; case NV3_PGRAPH_PATTERN_BITMAP_HIGH: - ret = nv3->pgraph.pattern_bitmap_high; + ret = (nv3->pgraph.pattern_bitmap >> 32) & 0xFFFFFFFF; break; case NV3_PGRAPH_PATTERN_BITMAP_LOW: - ret = nv3->pgraph.pattern_bitmap_low; + ret = (nv3->pgraph.pattern_bitmap & 0xFFFFFFFF); break; // Beta factor case NV3_PGRAPH_BETA: @@ -388,23 +388,23 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) *(uint32_t*)&nv3->pgraph.src_canvas_max = value; break; // Pattern - case NV3_PGRAPH_PATTERN_COLOR_0_0: - *(uint32_t*)&nv3->pgraph.pattern_color_0_0 = value; + case NV3_PGRAPH_pattern_color_0_rgb: + *(uint32_t*)&nv3->pgraph.pattern_color_0_rgb = value; break; - case NV3_PGRAPH_PATTERN_COLOR_0_1: - *(uint32_t*)&nv3->pgraph.pattern_color_0_1 = value; + case NV3_PGRAPH_pattern_color_0_alpha: + *(uint32_t*)&nv3->pgraph.pattern_color_0_alpha = value; break; - case NV3_PGRAPH_PATTERN_COLOR_1_0: - *(uint32_t*)&nv3->pgraph.pattern_color_1_0 = value; + case NV3_PGRAPH_pattern_color_1_rgb: + *(uint32_t*)&nv3->pgraph.pattern_color_1_rgb = value; break; - case NV3_PGRAPH_PATTERN_COLOR_1_1: - *(uint32_t*)&nv3->pgraph.pattern_color_1_1 = value; + case NV3_PGRAPH_pattern_color_1_alpha: + *(uint32_t*)&nv3->pgraph.pattern_color_1_alpha = value; break; case NV3_PGRAPH_PATTERN_BITMAP_HIGH: - nv3->pgraph.pattern_bitmap_high = value; + nv3->pgraph.pattern_bitmap |= ((uint64_t)value << 32); break; case NV3_PGRAPH_PATTERN_BITMAP_LOW: - nv3->pgraph.pattern_bitmap_low = value; + nv3->pgraph.pattern_bitmap |= value; break; // Beta factor case NV3_PGRAPH_BETA: @@ -415,7 +415,7 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) nv3->pgraph.rop = value & 0xFF; break; case NV3_PGRAPH_CHROMA_KEY: - nv3->pgraph.chroma_key = *(nv3_color_x2a10g10b10_t*)value; + nv3->pgraph.chroma_key = value; break; case NV3_PGRAPH_PLANE_MASK: nv3->pgraph.plane_mask = value;