diff options
author | Keith Whitwell <[email protected]> | 2010-08-22 14:14:55 +0100 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2010-08-22 14:49:17 +0100 |
commit | 42719df0b866a00ea4a7739e82e1639c9943fcfd (patch) | |
tree | 96a1256b9475146a2a5ba2d9db43afc95340a0eb /src/gallium/state_trackers | |
parent | 3d4b60f1f7be3dc54951c9c414601062e73ca674 (diff) |
glx/xlib: configurable strict/non-strict buffer size invalidate
Introduce a new configuration option XMESA_STRICT_INVALIDATE to switch
between swapbuffers-based and glViewport-based buffer invalidation.
Default strict invalidate to false, ie glViewport-based invalidation,
aka ST_MANAGER_BROKEN_INVALIDATE.
This means we will not call XGetGeometry after every swapbuffers,
which allows swapbuffers to remain asynchronous. For apps running at
100fps with synchronous swapping, a 10% boost is typical. For gears,
I see closer to 20% speedup.
Note that the work of copying data on swapbuffers doesn't disappear -
this change just allows the X server to execute the PutImage
asynchronously without us effectively blocked until its completion.
This applies even to llvmpipe's threaded rasterization as the
swapbuffers operation was a large part of the serial component of an
llvmpipe frame.
The downside of this is correctness - applications which don't call
glViewport on window resizes will get incorrect rendering, unless
XMESA_STRICT_INVALIDATE is set.
The ultimate solution would be to have per-frame but asynchronous
invalidation. Xcb almost looks as if it could provide this, but the
API doesn't seem to quite be there.
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_api.c | 32 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_api.h | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_st.c | 12 |
3 files changed, 42 insertions, 4 deletions
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index 2fc400b3fcc..894ed548ee2 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -72,10 +72,35 @@ static struct xm_driver driver; static struct st_api *stapi; +/* Default strict invalidate to false. This means we will not call + * XGetGeometry after every swapbuffers, which allows swapbuffers to + * remain asynchronous. For apps running at 100fps with synchronous + * swapping, a 10% boost is typical. For gears, I see closer to 20% + * speedup. + * + * Note that the work of copying data on swapbuffers doesn't disappear + * - this change just allows the X server to execute the PutImage + * asynchronously without us effectively blocked until its completion. + * + * This speeds up even llvmpipe's threaded rasterization as the + * swapbuffers operation was a large part of the serial component of + * an llvmpipe frame. + * + * The downside of this is correctness - applications which don't call + * glViewport on window resizes will get incorrect rendering. A + * better solution would be to have per-frame but asynchronous + * invalidation. Xcb almost looks as if it could provide this, but + * the API doesn't seem to quite be there. + */ +boolean xmesa_strict_invalidate = FALSE; + void xmesa_set_driver( const struct xm_driver *templ ) { driver = *templ; stapi = driver.create_st_api(); + + xmesa_strict_invalidate = + debug_get_bool_option("XMESA_STRICT_INVALIDATE", FALSE); } @@ -91,7 +116,12 @@ static int xmesa_get_param(struct st_manager *smapi, enum st_manager_param param) { - return 0; + switch(param) { + case ST_MANAGER_BROKEN_INVALIDATE: + return !xmesa_strict_invalidate; + default: + return 0; + } } static XMesaDisplay diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h index 4f2c8a6e6a9..934c7494503 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.h +++ b/src/gallium/state_trackers/glx/xlib/xm_api.h @@ -378,6 +378,6 @@ xmesa_buffer_height(XMesaBuffer b) return b->height; } - +extern boolean xmesa_strict_invalidate; #endif diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c index 9cd744c3a63..873d5b66031 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_st.c +++ b/src/gallium/state_trackers/glx/xlib/xm_st.c @@ -211,6 +211,12 @@ xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, /* record newly allocated textures */ new_mask = statt_mask & ~xstfb->texture_mask; + /* If xmesa_strict_invalidate is not set, we will not yet have + * called XGetGeometry(). Do so here: + */ + if (!xmesa_strict_invalidate) + xmesa_check_buffer_size(xstfb->buffer); + resized = (xstfb->buffer->width != xstfb->texture_width || xstfb->buffer->height != xstfb->texture_height); @@ -252,7 +258,8 @@ xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, boolean ret; ret = xmesa_st_framebuffer_display(stfbi, statt); - if (ret) + + if (ret && xmesa_strict_invalidate) xmesa_check_buffer_size(xstfb->buffer); return ret; @@ -327,7 +334,8 @@ xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi) *back = tmp; } - xmesa_check_buffer_size(xstfb->buffer); + if (xmesa_strict_invalidate) + xmesa_check_buffer_size(xstfb->buffer); } } |