xf86-video-intel: 3 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_display_fake.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Fri Jul 12 05:17:14 PDT 2013


 src/sna/kgem.c             |   65 +++++++++++++++++----------
 src/sna/sna.h              |    2 
 src/sna/sna_accel.c        |  108 ++++++++++++++++++++++++++++++++++++++++++---
 src/sna/sna_display.c      |   59 ------------------------
 src/sna/sna_display_fake.c |   59 ------------------------
 src/sna/sna_driver.c       |    2 
 6 files changed, 145 insertions(+), 150 deletions(-)

New commits:
commit 39f1954f667bf20cd0c25dfa5fb5267a3f9eb113
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 11 21:57:02 2013 +0100

    sna: Replace parsing of /proc/cpuinfo with parsing of cpuid
    
    Courtesy of a patch from Chad Versace via Ben Widawsky, actually digging
    through CPUID for the cache info looks quite easy in comparison to the
    fragile approach of parsing a linux specific file that may or may not be
    available.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 7091ca4..13b509b 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -38,6 +38,7 @@
 #include <time.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <cpuid.h>
 
 #include <xf86drm.h>
 
@@ -696,29 +697,47 @@ total_ram_size(void)
 	return 0;
 }
 
-static size_t
+static unsigned
 cpu_cache_size(void)
 {
-	FILE *file = fopen("/proc/cpuinfo", "r");
-	size_t size = -1;
-	if (file) {
-		size_t len = 0;
-		char *line = NULL;
-		while (getline(&line, &len, file) != -1) {
-			int mb;
-			if (sscanf(line, "cache size : %d KB", &mb) == 1) {
-				/* Paranoid check against gargantuan caches */
-				if (mb <= 1<<20)
-					size = mb * 1024;
-				break;
-			}
-		}
-		free(line);
-		fclose(file);
-	}
-	if (size == -1)
-		ErrorF("Unknown CPU cache size\n");
-	return size;
+	/* Deterministic Cache Parmaeters (Function 04h)":
+	 *    When EAX is initialized to a value of 4, the CPUID instruction
+	 *    returns deterministic cache information in the EAX, EBX, ECX
+	 *    and EDX registers.  This function requires ECX be initialized
+	 *    with an index which indicates which cache to return information
+	 *    about. The OS is expected to call this function (CPUID.4) with
+	 *    ECX = 0, 1, 2, until EAX[4:0] == 0, indicating no more caches.
+	 *    The order in which the caches are returned is not specified
+	 *    and may change at Intel's discretion.
+	 *
+	 * Calculating the Cache Size in bytes:
+	 *          = (Ways +1) * (Partitions +1) * (Line Size +1) * (Sets +1)
+	 */
+
+	 unsigned int eax, ebx, ecx, edx;
+	 unsigned int llc_size = 0;
+	 int cnt = 0;
+
+	 if (__get_cpuid_max(false, 0) < 4)
+		 return 0;
+
+	 do {
+		 unsigned associativity, line_partitions, line_size, sets;
+
+		 __cpuid_count(4, cnt++, eax, ebx, ecx, edx);
+
+		 if ((eax & 0x1f) == 0)
+			 break;
+
+		 associativity = ((ebx >> 22) & 0x3ff) + 1;
+		 line_partitions = ((ebx >> 12) & 0x3ff) + 1;
+		 line_size = (ebx & 0xfff) + 1;
+		 sets = ecx + 1;
+
+		 llc_size = associativity * line_partitions * line_size * sets;
+	 } while (1);
+
+	 return llc_size;
 }
 
 static int gem_param(struct kgem *kgem, int name)
@@ -1177,8 +1196,8 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
 		kgem->min_alignment = 64;
 
 	kgem->half_cpu_cache_pages = cpu_cache_size() >> 13;
-	DBG(("%s: half cpu cache %d pages\n", __FUNCTION__,
-	     kgem->half_cpu_cache_pages));
+	DBG(("%s: last-level cache size: %d bytes, threshold in pages: %d\n",
+	     __FUNCTION__, cpu_cache_size(), kgem->half_cpu_cache_pages));
 
 	kgem->next_request = __kgem_request_alloc(kgem);
 
