From b0f20c9bbaf779813e84be48831a10630933914d Mon Sep 17 00:00:00 2001 From: Erik Abair Date: Tue, 3 May 2022 16:44:18 -0700 Subject: [PATCH] nv2a: Fix stale texture in surface input and output case --- hw/xbox/nv2a/pgraph.c | 61 +++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/hw/xbox/nv2a/pgraph.c b/hw/xbox/nv2a/pgraph.c index bac7151e9b..d2486c1fd3 100644 --- a/hw/xbox/nv2a/pgraph.c +++ b/hw/xbox/nv2a/pgraph.c @@ -2796,6 +2796,14 @@ DEF_METHOD(NV097, SET_BEGIN_END) glEndQuery(GL_SAMPLES_PASSED); } + pg->draw_time++; + if (pg->color_binding && pgraph_color_write_enabled(pg)) { + pg->color_binding->draw_time = pg->draw_time; + } + if (pg->zeta_binding && pgraph_zeta_write_enabled(pg)) { + pg->zeta_binding->draw_time = pg->draw_time; + } + NV2A_GL_DGROUP_END(); } else { NV2A_GL_DGROUP_BEGIN("NV097_SET_BEGIN_END: 0x%x", parameter); @@ -6160,7 +6168,32 @@ static void pgraph_bind_textures(NV2AState *d) nv2a_profile_inc_counter(NV2A_PROF_TEX_BIND); - if (!pg->texture_dirty[i] && pg->texture_binding[i]) { + hwaddr dma_len; + uint8_t *texture_data; + if (dma_select) { + texture_data = (uint8_t*)nv_dma_map(d, pg->dma_b, &dma_len); + } else { + texture_data = (uint8_t*)nv_dma_map(d, pg->dma_a, &dma_len); + } + assert(offset < dma_len); + texture_data += offset; + hwaddr texture_vram_offset = texture_data - d->vram_ptr; + + hwaddr palette_dma_len; + uint8_t *palette_data; + if (palette_dma_select) { + palette_data = (uint8_t*)nv_dma_map(d, pg->dma_b, &palette_dma_len); + } else { + palette_data = (uint8_t*)nv_dma_map(d, pg->dma_a, &palette_dma_len); + } + assert(palette_offset < palette_dma_len); + palette_data += palette_offset; + hwaddr palette_vram_offset = palette_data - d->vram_ptr; + + SurfaceBinding *surface = pgraph_surface_get(d, texture_vram_offset); + TextureBinding *tbind = pg->texture_binding[i]; + if (!pg->texture_dirty[i] && tbind && + (!surface || tbind->draw_time == surface->draw_time)) { glBindTexture(pg->texture_binding[i]->gl_target, pg->texture_binding[i]->gl_texture); continue; @@ -6243,28 +6276,6 @@ static void pgraph_bind_textures(NV2AState *d) assert(levels > 0); } - hwaddr dma_len; - uint8_t *texture_data; - if (dma_select) { - texture_data = (uint8_t*)nv_dma_map(d, pg->dma_b, &dma_len); - } else { - texture_data = (uint8_t*)nv_dma_map(d, pg->dma_a, &dma_len); - } - assert(offset < dma_len); - texture_data += offset; - hwaddr texture_vram_offset = texture_data - d->vram_ptr; - - hwaddr palette_dma_len; - uint8_t *palette_data; - if (palette_dma_select) { - palette_data = (uint8_t*)nv_dma_map(d, pg->dma_b, &palette_dma_len); - } else { - palette_data = (uint8_t*)nv_dma_map(d, pg->dma_a, &palette_dma_len); - } - assert(palette_offset < palette_dma_len); - palette_data += palette_offset; - hwaddr palette_vram_offset = palette_data - d->vram_ptr; - size_t length = 0; if (f.linear) { assert(cubemap == false); @@ -6329,7 +6340,6 @@ static void pgraph_bind_textures(NV2AState *d) * Check active surfaces to see if this texture was a render target */ bool surf_to_tex = false; - SurfaceBinding *surface = pgraph_surface_get(d, texture_vram_offset); if (surface != NULL) { surf_to_tex = pgraph_check_surface_to_texture_compatibility( surface, &state); @@ -6424,7 +6434,8 @@ static void pgraph_bind_textures(NV2AState *d) TextureBinding *binding = key_out->binding; binding->refcnt++; - if (surf_to_tex && (binding->draw_time < surface->draw_time)) { + if (surf_to_tex && binding->draw_time < surface->draw_time) { + NV2A_XPRINTF(DBG_SURFACES, "Rendering surface @ %" HWADDR_PRIx " to texture (%dx%d)\n", surface->vram_addr, surface->width, surface->height);