diff options
author | Marek Olšák <[email protected]> | 2010-05-16 18:43:44 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2010-05-16 19:31:23 +0200 |
commit | 0b94c05c2827336e2abf46629590edf05a6b3f64 (patch) | |
tree | 3f6730b3732406ba731f91a8991e40ce7699e1cf /src/gallium/drivers | |
parent | 581be86342858b0bbe22373f801235a1d3d792db (diff) |
r300g: implement flush+sync (AKA glFinish)
See comments in the code.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/r300/r300_flush.c | 36 |
1 files changed, 36 insertions, 0 deletions
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 <[email protected]> + * Copyright 2010 Marek Olšák <[email protected]> * * 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) |