commit c604d1426cc11f9799044710acf1ef7d226d2604
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 11 16:40:51 2013 +0100

    sna: Remove the duplicated open-coding of SetScreenPixmap
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 17cae7e..249d57c 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -149,7 +149,7 @@ struct sna_glyph {
 	uint16_t size, pos;
 };
 
-static inline WindowPtr root(ScreenPtr screen)
+static inline WindowPtr get_root_window(ScreenPtr screen)
 {
 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0)
 	return screen->root;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 50aa48e..2eb1699 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -15062,6 +15062,77 @@ sna_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
 	*(PixmapPtr *)__get_private(window, sna_window_key) = pixmap;
 }
 
+struct sna_visit_set_pixmap_window {
+	PixmapPtr old, new;
+};
+
+static int
+sna_visit_set_window_pixmap(WindowPtr window, pointer data)
+{
+    struct sna_visit_set_pixmap_window *visit = data;
+
+    if (fbGetWindowPixmap(window) == visit->old) {
+	    window->drawable.pScreen->SetWindowPixmap(window, visit->new);
+	    return WT_WALKCHILDREN;
+    }
+
+    return WT_DONTWALKCHILDREN;
+}
+
+static void
+migrate_dirty_tracking(PixmapPtr old_front, PixmapPtr new_front)
+{
+#if HAS_PIXMAP_SHARING
+	ScreenPtr screen = old_front->drawable.pScreen;
+	PixmapDirtyUpdatePtr dirty, safe;
+
+	xorg_list_for_each_entry_safe(dirty, safe, &screen->pixmap_dirty_list, ent) {
+		assert(dirty->src == old_front);
+		if (dirty->src != old_front)
+			continue;
+
+		DamageUnregister(&dirty->src->drawable, dirty->damage);
+		DamageDestroy(dirty->damage);
+
+		dirty->damage = DamageCreate(NULL, NULL,
+					     DamageReportNone,
+					     TRUE, screen, screen);
+		if (!dirty->damage) {
+			xorg_list_del(&dirty->ent);
+			free(dirty);
+			continue;
+		}
+
+		DamageRegister(&new_front->drawable, dirty->damage);
+		dirty->src = new_front;
+	}
+#endif
+}
+
+static void
+sna_set_screen_pixmap(PixmapPtr pixmap)
+{
+	PixmapPtr old_front = pixmap->drawable.pScreen->devPrivate;
+	WindowPtr root;
+
+	assert(pixmap == to_sna_from_pixmap(pixmap)->front);
+
+	if (old_front)
+		migrate_dirty_tracking(old_front, pixmap);
+
+	root = get_root_window(pixmap->drawable.pScreen);
+	if (root) {
+		struct sna_visit_set_pixmap_window visit;
+
+		visit.old = old_front;
+		visit.new = pixmap;
+		TraverseTree(root, sna_visit_set_window_pixmap, &visit);
+		assert(fbGetWindowPixmap(root) == pixmap);
+	}
+
+	pixmap->drawable.pScreen->devPrivate = pixmap;
+}
+
 static Bool
 sna_create_window(WindowPtr win)
 {
@@ -15236,6 +15307,8 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 	assert(screen->SetWindowPixmap == NULL);
 	screen->SetWindowPixmap = sna_set_window_pixmap;
 
+	screen->SetScreenPixmap = sna_set_screen_pixmap;
+
 	if (sna->kgem.has_userptr)
 		ShmRegisterFuncs(screen, &shm_funcs);
 	else
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e1fc6fc..1427cd6 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2610,24 +2610,6 @@ sna_mode_compute_possible_clones(ScrnInfoPtr scrn)
 	}
 }
 
