diff options
author | Eric Anholt <eric@anholt.net> | 2014-06-05 17:38:22 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-06-09 13:50:13 -0400 |
commit | 387f6a6351855cc3f1b57582932608b7e7a96e9d (patch) | |
tree | 493c7cc6ce478bd67be25f68ff64c8fa187ab2a8 | |
parent | 0fe45a489b33ab72a1811dc8492eb41950ad7253 (diff) |
glamor: Use buffer_storage
29.5361% +/- 2.74092% improvement in x11perf -aa10text (n=489).
Pulled from Eric's xserver glamor tree.
v2: Fix fallback, return correct buffer offset, map whole buffer,
unmap conditionally.
v3: add conditional defines to make it compile with outdated headers.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | src/glamor.c | 2 | ||||
-rw-r--r-- | src/glamor_priv.h | 2 | ||||
-rw-r--r-- | src/glamor_vbo.c | 63 |
3 files changed, 66 insertions, 1 deletions
diff --git a/src/glamor.c b/src/glamor.c index 52e2f21..2567013 100644 --- a/src/glamor.c +++ b/src/glamor.c @@ -333,6 +333,8 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_gl_has_extension("GL_MESA_pack_invert"); glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit"); + glamor_priv->has_buffer_storage = + glamor_gl_has_extension("GL_ARB_buffer_storage"); glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); #ifdef MAX_FBO_SIZE diff --git a/src/glamor_priv.h b/src/glamor_priv.h index f7fdb88..4d75759 100644 --- a/src/glamor_priv.h +++ b/src/glamor_priv.h @@ -240,6 +240,7 @@ typedef struct glamor_screen_private { enum glamor_gl_flavor gl_flavor; int has_pack_invert; int has_fbo_blit; + int has_buffer_storage; int max_fbo_size; struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; @@ -256,6 +257,7 @@ typedef struct glamor_screen_private { int composite_vbo_offset; int vbo_size; char *vb; + char *vb_base; int vb_stride; Bool has_source_coords, has_mask_coords; int render_nr_verts; diff --git a/src/glamor_vbo.c b/src/glamor_vbo.c index 8b1d99a..2cabca1 100644 --- a/src/glamor_vbo.c +++ b/src/glamor_vbo.c @@ -29,17 +29,72 @@ #include "glamor_priv.h" +/* Allow compilation with outdated GL headers */ +#ifndef GL_MAP_PERSISTENT_BIT +# define GL_MAP_PERSISTENT_BIT 0x0040 +#endif +#ifndef GL_MAP_COHERENT_BIT +# define GL_MAP_COHERENT_BIT 0x0080 +#endif + void * glamor_get_vbo_space(ScreenPtr screen, int size, char **vbo_offset) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_gl_dispatch *dispatch; + int err = 0; dispatch = glamor_get_dispatch(glamor_priv); dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + if (glamor_priv->has_buffer_storage) { + if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) { + if (glamor_priv->vbo_mapped) + dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); + + if (size > glamor_priv->vbo_size) { + glamor_priv->vbo_size = MAX(65536, size); + + /* We aren't allowed to resize glBufferStorage() + * buffers, so we need to gen a new one. + */ + dispatch->glDeleteBuffers(1, &glamor_priv->vbo); + dispatch->glGenBuffers(1, &glamor_priv->vbo); + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + + assert(dispatch->glGetError() == GL_NO_ERROR); + dispatch->glBufferStorage(GL_ARRAY_BUFFER, glamor_priv->vbo_size, NULL, + GL_MAP_WRITE_BIT | + GL_MAP_PERSISTENT_BIT | + GL_MAP_COHERENT_BIT); + + err = dispatch->glGetError(); + if (err != GL_NO_ERROR) { + /* If the driver failed our coherent mapping, fall + * back to the ARB_mbr path. + */ + ErrorF("ARB_buffer_storage: falling back to MapBufferRange path!\n"); + glamor_priv->has_buffer_storage = FALSE; + glamor_priv->vbo_size = 0; + glamor_put_dispatch(glamor_priv); + return glamor_get_vbo_space(screen, size, vbo_offset); + } + } + + glamor_priv->vbo_offset = 0; + glamor_priv->vb_base = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, + 0, glamor_priv->vbo_size, + GL_MAP_WRITE_BIT | + GL_MAP_INVALIDATE_BUFFER_BIT | + GL_MAP_PERSISTENT_BIT | + GL_MAP_COHERENT_BIT); + } + glamor_priv->vb = glamor_priv->vb_base + glamor_priv->vbo_offset; + *vbo_offset = (void *)(uintptr_t)glamor_priv->vbo_offset; + glamor_priv->vbo_offset += size; + glamor_priv->vbo_mapped = TRUE; + } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) { glamor_priv->vbo_size = MAX(65536, size); glamor_priv->vbo_offset = 0; @@ -81,6 +136,12 @@ glamor_put_vbo_space(ScreenPtr screen) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_gl_dispatch *dispatch; + /* If we're in the ARB_buffer_storage path, we have a persistent + * mapping, so we can leave it around until we reach the end. + */ + if (glamor_priv->has_buffer_storage) + return; + dispatch = glamor_get_dispatch(glamor_priv); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { |