From: Marek Olšák Date: Sun, 16 May 2010 16:43:44 +0000 (+0200) Subject: r300g: implement flush+sync (AKA glFinish) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0b94c05c2827336e2abf46629590edf05a6b3f64;p=mesa.git r300g: implement flush+sync (AKA glFinish) See comments in the code. --- diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index 3d22027136b..d6876c1903f 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson + * Copyright 2010 Marek Olšák * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -37,6 +38,8 @@ static void r300_flush(struct pipe_context* pipe, struct r300_context *r300 = r300_context(pipe); struct r300_query *query; struct r300_atom *atom; + struct pipe_framebuffer_state *fb; + unsigned i; CS_LOCALS(r300); (void) cs_count; @@ -72,6 +75,39 @@ static void r300_flush(struct pipe_context* pipe, foreach(query, &r300->query_list) { query->flushed = TRUE; } + + /* XXX + * + * This is a preliminary implementation of glFinish. Note that st/mesa + * uses a non-null fence when glFinish is called and then waits for + * the fence. Instead of returning the actual fence, we do the sync + * directly. + * + * The ideal implementation should use something like EmitIrqLocked and + * WaitIrq, or better, real fences. + * + * This feature degrades performance to the level of r300c for games that + * use glFinish a lot, even openarena does. Ideally we wouldn't need + * glFinish at all if we had proper throttling in swapbuffers so that + * the CPU wouldn't outrun the GPU by several frames, so this is basically + * a temporary fix for the input lag. Once swap&sync works with DRI2, + * I'll be happy to remove this code. + * + * - M. */ + if (fence && r300->fb_state.state) { + fb = r300->fb_state.state; + + for (i = 0; i < fb->nr_cbufs; i++) { + if (fb->cbufs[i]->texture) { + r300->rws->buffer_wait(r300->rws, + r300_texture(fb->cbufs[i]->texture)->buffer); + } + if (fb->zsbuf) { + r300->rws->buffer_wait(r300->rws, + r300_texture(fb->zsbuf->texture)->buffer); + } + } + } } void r300_init_flush_functions(struct r300_context* r300)