summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-05-16 18:43:44 +0200
committerMarek Olšák <[email protected]>2010-05-16 19:31:23 +0200
commit0b94c05c2827336e2abf46629590edf05a6b3f64 (patch)
tree3f6730b3732406ba731f91a8991e40ce7699e1cf /src/gallium/drivers/r300
parent581be86342858b0bbe22373f801235a1d3d792db (diff)
r300g: implement flush+sync (AKA glFinish)
See comments in the code.
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_flush.c36
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)