summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2014-02-28 13:02:13 -0500
committerZhigang Gong <zhigang.gong@gmail.com>2014-03-13 21:52:25 +0800
commit6546108f9689e771b91d5cdd6bd461b7dbd6bd50 (patch)
tree3c684a68a1ee74397deb0c29c79ead6fe5e851b2
parent1bed3cc8ce8b0b24c37daa79b375ba2cf94ef008 (diff)
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 <alexander.deucher@amd.com>
-rw-r--r--src/Makefile.am1
-rw-r--r--src/glamor.h1
-rw-r--r--src/glamor_priv.h10
-rw-r--r--src/glamor_render.c67
-rw-r--r--src/glamor_trapezoid.c68
-rw-r--r--src/glamor_vbo.c97
6 files changed, 141 insertions, 103 deletions
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);
+}