xf86-video-intel: 2 commits - src/sna/blt.c src/sna/compiler.h src/sna/sna_present.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Apr 5 17:09:43 UTC 2016


 src/sna/blt.c         |   42 ++++++++++++++++++++++++++----------------
 src/sna/compiler.h    |    5 +++++
 src/sna/sna_present.c |   14 ++++++++++++++
 3 files changed, 45 insertions(+), 16 deletions(-)

New commits:
commit 65dc4176d84e1d1764a6fa1edc972aa7f1dcd2ba
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 5 17:53:55 2016 +0100

    sna/present: Prevent reporting an incomplete event
    
    If we cancel a flip, we may try to restore the current mode and this may
    flush the partial flip (in a multi-monitor setup). We report the completed
    event back to present and free the event info. Then we report the error
    back to present, and free the event info a second time. Chaos and
    corruption ensues.
    
    Reported-and-tested-by: Christoph Haag <haagch at frickel.club>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94829
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index e08afe5..727fa87 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -45,6 +45,7 @@ struct sna_present_event {
 	uint64_t *event_id;
 	uint64_t target_msc;
 	int n_event_id;
+	bool queued;
 };
 
 static void sna_present_unflip(ScreenPtr screen, uint64_t event_id);
@@ -260,6 +261,7 @@ static bool sna_present_queue(struct sna_present_event *info,
 		if (!sna_fake_vblank(info))
 			return false;
 	} else {
+		info->queued = true;
 		if (info->target_msc - last_msc == 1) {
 			sna_crtc_set_vblank(info->crtc);
 			info->crtc = mark_crtc(info->crtc);
@@ -334,6 +336,11 @@ sna_present_vblank_handler(struct drm_event_vblank *event)
 	struct sna_present_event *info = to_present_event(event->user_data);
 	xf86CrtcPtr crtc = info->crtc;
 
+	if (!info->queued) {
+		DBG(("%s: arrived unexpectedly early (not queued)\n", __FUNCTION__));
+		return;
+	}
+
 	vblank_complete(info,
 			ust64(event->tv_sec, event->tv_usec),
 			sna_crtc_record_event(unmask_crtc(crtc), event));
@@ -406,6 +413,7 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
 	info->event_id[0] = event_id;
 	info->n_event_id = 1;
 	list_add_tail(&info->link, &tmp->link);
+	info->queued = false;
 
 	if (!sna_present_queue(info, swap->msc)) {
 		list_del(&info->link);
@@ -569,6 +577,10 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
 
 	DBG(("%s(sequence=%d): event=%lld\n", __FUNCTION__, event->sequence, (long long)info->event_id[0]));
 	assert(info->n_event_id == 1);
+	if (!info->queued) {
+		DBG(("%s: arrived unexpectedly early (not queued)\n", __FUNCTION__));
+		return;
+	}
 
 	if (info->crtc == NULL) {
 		swap.tv_sec = event->tv_sec;
@@ -621,6 +633,7 @@ flip(struct sna *sna,
 	info->event_id[0] = event_id;
 	info->n_event_id = 1;
 	info->target_msc = target_msc;
+	info->queued = false;
 
 	if (!sna_page_flip(sna, bo, present_flip_handler, info)) {
 		DBG(("%s: pageflip failed\n", __FUNCTION__));
@@ -628,6 +641,7 @@ flip(struct sna *sna,
 		return FALSE;
 	}
 
+	info->queued = true;
 	if (info->crtc)
 		sna_crtc_set_vblank(info->crtc);
 	return TRUE;
commit bb5194eebd72e828a46f504d91f1ecd5b5804f57
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 5 06:51:46 2016 +0100

    sna: Add alignment hints to tiled memcpy
    
    Telling the compiler the known alignment should improve the memcpy
    operation, but only has a small impact today (a few bytes/instructions
    per function).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/blt.c b/src/sna/blt.c
index 2dae9c2..39e4149 100644
--- a/src/sna/blt.c
+++ b/src/sna/blt.c
@@ -258,7 +258,8 @@ memcpy_to_tiled_x__swizzle_0(const void *src, void *dst, int bpp,
 			if (dst_x & tile_mask) {
 				const unsigned x = (dst_x & tile_mask) * cpp;
 				const unsigned len = min(tile_width - x, w);
-				memcpy(tile_row + x, src, len);
+				memcpy(assume_misaligned(tile_row + x, tile_width, x),
+				       src, len);
 
 				tile_row += tile_size;
 				src = (const uint8_t *)src + len;
@@ -266,13 +267,14 @@ memcpy_to_tiled_x__swizzle_0(const void *src, void *dst, int bpp,
 			}
 		}
 		while (w >= tile_width) {
-			memcpy(tile_row, src, tile_width);
+			memcpy(assume_aligned(tile_row, tile_width),
+			       src, tile_width);
 
 			tile_row += tile_size;
 			src = (const uint8_t *)src + tile_width;
 			w -= tile_width;
 		}
-		memcpy(tile_row, src, w);
+		memcpy(assume_aligned(tile_row, tile_width), src, w);
 		src = (const uint8_t *)src + src_stride + w;
 		dst_y++;
 	}
@@ -314,7 +316,9 @@ memcpy_from_tiled_x__swizzle_0(const void *src, void *dst, int bpp,
 			if (src_x & tile_mask) {
 				const unsigned x = (src_x & tile_mask) * cpp;
 				const unsigned len = min(tile_width - x, w);
-				memcpy(dst, tile_row + x, len);
+				memcpy(dst,
+				       assume_misaligned(tile_row, tile_width, x),
+				       len);
 
 				tile_row += tile_size;
 				dst = (uint8_t *)dst + len;
@@ -322,13 +326,15 @@ memcpy_from_tiled_x__swizzle_0(const void *src, void *dst, int bpp,
 			}
 		}
 		while (w >= tile_width) {
-			memcpy(dst, tile_row, tile_width);
+			memcpy(dst,
+			       assume_aligned(tile_row, tile_width),
+			       tile_width);
 
 			tile_row += tile_size;
 			dst = (uint8_t *)dst + tile_width;
 			w -= tile_width;
 		}
-		memcpy(dst, tile_row, w);
+		memcpy(dst, assume_aligned(tile_row, tile_width), w);
 		dst = (uint8_t *)dst + dst_stride + w;
 		src_y++;
 	}
@@ -379,7 +385,8 @@ memcpy_to_tiled_x__##swizzle (const void *src, void *dst, int bpp, \
 				tile_row + \
 				(dx >> tile_pixels) * tile_size + \
 				(dx & tile_mask) * cpp; \
-			memcpy((char *)dst + swizzle(offset), src_row, 64); \
+			memcpy(assume_aligned((char *)dst+swizzle(offset),64), \
+			       src_row, 64); \
 			src_row += 64; \
 			x -= 64; \
 			dx += swizzle_pixels; \
@@ -389,7 +396,7 @@ memcpy_to_tiled_x__##swizzle (const void *src, void *dst, int bpp, \
 				tile_row + \
 				(dx >> tile_pixels) * tile_size + \
 				(dx & tile_mask) * cpp; \
-			memcpy((char *)dst + swizzle(offset), src_row, x); \
+			memcpy(assume_aligned((char *)dst + swizzle(offset), 64), src_row, x); \
 		} \
 	} \
 }
@@ -439,7 +446,7 @@ memcpy_from_tiled_x__##swizzle (const void *src, void *dst, int bpp, \
 				tile_row + \
 				(sx >> tile_pixels) * tile_size + \
 				(sx & tile_mask) * cpp; \
-			memcpy(dst_row, (const char *)src + swizzle(offset), 64); \
+			memcpy(dst_row, assume_aligned((const char *)src + swizzle(offset), 64), 64); \
 			dst_row += 64; \
 			x -= 64; \
 			sx += swizzle_pixels; \
@@ -449,7 +456,7 @@ memcpy_from_tiled_x__##swizzle (const void *src, void *dst, int bpp, \
 				tile_row + \
 				(sx >> tile_pixels) * tile_size + \
 				(sx & tile_mask) * cpp; \
-			memcpy(dst_row, (const char *)src + swizzle(offset), x); \
+			memcpy(dst_row, assume_aligned((const char *)src + swizzle(offset), 64), x); \
 		} \
 	} \
 }
