summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2014-06-05 17:38:22 +0200
committerAlex Deucher <alexander.deucher@amd.com>2014-06-09 13:50:13 -0400
commit387f6a6351855cc3f1b57582932608b7e7a96e9d (patch)
tree493c7cc6ce478bd67be25f68ff64c8fa187ab2a8
parent0fe45a489b33ab72a1811dc8492eb41950ad7253 (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.c2
-rw-r--r--src/glamor_priv.h2
-rw-r--r--src/glamor_vbo.c63
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) {