From 6546108f9689e771b91d5cdd6bd461b7dbd6bd50 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 28 Feb 2014 13:02:13 -0500 Subject: glamor: Extract the streamed vertex data code used by Render. (v2) We should be uploading any vertex data using this kind of upload style, since it saves a bunch of extra copies of our vertex data. Ported from Eric's glamor xserver tree. v2: fix composite_vbo_offset init in trapezoid rendering Signed-off-by: Alex Deucher --- src/Makefile.am | 1 + src/glamor.h | 1 + src/glamor_priv.h | 10 ++++++ src/glamor_render.c | 67 ++++++++-------------------------- src/glamor_trapezoid.c | 68 ++++++++++------------------------- src/glamor_vbo.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 141 insertions(+), 103 deletions(-) create mode 100644 src/glamor_vbo.c diff --git a/src/Makefile.am b/src/Makefile.am index 2fd521f..4f476d3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,7 @@ libglamor_la_SOURCES = \ glamor_pixmap.c\ glamor_largepixmap.c\ glamor_picture.c\ + glamor_vbo.c \ glamor_window.c\ glamor_gl_dispatch.c\ glamor_fbo.c\ diff --git a/src/glamor.h b/src/glamor.h index 1bb48ed..0172d57 100644 --- a/src/glamor.h +++ b/src/glamor.h @@ -315,6 +315,7 @@ extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap); extern _X_EXPORT int glamor_create_gc(GCPtr gc); extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable); + /* Glamor rendering/drawing functions with XXX_nf. * nf means no fallback within glamor internal if possible. If glamor * fail to accelerate the operation, glamor will return a false, and the diff --git a/src/glamor_priv.h b/src/glamor_priv.h index 8c118cb..35c6ce2 100644 --- a/src/glamor_priv.h +++ b/src/glamor_priv.h @@ -250,6 +250,7 @@ typedef struct glamor_screen_private { GLuint vbo, ebo; Bool vbo_mapped; int vbo_offset; + int composite_vbo_offset; int vbo_size; char *vb; int vb_stride; @@ -801,6 +802,15 @@ glamor_triangles(CARD8 op, void glamor_pixmap_init(ScreenPtr screen); void glamor_pixmap_fini(ScreenPtr screen); + +/* glamor_vbo.c */ + +void * +glamor_get_vbo_space(ScreenPtr screen, int size, char **vbo_offset); + +void +glamor_put_vbo_space(ScreenPtr screen); + /** * Download a pixmap's texture to cpu memory. If success, * One copy of current pixmap's texture will be put into diff --git a/src/glamor_render.c b/src/glamor_render.c index f7610bd..9bf1b07 100644 --- a/src/glamor_render.c +++ b/src/glamor_render.c @@ -726,6 +726,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) glamor_get_screen_private(screen); glamor_gl_dispatch *dispatch; int vert_size; + char *vbo_offset; glamor_priv->render_nr_verts = 0; glamor_priv->vb_stride = 2 * sizeof(float); @@ -737,46 +738,22 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) vert_size = n_verts * glamor_priv->vb_stride; 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->vbo_size < (glamor_priv->vbo_offset + vert_size)) { - glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * - glamor_priv->vb_stride; - glamor_priv->vbo_offset = 0; - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_size, - NULL, GL_STREAM_DRAW); - } - - glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - vert_size, - GL_MAP_WRITE_BIT | - GL_MAP_UNSYNCHRONIZED_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); - assert(glamor_priv->vb != NULL); - glamor_priv->vb -= glamor_priv->vbo_offset; - glamor_priv->vbo_mapped = TRUE; - } else - glamor_priv->vbo_offset = 0; + glamor_get_vbo_space(screen, vert_size, &vbo_offset); + glamor_priv->composite_vbo_offset = 0; dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long) - glamor_priv->vbo_offset)); + GL_FALSE, + glamor_priv->vb_stride, + vbo_offset); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); if (glamor_priv->has_source_coords) { dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, - (void *) ((long) - glamor_priv->vbo_offset - + - 2 * - sizeof(float))); + vbo_offset + 2 * sizeof(float)); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); } @@ -784,12 +761,8 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, - (void *) ((long) - glamor_priv->vbo_offset - + - (glamor_priv->has_source_coords - ? 4 : 2) * - sizeof(float))); + vbo_offset + (glamor_priv->has_source_coords ? + 4 : 2) * sizeof(float)); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); } glamor_put_dispatch(glamor_priv); @@ -803,7 +776,7 @@ glamor_emit_composite_vert(ScreenPtr screen, { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset); + float *vb = (float *) (glamor_priv->vb + glamor_priv->composite_vbo_offset); int j = 0; vb[j++] = dst_coords[i * 2 + 0]; @@ -818,7 +791,7 @@ glamor_emit_composite_vert(ScreenPtr screen, } glamor_priv->render_nr_verts++; - glamor_priv->vbo_offset += glamor_priv->vb_stride; + glamor_priv->composite_vbo_offset += glamor_priv->vb_stride; } @@ -831,18 +804,7 @@ glamor_flush_composite_rects(ScreenPtr screen) glamor_gl_dispatch *dispatch; dispatch = glamor_get_dispatch(glamor_priv); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - if (glamor_priv->vbo_mapped) { - dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); - glamor_priv->vbo_mapped = FALSE; - } - } else { - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - glamor_priv->vb, GL_DYNAMIC_DRAW); - } + glamor_put_vbo_space(screen); if (!glamor_priv->render_nr_verts) return; @@ -1400,8 +1362,7 @@ glamor_composite_with_shader(CARD8 op, DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n", x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height); - vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset); - assert(glamor_priv->vbo_offset < glamor_priv->vbo_size - glamor_priv->vb_stride); + vertices = (float *) (glamor_priv->vb + glamor_priv->composite_vbo_offset); glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale, dst_yscale, x_dest, y_dest, @@ -1427,7 +1388,7 @@ glamor_composite_with_shader(CARD8 op, glamor_priv->yInverted, vertices, vb_stride); } glamor_priv->render_nr_verts += 4; - glamor_priv->vbo_offset += glamor_priv->vb_stride * 4; + glamor_priv->composite_vbo_offset += glamor_priv->vb_stride * 4; rects++; } glamor_flush_composite_rects(screen); diff --git a/src/glamor_trapezoid.c b/src/glamor_trapezoid.c index e1ca252..cce7eb6 100644 --- a/src/glamor_trapezoid.c +++ b/src/glamor_trapezoid.c @@ -204,15 +204,7 @@ glamor_flush_composite_triangles(ScreenPtr screen) glamor_gl_dispatch *dispatch; dispatch = glamor_get_dispatch(glamor_priv); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); - else { - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - glamor_priv->vb, GL_DYNAMIC_DRAW); - } + glamor_put_vbo_space(screen); if (!glamor_priv->render_nr_verts) return; @@ -572,6 +564,7 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts) glamor_gl_dispatch *dispatch; int stride; int vert_size; + char *vbo_offset; glamor_priv->render_nr_verts = 0; @@ -600,58 +593,39 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts) dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) { - glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * - glamor_priv->vb_stride; - glamor_priv->vbo_offset = 0; - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_size, - NULL, GL_STREAM_DRAW); - } - - glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - vert_size, - GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); - - assert(glamor_priv->vb != NULL); - glamor_priv->vb -= glamor_priv->vbo_offset; - } else { - glamor_priv->vbo_offset = 0; - } + glamor_get_vbo_space(screen, vert_size, &vbo_offset); + glamor_priv->composite_vbo_offset = 0; dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); /* Set the vertex pointer. */ dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset)); + GL_FALSE, glamor_priv->vb_stride, + vbo_offset); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); stride = 2; dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); + GL_FALSE, glamor_priv->vb_stride, + vbo_offset + stride * sizeof(float)); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); stride += 2; dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); + GL_FALSE, glamor_priv->vb_stride, + vbo_offset + stride * sizeof(float)); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); stride += 2; dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); + GL_FALSE, glamor_priv->vb_stride, + vbo_offset + stride * sizeof(float)); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); stride += 4; dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); + GL_FALSE, glamor_priv->vb_stride, + vbo_offset + stride * sizeof(float)); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); glamor_put_dispatch(glamor_priv); @@ -1437,7 +1411,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, miTrapezoidBounds(1, ptrap, &one_trap_bound); - vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset) + 2; + vertices = (float*)(glamor_priv->vb + + glamor_priv->composite_vbo_offset) + 2; glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width), (pixmap_priv->base.pixmap->drawable.height), (one_trap_bound.x1), @@ -1519,7 +1494,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, right_slope); glamor_priv->render_nr_verts += 4; - glamor_priv->vbo_offset += glamor_priv->vb_stride * 4; + glamor_priv->composite_vbo_offset += glamor_priv->vb_stride * 4; } i += mrect; @@ -1528,14 +1503,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, if (!glamor_priv->render_nr_verts) continue; - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); - else { - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - glamor_priv->vb, GL_DYNAMIC_DRAW); - } + glamor_put_vbo_space(screen); #ifndef GLAMOR_GLES2 dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts, diff --git a/src/glamor_vbo.c b/src/glamor_vbo.c new file mode 100644 index 0000000..3689379 --- /dev/null +++ b/src/glamor_vbo.c @@ -0,0 +1,97 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * @file glamor_vbo.c + * + * Helpers for managing streamed vertex bufffers used in glamor. + */ + +#include "glamor_priv.h" + +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; + + 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->vbo_size < glamor_priv->vbo_offset + size) { + glamor_priv->vbo_size = MAX(65536, size); + glamor_priv->vbo_offset = 0; + dispatch->glBufferData(GL_ARRAY_BUFFER, + glamor_priv->vbo_size, NULL, GL_STREAM_DRAW); + } + + glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, + glamor_priv->vbo_offset, + size, + GL_MAP_WRITE_BIT | + GL_MAP_UNSYNCHRONIZED_BIT | + GL_MAP_INVALIDATE_RANGE_BIT); + assert(glamor_priv->vb != NULL); + *vbo_offset = (void *)(uintptr_t)glamor_priv->vbo_offset; + glamor_priv->vbo_mapped = TRUE; + } else { + /* Return a pointer to the statically allocated non-VBO + * memory. We'll upload it through glBufferData() later. + */ + if (glamor_priv->vbo_size < size) { + glamor_priv->vbo_size = size; + free(glamor_priv->vb); + glamor_priv->vb = XNFalloc(size); + } + *vbo_offset = NULL; + glamor_priv->vbo_offset = 0; + } + + glamor_put_dispatch(glamor_priv); + + return glamor_priv->vb; +} + +void +glamor_put_vbo_space(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; + + dispatch = glamor_get_dispatch(glamor_priv); + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + if (glamor_priv->vbo_mapped) { + dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); + glamor_priv->vbo_mapped = FALSE; + } + } else { + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, + glamor_priv->vb, GL_DYNAMIC_DRAW); + } + + glamor_put_dispatch(glamor_priv); +} -- cgit v1.2.3