@@ -510,7 +517,7 @@ memcpy_to_tiled_x__gen2(const void *src, void *dst, int bpp,
 			if (dst_x & tile_mask) {
 				const unsigned x = (dst_x & tile_mask) * cpp;
 				const unsigned len = min(tile_width - x, w);
-				memcpy(tile_row + x, src, len);
+				memcpy(assume_misaligned(tile_row + x, tile_width, x), src, len);
 
 				tile_row += tile_size;
 				src = (const uint8_t *)src + len;
@@ -518,13 +525,14 @@ memcpy_to_tiled_x__gen2(const void *src, void *dst, int bpp,
 			}
 		}
 		while (w >= tile_width) {
-			memcpy(tile_row, src, tile_width);
+			memcpy(assume_aligned(tile_row, tile_width),
+			       src, tile_width);
 
 			tile_row += tile_size;
 			src = (const uint8_t *)src + tile_width;
 			w -= tile_width;
 		}
-		memcpy(tile_row, src, w);
+		memcpy(assume_aligned(tile_row, tile_width), src, w);
 		src = (const uint8_t *)src + src_stride + w;
 		dst_y++;
 	}
@@ -566,7 +574,7 @@ memcpy_from_tiled_x__gen2(const void *src, void *dst, int bpp,
 			if (src_x & tile_mask) {
 				const unsigned x = (src_x & tile_mask) * cpp;
 				const unsigned len = min(tile_width - x, w);
-				memcpy(dst, tile_row + x, len);
+				memcpy(dst, assume_misaligned(tile_row + x, tile_width, x), len);
 
 				tile_row += tile_size;
 				dst = (uint8_t *)dst + len;
@@ -574,13 +582,15 @@ memcpy_from_tiled_x__gen2(const void *src, void *dst, int bpp,
 			}
 		}
 		while (w >= tile_width) {
-			memcpy(dst, tile_row, tile_width);
+			memcpy(dst,
+			       assume_aligned(tile_row, tile_width),
+			       tile_width);
 
 			tile_row += tile_size;
 			dst = (uint8_t *)dst + tile_width;
 			w -= tile_width;
 		}
-		memcpy(dst, tile_row, w);
+		memcpy(dst, assume_aligned(tile_row, tile_width), w);
 		dst = (uint8_t *)dst + dst_stride + w;
 		src_y++;
 	}
diff --git a/src/sna/compiler.h b/src/sna/compiler.h
index c723137..a1634b3 100644
--- a/src/sna/compiler.h
+++ b/src/sna/compiler.h
@@ -71,6 +71,11 @@
 
 #if HAS_GCC(4, 7)
 #define avx2 fast __attribute__((target("avx2,avx,sse4.2,sse2,fpmath=sse")))
+#define assume_aligned(ptr, align) __builtin_assume_aligned((ptr), (align))
+#define assume_misaligned(ptr, align, offset) __builtin_assume_aligned((ptr), (align), (offset))
+#else
+#define assume_aligned(ptr, align) (ptr)
+#define assume_misaligned(ptr, align, offset) (ptr)
 #endif
 
 #if HAS_GCC(4, 5) && defined(__OPTIMIZE__)


More information about the xorg-commit mailing list