-struct sna_visit_set_pixmap_window {
-	PixmapPtr old, new;
-};
-
-static int
-sna_visit_set_window_pixmap(WindowPtr window, pointer data)
-{
-    struct sna_visit_set_pixmap_window *visit = data;
-    ScreenPtr screen = window->drawable.pScreen;
-
-    if (screen->GetWindowPixmap(window) == visit->old) {
-	    screen->SetWindowPixmap(window, visit->new);
-	    return WT_WALKCHILDREN;
-    }
-
-    return WT_DONTWALKCHILDREN;
-}
-
 static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
 {
 	struct sna_pixmap *old_priv, *new_priv;
@@ -2695,36 +2677,6 @@ static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
 			       new->drawable.height);
 }
 
-static void
-migrate_dirty_tracking(struct sna *sna, PixmapPtr old_front)
-{
-#if HAS_PIXMAP_SHARING
-	ScreenPtr screen = sna->scrn->pScreen;
-	PixmapDirtyUpdatePtr dirty, safe;
-
-	xorg_list_for_each_entry_safe(dirty, safe, &screen->pixmap_dirty_list, ent) {
-		assert(dirty->src == old_front);
-		if (dirty->src != old_front)
-			continue;
-
-		DamageUnregister(&dirty->src->drawable, dirty->damage);
-		DamageDestroy(dirty->damage);
-
-		dirty->damage = DamageCreate(NULL, NULL,
-					     DamageReportNone,
-					     TRUE, screen, screen);
-		if (!dirty->damage) {
-			xorg_list_del(&dirty->ent);
-			free(dirty);
-			continue;
-		}
-
-		DamageRegister(&sna->front->drawable, dirty->damage);
-		dirty->src = sna->front;
-	}
-#endif
-}
-
 static Bool
 sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 {
@@ -2783,17 +2735,6 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 			sna_crtc_disable(crtc);
 	}
 
-	/* Open-coded screen->SetScreenPixmap */
-	migrate_dirty_tracking(sna, old_front);
-
-	if (root(screen)) {
-		struct sna_visit_set_pixmap_window visit;
-
-		visit.old = old_front;
-		visit.new = sna->front;
-		TraverseTree(root(screen), sna_visit_set_window_pixmap, &visit);
-		assert(screen->GetWindowPixmap(root(screen)) == sna->front);
-	}
 	screen->SetScreenPixmap(sna->front);
 	assert(screen->GetScreenPixmap(screen) == sna->front);
 
diff --git a/src/sna/sna_display_fake.c b/src/sna/sna_display_fake.c
index b4a5a94..113c44a 100644
--- a/src/sna/sna_display_fake.c
+++ b/src/sna/sna_display_fake.c
@@ -199,54 +199,6 @@ sna_output_fake(struct sna *sna)
 	return true;
 }
 
