nv2a: Block renderer finalization on display present

This commit is contained in:
Matt Borgerson 2024-07-26 17:21:01 -07:00 committed by mborgerson
parent 25afb8603d
commit 792ed56d58
6 changed files with 30 additions and 12 deletions

View File

@ -24,6 +24,7 @@
void nv2a_init(PCIBus *bus, int devfn, MemoryRegion *ram);
void nv2a_context_init(void);
int nv2a_get_framebuffer_surface(void);
void nv2a_release_framebuffer_surface(void);
void nv2a_set_surface_scale_factor(unsigned int scale);
unsigned int nv2a_get_surface_scale_factor(void);
const uint8_t *nv2a_get_dac_palette(void);

View File

@ -39,8 +39,6 @@ void pgraph_gl_set_surface_scale_factor(NV2AState *d, unsigned int scale)
g_config.display.quality.surface_scale = scale < 1 ? 1 : scale;
qemu_mutex_unlock_iothread();
qemu_mutex_lock(&d->pfifo.lock);
qatomic_set(&d->pfifo.halt, true);
qemu_mutex_unlock(&d->pfifo.lock);
@ -67,8 +65,6 @@ void pgraph_gl_set_surface_scale_factor(NV2AState *d, unsigned int scale)
qatomic_set(&d->pfifo.halt, false);
pfifo_kick(d);
qemu_mutex_unlock(&d->pfifo.lock);
qemu_mutex_lock_iothread();
}
unsigned int pgraph_gl_get_surface_scale_factor(NV2AState *d)

View File

@ -222,6 +222,7 @@ void pgraph_init(NV2AState *d)
qemu_mutex_init(&pg->renderer_lock);
qemu_event_init(&pg->sync_complete, false);
qemu_event_init(&pg->flush_complete, false);
qemu_cond_init(&pg->framebuffer_released);
pg->frame_time = 0;
pg->draw_time = 0;
@ -352,26 +353,41 @@ void pgraph_destroy(PGRAPHState *pg)
int nv2a_get_framebuffer_surface(void)
{
NV2AState *d = g_nv2a;
PGRAPHState *pg = &d->pgraph;
int s = 0;
qemu_mutex_lock(&d->pgraph.renderer_lock);
if (d->pgraph.renderer->ops.get_framebuffer_surface) {
s = d->pgraph.renderer->ops.get_framebuffer_surface(d);
qemu_mutex_lock(&pg->renderer_lock);
assert(!pg->framebuffer_in_use);
pg->framebuffer_in_use = true;
if (pg->renderer->ops.get_framebuffer_surface) {
s = pg->renderer->ops.get_framebuffer_surface(d);
}
qemu_mutex_unlock(&d->pgraph.renderer_lock);
qemu_mutex_unlock(&pg->renderer_lock);
return s;
}
void nv2a_release_framebuffer_surface(void)
{
NV2AState *d = g_nv2a;
PGRAPHState *pg = &d->pgraph;
qemu_mutex_lock(&pg->renderer_lock);
pg->framebuffer_in_use = false;
qemu_cond_broadcast(&pg->framebuffer_released);
qemu_mutex_unlock(&pg->renderer_lock);
}
void nv2a_set_surface_scale_factor(unsigned int scale)
{
NV2AState *d = g_nv2a;
qemu_mutex_unlock_iothread();
qemu_mutex_lock(&d->pgraph.renderer_lock);
if (d->pgraph.renderer->ops.set_surface_scale_factor) {
d->pgraph.renderer->ops.set_surface_scale_factor(d, scale);
}
qemu_mutex_unlock(&d->pgraph.renderer_lock);
qemu_mutex_lock_iothread();
}
unsigned int nv2a_get_surface_scale_factor(void)
@ -379,11 +395,13 @@ unsigned int nv2a_get_surface_scale_factor(void)
NV2AState *d = g_nv2a;
int s = 1;
qemu_mutex_unlock_iothread();
qemu_mutex_lock(&d->pgraph.renderer_lock);
if (d->pgraph.renderer->ops.get_surface_scale_factor) {
s = d->pgraph.renderer->ops.get_surface_scale_factor(d);
}
qemu_mutex_unlock(&d->pgraph.renderer_lock);
qemu_mutex_lock_iothread();
return s;
}
@ -2958,6 +2976,9 @@ void pgraph_process_pending(NV2AState *d)
qemu_mutex_unlock(&d->pfifo.lock);
qemu_mutex_lock(&d->pgraph.lock);
while (pg->framebuffer_in_use) {
qemu_cond_wait(&d->pgraph.framebuffer_released, &d->pgraph.renderer_lock);
}
if (pg->renderer->ops.finalize) {
pg->renderer->ops.finalize(d);

View File

@ -235,6 +235,9 @@ typedef struct PGRAPHState {
bool sync_pending;
QemuEvent sync_complete;
bool framebuffer_in_use;
QemuCond framebuffer_released;
unsigned int surface_scale_factor;
uint8_t *scale_buf;

View File

@ -36,8 +36,6 @@ void pgraph_vk_set_surface_scale_factor(NV2AState *d, unsigned int scale)
{
g_config.display.quality.surface_scale = scale < 1 ? 1 : scale;
qemu_mutex_unlock_iothread();
qemu_mutex_lock(&d->pfifo.lock);
qatomic_set(&d->pfifo.halt, true);
qemu_mutex_unlock(&d->pfifo.lock);
@ -65,8 +63,6 @@ void pgraph_vk_set_surface_scale_factor(NV2AState *d, unsigned int scale)
qatomic_set(&d->pfifo.halt, false);
pfifo_kick(d);
qemu_mutex_unlock(&d->pfifo.lock);
qemu_mutex_lock_iothread();
}
unsigned int pgraph_vk_get_surface_scale_factor(NV2AState *d)

View File

@ -1209,6 +1209,7 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl)
qemu_mutex_unlock_main_loop();
glFinish();
nv2a_release_framebuffer_surface();
SDL_GL_SwapWindow(scon->real_window);
/* VGA update (see note above) + vblank */