summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2017-07-26 16:54:40 -0700
committerAdam Jackson <ajax@redhat.com>2017-10-26 13:39:19 -0400
commit4510909db39302512a4b0bd33f7e325d32462f1b (patch)
tree422ab07e2fa20cb8e520a5eccef94b6b315401c3
parent5cb97c31232794120c1a105e2a4e173151b31fcd (diff)
glamor: Use GL_MESA_tile_raster_order for overlapping blits.glamor-did-not-regress
Improves Raspberry Pi 3 x11perf -copywinwin500 from ~480/sec to ~700/sec. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Keith Packard <keithp@keithp.com>
-rw-r--r--glamor/glamor.c2
-rw-r--r--glamor/glamor_copy.c74
-rw-r--r--glamor/glamor_priv.h1
3 files changed, 52 insertions, 25 deletions
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 91236e29c..d06934595 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -601,6 +601,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
epoxy_has_gl_extension("GL_EXT_map_buffer_range");
glamor_priv->has_buffer_storage =
epoxy_has_gl_extension("GL_ARB_buffer_storage");
+ glamor_priv->has_mesa_tile_raster_order =
+ epoxy_has_gl_extension("GL_MESA_tile_raster_order");
glamor_priv->has_nv_texture_barrier =
epoxy_has_gl_extension("GL_NV_texture_barrier");
glamor_priv->has_unpack_subimage =
diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index cbaf06ddd..bd4a0e20f 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -317,6 +317,13 @@ bail:
return FALSE;
}
+/* Include the enums here for the moment, to keep from needing to bump epoxy. */
+#ifndef GL_TILE_RASTER_ORDER_FIXED_MESA
+#define GL_TILE_RASTER_ORDER_FIXED_MESA 0x8BB8
+#define GL_TILE_RASTER_ORDER_INCREASING_X_MESA 0x8BB9
+#define GL_TILE_RASTER_ORDER_INCREASING_Y_MESA 0x8BBA
+#endif
+
/*
* Copy from GPU to GPU by using the source
* as a texture and painting that into the destination
@@ -388,6 +395,18 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
v = glamor_get_vbo_space(dst->pScreen, nbox * 8 * sizeof (int16_t), &vbo_offset);
+ if (src_pixmap == dst_pixmap && glamor_priv->has_mesa_tile_raster_order) {
+ glEnable(GL_TILE_RASTER_ORDER_FIXED_MESA);
+ if (dx >= 0)
+ glEnable(GL_TILE_RASTER_ORDER_INCREASING_X_MESA);
+ else
+ glDisable(GL_TILE_RASTER_ORDER_INCREASING_X_MESA);
+ if (dy >= 0)
+ glEnable(GL_TILE_RASTER_ORDER_INCREASING_Y_MESA);
+ else
+ glDisable(GL_TILE_RASTER_ORDER_INCREASING_Y_MESA);
+ }
+
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
2 * sizeof (GLshort), vbo_offset);
@@ -451,6 +470,9 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
ret = TRUE;
bail_ctx:
+ if (src_pixmap == dst_pixmap && glamor_priv->has_mesa_tile_raster_order) {
+ glDisable(GL_TILE_RASTER_ORDER_FIXED_MESA);
+ }
glDisable(GL_SCISSOR_TEST);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -611,34 +633,36 @@ glamor_copy_needs_temp(DrawablePtr src,
if (!glamor_priv->has_nv_texture_barrier)
return TRUE;
- glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
- glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y);
-
- bounds = box[0];
- for (n = 1; n < nbox; n++) {
- bounds.x1 = min(bounds.x1, box[n].x1);
- bounds.y1 = min(bounds.y1, box[n].y1);
+ if (!glamor_priv->has_mesa_tile_raster_order) {
+ glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
+ glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y);
- bounds.x2 = max(bounds.x2, box[n].x2);
- bounds.y2 = max(bounds.y2, box[n].y2);
- }
+ bounds = box[0];
+ for (n = 1; n < nbox; n++) {
+ bounds.x1 = min(bounds.x1, box[n].x1);
+ bounds.y1 = min(bounds.y1, box[n].y1);
- /* Check to see if the pixmap-relative boxes overlap in both X and Y,
- * in which case we can't rely on NV_texture_barrier and must
- * make a temporary copy
- *
- * dst.x1 < src.x2 &&
- * src.x1 < dst.x2 &&
- *
- * dst.y1 < src.y2 &&
- * src.y1 < dst.y2
- */
- if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x &&
- bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x &&
+ bounds.x2 = max(bounds.x2, box[n].x2);
+ bounds.y2 = max(bounds.y2, box[n].y2);
+ }
- bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y &&
- bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) {
- return TRUE;
+ /* Check to see if the pixmap-relative boxes overlap in both X and Y,
+ * in which case we can't rely on NV_texture_barrier and must
+ * make a temporary copy
+ *
+ * dst.x1 < src.x2 &&
+ * src.x1 < dst.x2 &&
+ *
+ * dst.y1 < src.y2 &&
+ * src.y1 < dst.y2
+ */
+ if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x &&
+ bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x &&
+
+ bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y &&
+ bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) {
+ return TRUE;
+ }
}
glTextureBarrierNV();
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 07a98efeb..7050df526 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -192,6 +192,7 @@ typedef struct glamor_screen_private {
Bool has_map_buffer_range;
Bool has_buffer_storage;
Bool has_khr_debug;
+ Bool has_mesa_tile_raster_order;
Bool has_nv_texture_barrier;
Bool has_pack_subimage;
Bool has_unpack_subimage;