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>
This commit is contained in:
Eric Anholt 2017-07-26 16:54:40 -07:00
parent 885636b7d4
commit c66d65a645
3 changed files with 51 additions and 24 deletions

View File

@ -601,6 +601,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
epoxy_has_gl_extension("GL_EXT_map_buffer_range"); epoxy_has_gl_extension("GL_EXT_map_buffer_range");
glamor_priv->has_buffer_storage = glamor_priv->has_buffer_storage =
epoxy_has_gl_extension("GL_ARB_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 = glamor_priv->has_nv_texture_barrier =
epoxy_has_gl_extension("GL_NV_texture_barrier"); epoxy_has_gl_extension("GL_NV_texture_barrier");
glamor_priv->has_unpack_subimage = glamor_priv->has_unpack_subimage =

View File

@ -317,6 +317,13 @@ bail:
return FALSE; 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 * Copy from GPU to GPU by using the source
* as a texture and painting that into the destination * 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); 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); glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
2 * sizeof (GLshort), vbo_offset); 2 * sizeof (GLshort), vbo_offset);
@ -451,6 +470,9 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
ret = TRUE; ret = TRUE;
bail_ctx: 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); glDisable(GL_SCISSOR_TEST);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
@ -611,34 +633,36 @@ glamor_copy_needs_temp(DrawablePtr src,
if (!glamor_priv->has_nv_texture_barrier) if (!glamor_priv->has_nv_texture_barrier)
return TRUE; return TRUE;
glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y); if (!glamor_priv->has_mesa_tile_raster_order) {
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y); 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]; bounds = box[0];
for (n = 1; n < nbox; n++) { for (n = 1; n < nbox; n++) {
bounds.x1 = min(bounds.x1, box[n].x1); bounds.x1 = min(bounds.x1, box[n].x1);
bounds.y1 = min(bounds.y1, box[n].y1); bounds.y1 = min(bounds.y1, box[n].y1);
bounds.x2 = max(bounds.x2, box[n].x2); bounds.x2 = max(bounds.x2, box[n].x2);
bounds.y2 = max(bounds.y2, box[n].y2); bounds.y2 = max(bounds.y2, box[n].y2);
} }
/* Check to see if the pixmap-relative boxes overlap in both X and Y, /* 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 * in which case we can't rely on NV_texture_barrier and must
* make a temporary copy * make a temporary copy
* *
* dst.x1 < src.x2 && * dst.x1 < src.x2 &&
* src.x1 < dst.x2 && * src.x1 < dst.x2 &&
* *
* dst.y1 < src.y2 && * dst.y1 < src.y2 &&
* src.y1 < dst.y2 * src.y1 < dst.y2
*/ */
if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x && if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x &&
bounds.x1 + dx + src_off_x < bounds.x2 + dst_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 + dst_off_y < bounds.y2 + dy + src_off_y &&
bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) { bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) {
return TRUE; return TRUE;
}
} }
glTextureBarrierNV(); glTextureBarrierNV();

View File

@ -192,6 +192,7 @@ typedef struct glamor_screen_private {
Bool has_map_buffer_range; Bool has_map_buffer_range;
Bool has_buffer_storage; Bool has_buffer_storage;
Bool has_khr_debug; Bool has_khr_debug;
Bool has_mesa_tile_raster_order;
Bool has_nv_texture_barrier; Bool has_nv_texture_barrier;
Bool has_pack_subimage; Bool has_pack_subimage;
Bool has_unpack_subimage; Bool has_unpack_subimage;