diff options
author | Eric Anholt <eric@anholt.net> | 2017-07-26 16:54:40 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2017-10-13 17:23:46 -0700 |
commit | c66d65a645332bbf055a1c49f092636139eb9285 (patch) | |
tree | 8c2ee246d52eca34593ad905b0ae777de87770a7 | |
parent | 885636b7d42b3c7b151fc386d358184db004ce45 (diff) |
glamor: Use GL_MESA_tile_raster_order for overlapping blits.
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.c | 2 | ||||
-rw-r--r-- | glamor/glamor_copy.c | 74 | ||||
-rw-r--r-- | glamor/glamor_priv.h | 1 |
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; |