summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2016-06-14 20:03:53 +0200
committerNicolai Hähnle <[email protected]>2016-06-22 11:44:03 +0200
commit3948cd37973696dc319170877382676809659465 (patch)
treea3183b910425b46e24dd1ae475045f0ebeea2774
parent36ed1b695e5a0ae5714b79cae3a089b5e7e8bd29 (diff)
st/mesa: use a single memcpy in st_ReadPixels when possible
This avoids costly address recomputations, function overhead, and may trigger large copy optimizations. Reviewed-by: Brian Paul <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 39d2274b3b4..77c63323295 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -520,14 +520,21 @@ st_ReadPixels(struct gl_context *ctx, GLint x, GLint y,
/* memcpy data into a user buffer */
{
const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
- GLuint row;
-
- for (row = 0; row < (unsigned) height; row++) {
- void *dest = _mesa_image_address2d(pack, pixels,
- width, height, format,
- type, row, 0);
- memcpy(dest, map, bytesPerRow);
- map += tex_xfer->stride;
+ const uint destStride = _mesa_image_row_stride(pack, width, format, type);
+ char *dest = _mesa_image_address2d(pack, pixels,
+ width, height, format,
+ type, 0, 0);
+
+ if (tex_xfer->stride == bytesPerRow && destStride == bytesPerRow) {
+ memcpy(dest, map, bytesPerRow * height);
+ } else {
+ GLuint row;
+
+ for (row = 0; row < (unsigned) height; row++) {
+ memcpy(dest, map, bytesPerRow);
+ map += tex_xfer->stride;
+ dest += destStride;
+ }
}
}