From 97a06fa007608aa55881f26d5eb623ba34a9c1a3 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sat, 22 Mar 2025 13:25:33 +0000 Subject: [PATCH] Implement RAMRO, and also fix runout_put and runout_get so that it can actually runout without freezing (I don't think it should be even if it's only running out on a few objects, but it should be able to runout anyway.) --- .../nv/nv3/classes/nv3_class_007_rectangle.c | 2 +- src/video/nv/nv3/render/nv3_render_core.c | 14 ++++++-- src/video/nv/nv3/subsystems/nv3_pfifo.c | 35 ++++++++++++++++--- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/video/nv/nv3/classes/nv3_class_007_rectangle.c b/src/video/nv/nv3/classes/nv3_class_007_rectangle.c index 856c1c6cd..a92a1f761 100644 --- a/src/video/nv/nv3/classes/nv3_class_007_rectangle.c +++ b/src/video/nv/nv3/classes/nv3_class_007_rectangle.c @@ -48,7 +48,7 @@ void nv3_class_007_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ nv3->pgraph.rectangle.size[index].h = (param >> 16) & 0xFFFF; - nv_log("Rect%d Size=%d,%d\n", index, nv3->pgraph.rectangle.size[index].w, nv3->pgraph.rectangle.size[index].h); + nv_log("Rect%d Size=%d,%d Color=0x%08x\n", index, nv3->pgraph.rectangle.size[index].w, nv3->pgraph.rectangle.size[index].h, nv3->pgraph.rectangle.color); nv3_render_rect(nv3->pgraph.rectangle.position[index], nv3->pgraph.rectangle.size[index], nv3->pgraph.rectangle.color, grobj); } diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index 8d7bdd189..7b9b3e303 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -128,6 +128,10 @@ 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); + break; case nv3_pgraph_pixel_format_r8g8b8: break; @@ -146,6 +150,12 @@ uint32_t nv3_render_downconvert(nv3_grobj_t grobj, nv3_color_expanded_t color) return packed_color; } +/* Runs the chroma key test */ +void nv3_render_chroma_test(nv3_grobj_t grobj) +{ + +} + /* Convert expanded colour format to chroma key format */ uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded) { @@ -200,10 +210,10 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr case 8: break; case 16: - vram_x = position.x * 2; + vram_x = position.x << 1; break; case 32: - vram_x = position.x * 4; + vram_x = position.x << 2; break; } diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c index 81b13e5bf..bac84ede9 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c @@ -556,20 +556,22 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) nv3->pfifo.cache1_settings.get_address = val; break; case NV3_PFIFO_RUNOUT_GET: + uint32_t size_get = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); if (size_get == 0) //512b - nv3->pfifo.runout_get = ((val & 0x3F) << 3); + nv3->pfifo.runout_get = val & (NV3_RAMIN_RAMRO_SIZE_0 - 0x07); else - nv3->pfifo.runout_get = ((val & 0x3FF) << 3); + nv3->pfifo.runout_get = val & (NV3_RAMIN_RAMRO_SIZE_1 - 0x07); break; case NV3_PFIFO_RUNOUT_PUT: uint32_t size_put = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); if (size_put == 0) //512b - nv3->pfifo.runout_put = ((val & 0x3F) << 3); + nv3->pfifo.runout_put = val & (NV3_RAMIN_RAMRO_SIZE_0 - 0x07); else - nv3->pfifo.runout_put = ((val & 0x3FF) << 3); + nv3->pfifo.runout_put = val & (NV3_RAMIN_RAMRO_SIZE_1 - 0x07); + break; /* Cache1 is handled below */ case NV3_PFIFO_CACHE0_CTX: @@ -833,6 +835,31 @@ void nv3_pfifo_cache1_push(uint32_t addr, uint32_t param) if (oh_shit) { nv_log("WE ARE FUCKED Runout Error=%d Channel=%d Subchannel=%d Method=0x%04x IMPLEMENT THIS OR DIE!!!", oh_shit_reason, channel, subchannel, method_offset); + + nv3_ramro_write(nv3->pfifo.runout_put, new_address); + nv3_ramro_write(nv3->pfifo.runout_put + 4, param); + + nv3->pfifo.runout_put += 0x08; + + uint32_t ramro_size = (nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01; + + /* Make sure it's valid */ + switch (ramro_size) + { + case 0: + nv3->pfifo.runout_put &= (NV3_RAMIN_RAMRO_SIZE_0 - 0x07); + break; + case 1: + nv3->pfifo.runout_put &= (NV3_RAMIN_RAMRO_SIZE_1 - 0x07); + break; + } + + /* Fire the interrupt. Also the very bad interrupt...*/ + if (nv3->pfifo.runout_get == nv3->pfifo.runout_put) + nv3_pfifo_interrupt(NV3_PFIFO_INTR_RUNOUT_OVERFLOW, true); + else + nv3_pfifo_interrupt(NV3_PFIFO_INTR_RUNOUT, true); + return; }