-struct sna_visit_set_pixmap_window {
-	PixmapPtr old, new;
-};
-
-static int
-sna_visit_set_window_pixmap(WindowPtr window, pointer data)
-{
-    struct sna_visit_set_pixmap_window *visit = data;
-    ScreenPtr screen = window->drawable.pScreen;
-
-    if (screen->GetWindowPixmap(window) == visit->old) {
-	    screen->SetWindowPixmap(window, visit->new);
-	    return WT_WALKCHILDREN;
-    }
-
-    return WT_DONTWALKCHILDREN;
-}
-
-static void
-migrate_dirty_tracking(struct sna *sna, PixmapPtr old_front)
-{
-#if HAS_PIXMAP_SHARING
-	ScreenPtr screen = sna->scrn->pScreen;
-	PixmapDirtyUpdatePtr dirty, safe;
-
-	xorg_list_for_each_entry_safe(dirty, safe, &screen->pixmap_dirty_list, ent) {
-		assert(dirty->src == old_front);
-		if (dirty->src != old_front)
-			continue;
-
-		DamageUnregister(&dirty->src->drawable, dirty->damage);
-		DamageDestroy(dirty->damage);
-
-		dirty->damage = DamageCreate(NULL, NULL,
-					     DamageReportNone,
-					     TRUE, screen, screen);
-		if (!dirty->damage) {
-			xorg_list_del(&dirty->ent);
-			free(dirty);
-			continue;
-		}
-
-		DamageRegister(&sna->front->drawable, dirty->damage);
-		dirty->src = sna->front;
-	}
-#endif
-}
-
 static Bool
 sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 {
@@ -279,17 +231,6 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 	scrn->virtualY = height;
 	scrn->displayWidth = width;
 
-	/* Open-coded screen->SetScreenPixmap */
-	migrate_dirty_tracking(sna, old_front);
-
-	if (root(screen)) {
-		struct sna_visit_set_pixmap_window visit;
-
-		visit.old = old_front;
-		visit.new = sna->front;
-		TraverseTree(root(screen), sna_visit_set_window_pixmap, &visit);
-		assert(screen->GetWindowPixmap(root(screen)) == sna->front);
-	}
 	screen->SetScreenPixmap(sna->front);
 	assert(screen->GetScreenPixmap(screen) == sna->front);
 
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index aafa365..eededf3 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -186,7 +186,7 @@ sna_set_fallback_mode(ScrnInfoPtr scrn)
 
 	xf86DisableUnusedFunctions(scrn);
 #ifdef RANDR_12_INTERFACE
-	if (root(scrn->pScreen))
+	if (get_root_window(scrn->pScreen))
 		xf86RandR12TellChanged(scrn->pScreen);
 #endif
 }
commit 07926bfe507071a3d46a2ec13bb86a36bc225761
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 11 15:28:55 2013 +0100

    sna: Remove the temporary region allocation from sna_do_copy
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index dc8e4dd..50aa48e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5458,7 +5458,7 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	    int dx, int dy,
 	    sna_copy_func copy, Pixel bitPlane, void *closure)
 {
-	RegionPtr clip, free_clip = NULL;
+	RegionPtr clip;
 	RegionRec region;
 	bool expose;
 
@@ -5510,14 +5510,37 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	} else if (src->type == DRAWABLE_PIXMAP) {
 		DBG(("%s: pixmap -- no source clipping\n", __FUNCTION__));
 	} else if (gc->subWindowMode == IncludeInferiors) {
+		WindowPtr w = (WindowPtr)src;
+
+		DBG(("%s: include inferiors (is-clipped? %d)\n",
+		     __FUNCTION__, w->parent || RegionNil(&w->borderClip)));
+
 		/*
 		 * XFree86 DDX empties the border clip when the
 		 * VT is inactive, make sure the region isn't empty
 		 */
-		if (((WindowPtr)src)->parent ||
-		    RegionNil(&((WindowPtr)src)->borderClip)) {
-			DBG(("%s: include inferiors\n", __FUNCTION__));
-			free_clip = clip = NotClippedByChildren((WindowPtr)src);
+		if (w->parent || RegionNil(&w->borderClip)) {
+			int16_t v;
+
+			v = max(w->borderClip.extents.x1,
+				w->winSize.extents.x1);
+			if (region.extents.x1 < v)
+				region.extents.x1 = v;
+
+			v = max(w->borderClip.extents.y1,
+				w->winSize.extents.y1);
+			if (region.extents.y1 < v)
+				region.extents.y1 = v;
+
+			v = min(w->borderClip.extents.x2,
+				w->winSize.extents.x2);
+			if (region.extents.x2 > v)
+				region.extents.x2 = v;
+
+			v = min(w->borderClip.extents.y2,
+				w->winSize.extents.y2);
+			if (region.extents.y2 > v)
+				region.extents.y2 = v;
 		}
 	} else {
 		DBG(("%s: window clip\n", __FUNCTION__));
@@ -5547,8 +5570,6 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	} else {
 		expose = false;
 		RegionIntersect(&region, &region, clip);
-		if (free_clip)
-			RegionDestroy(free_clip);
 	}
 	DBG(("%s: src extents (%d, %d), (%d, %d) x %ld\n", __FUNCTION__,
 	     region.extents.x1, region.extents.y1,


More information about the xorg-commit mailing list