xf86-video-intel: 4 commits - src/intel_display.c src/sna/fb src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna_glyphs.c src/sna/sna.h src/sna/sna_tiling.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Sep 4 00:56:02 PDT 2012


 src/intel_display.c   |    2 
 src/sna/fb/fb.h       |   14 ++--
 src/sna/gen6_render.c |   68 ++++++++++++---------
 src/sna/gen7_render.c |   68 ++++++++++++---------
 src/sna/kgem.c        |   59 ++++++++++++++++++
 src/sna/kgem.h        |    2 
 src/sna/sna.h         |   12 ++-
 src/sna/sna_accel.c   |  158 +++++++++++++++++++++++++++++++++++++++++++++++---
 src/sna/sna_display.c |   32 ++++++++++
 src/sna/sna_dri.c     |    8 +-
 src/sna/sna_driver.c  |   38 +++++++++---
 src/sna/sna_glyphs.c  |    4 -
 src/sna/sna_tiling.c  |    1 
 13 files changed, 381 insertions(+), 85 deletions(-)

New commits:
commit df68723baae71498de95924c72d4f23fa7fc7fdf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 3 20:43:48 2012 +0100

    sna: Port prime interfacing
    
    Preliminary prime support.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/fb/fb.h b/src/sna/fb/fb.h
index 3339236..215aec9 100644
--- a/src/sna/fb/fb.h
+++ b/src/sna/fb/fb.h
@@ -28,15 +28,15 @@
 #include "config.h"
 #endif
 
-#include <stdbool.h>
-#include <pixman.h>
-
 #include <xorg-server.h>
 #include <servermd.h>
 #include <gcstruct.h>
 #include <colormap.h>
 #include <windowstr.h>
 
+#include <stdbool.h>
+#include <pixman.h>
+
 #if HAS_DEBUG_FULL
 #define DBG(x) ErrorF x
 #else
@@ -288,13 +288,17 @@ typedef struct {
 	unsigned char bpp;          /* current drawable bpp */
 } FbGCPrivate, *FbGCPrivPtr;
 
+extern DevPrivateKeyRec sna_gc_key;
+extern DevPrivateKeyRec sna_window_key;
+
 static inline FbGCPrivate *fb_gc(GCPtr gc)
 {
-	return (FbGCPrivate *)gc->devPrivates;
+	return dixGetPrivateAddr(&gc->devPrivates, &sna_gc_key);
 }
+
 static inline PixmapPtr fbGetWindowPixmap(WindowPtr window)
 {
-	return *(void **)window->devPrivates;
+	return *(PixmapPtr *)dixGetPrivateAddr(&window->devPrivates, &sna_window_key);
 }
 
 #ifdef ROOTLESS
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index cb0c82a..d68ad9f 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2771,6 +2771,65 @@ struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name)
 	return bo;
 }
 
+struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size)
+{
+#ifdef DRM_IOCTL_PRIME_FD_TO_HANDLE
+	struct drm_prime_handle args;
+	struct drm_i915_gem_get_tiling tiling;
+	struct kgem_bo *bo;
+
+	DBG(("%s(name=%d)\n", __FUNCTION__, name));
+
+	VG_CLEAR(args);
+	args.fd = name;
+	args.flags = 0;
+	if (drmIoctl(kgem->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args))
+		return NULL;
+
+	VG_CLEAR(tiling);
+	tiling.handle = args.handle;
+	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) {
+		gem_close(kgem->fd, args.handle);
+		return NULL;
+	}
+
+	DBG(("%s: new handle=%d, tiling=%d\n", __FUNCTION__,
+	     args.handle, tiling.tiling_mode));
+	bo = __kgem_bo_alloc(args.handle, NUM_PAGES(size));
+	if (bo == NULL) {
+		gem_close(kgem->fd, args.handle);
+		return NULL;
+	}
+
+	bo->tiling = tiling.tiling_mode;
+	bo->reusable = false;
+
+	debug_alloc__bo(kgem, bo);
+	return bo;
+#else
+	return NULL;
+#endif
+}
+
+int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo)
+{
+#ifdef DRM_IOCTL_PRIME_HANDLE_TO_PRIME
+	struct drm_prime_handle args;
+
+	VG_CLEAR(args);
+	args.handle = bo->handle;
+	args.flags = DRM_CLOEXEC;
+
+	if (drmIoctl(kgem->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
+		return -1;
+
+	bo->reusable = false;
+	return args.fd;
+#else
+	return -1;
+#endif
+}
+
 struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags)
 {
 	struct kgem_bo *bo;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index d72db55..33cd3ff 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -207,6 +207,8 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
 				bool read_only);
 
 struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name);
+struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size);
+int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo);
 
 struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags);
 struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
diff --git a/src/sna/sna.h b/src/sna/sna.h
index d655da0..b876061 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -47,6 +47,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <xorg-server.h>
 
 #include <xf86Crtc.h>
+#if XF86_CRTC_VERSION >= 5
+#define HAS_PIXMAP_SHARING 1
+#endif
+
 #include <xf86str.h>
 #include <windowstr.h>
 #include <glyphstr.h>
@@ -149,9 +153,11 @@ static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
 		return get_window_pixmap((WindowPtr)drawable);
 }
 
+extern DevPrivateKeyRec sna_pixmap_key;
+
 constant static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
 {
-	return ((void **)pixmap->devPrivates)[1];
+	return ((void **)dixGetPrivateAddr(&pixmap->devPrivates, &sna_pixmap_key))[1];
 }
 
 static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable)
@@ -167,7 +173,7 @@ struct sna_gc {
 
 static inline struct sna_gc *sna_gc(GCPtr gc)
 {
-	return (struct sna_gc *)gc->devPrivates;
+	return dixGetPrivateAddr(&gc->devPrivates, &sna_gc_key);
 }
 
 enum {
@@ -309,7 +315,7 @@ to_sna_from_screen(ScreenPtr screen)
 constant static inline struct sna *
 to_sna_from_pixmap(PixmapPtr pixmap)
 {
-	return *(void **)pixmap->devPrivates;
+	return ((void **)dixGetPrivateAddr(&pixmap->devPrivates, &sna_pixmap_key))[0];
 }
 
 constant static inline struct sna *
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 0cb10bc..b9bf93b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -601,11 +601,7 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling)
 
 static inline void sna_set_pixmap(PixmapPtr pixmap, struct sna_pixmap *sna)
 {
-#if 0
-	dixSetPrivate(&pixmap->devPrivates, &sna_private_index, sna);
-#else
-	((void **)pixmap->devPrivates)[1] = sna;
-#endif
+	((void **)dixGetPrivateAddr(&pixmap->devPrivates, &sna_pixmap_key))[1] = sna;
 	assert(sna_pixmap(pixmap) == sna);
 }
 
@@ -709,7 +705,8 @@ create_pixmap(struct sna *sna, ScreenPtr screen,
 	if (!pixmap)
 		return NullPixmap;
 
-	((void **)pixmap->devPrivates)[0] = sna;
+	((void **)dixGetPrivateAddr(&pixmap->devPrivates, &sna_pixmap_key))[0] = sna;
+	assert(to_sna_from_pixmap(pixmap) == sna);
 
 	pixmap->drawable.type = DRAWABLE_PIXMAP;
 	pixmap->drawable.class = 0;
@@ -924,6 +921,111 @@ sna_pixmap_create_scratch(ScreenPtr screen,
 	return pixmap;
 }
 
+#ifdef CREATE_PIXMAP_USAGE_SHARED
+static Bool
+sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle)
+{
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	struct sna_pixmap *priv;
+	int fd;
+
+	priv = sna_pixmap_move_to_gpu(pixmap,
+				      MOVE_READ | MOVE_WRITE | __MOVE_DRI | __MOVE_FORCE);
+	if (priv == NULL)
+		return FALSE;
+
+	assert(priv->gpu_bo);
+
+	/* XXX */
+	if (priv->gpu_bo->tiling &&
+	    !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE))
+		return FALSE;
+	assert(priv->gpu_bo->tiling == I915_TILING_NONE);
+
+	/* And export the bo->pitch via pixmap->devKind */
+	pixmap->devPrivate.ptr =
+		kgem_bo_map(&sna->kgem, priv->gpu_bo);
+	if (pixmap->devPrivate.ptr == NULL)
+		return FALSE;
+
+	pixmap->devKind = priv->gpu_bo->pitch;
+	priv->mapped = true;
+
+	fd = kgem_bo_export_to_prime(&sna->kgem, priv->gpu_bo);
+	if (fd == -1)
+		return FALSE;
+
+	priv->pinned = true;
+
+	*fd_handle = (void *)(intptr_t)fd;
+	return TRUE;
+}
+
+static Bool
+sna_set_shared_pixmap_backing(PixmapPtr pixmap, void *fd_handle)
+{
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	struct sna_pixmap *priv;
+	struct kgem_bo *bo;
+
+	priv = sna_pixmap(pixmap);
+	if (priv == NULL)
+		return FALSE;
+
+	assert(!priv->pinned);
+	assert(priv->gpu_bo == NULL);
+	assert(priv->cpu_bo == NULL);
+	assert(priv->cpu_damage == NULL);
+	assert(priv->gpu_damage == NULL);
+
+	bo = kgem_bo_create_for_prime(&sna->kgem,
+				      (intptr_t)fd_handle,
+				      pixmap->devKind * pixmap->drawable.height);
+	if (bo == NULL)
+		return FALSE;
+
+	sna_damage_all(&priv->gpu_damage,
+		       pixmap->drawable.width,
+		       pixmap->drawable.height);
+
+	bo->pitch = pixmap->devKind;
+	priv->stride = pixmap->devKind;
+
+	priv->gpu_bo = bo;
+	priv->pinned = true;
+
+	close((intptr_t)fd_handle);
+	return TRUE;
+}
+
+static PixmapPtr
+sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen, int depth)
+{
+	PixmapPtr pixmap;
+	struct sna_pixmap *priv;
+
+	/* Create a stub to be attached later */
+	pixmap = create_pixmap(sna, screen, 0, 0, depth, 0);
+	if (pixmap == NullPixmap)
+		return NullPixmap;
+
+	pixmap->drawable.width = 0;
+	pixmap->drawable.height = 0;
+	pixmap->devKind = 0;
+	pixmap->devPrivate.ptr = NULL;
+
+	priv = sna_pixmap_attach(pixmap);
+	if (priv == NULL) {
+		free(pixmap);
+		return NullPixmap;
+	}
+
+	priv->stride = 0;
+	priv->create = 0;
+	return pixmap;
+}
+#endif
+
 static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 				   int width, int height, int depth,
 				   unsigned int usage)
@@ -936,6 +1038,13 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 	DBG(("%s(%d, %d, %d, usage=%x)\n", __FUNCTION__,
 	     width, height, depth, usage));
 
+#ifdef CREATE_PIXMAP_USAGE_SHARED
+	if (usage == CREATE_PIXMAP_USAGE_SHARED) {
+		assert((width|height) == 0);
+		return sna_create_pixmap_shared(sna, screen, depth);
+	}
+#endif
+
 	if ((width|height) == 0) {
 		usage = -1;
 		goto fallback;
@@ -13675,6 +13784,31 @@ static int32_t sna_timeout(struct sna *sna)
 	return next;
 }
 
+static void sna_accel_post_damage(struct sna *sna)
+{
+#if HAS_PIXMAP_SHARING
+	ScreenPtr screen = sna->scrn->pScreen;
+	PixmapDirtyUpdatePtr dirty;
+
+	xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
+		RegionRec pixregion;
+
+		if (!RegionNotEmpty(DamageRegion(dirty->damage)))
+			continue;
+
+		PixmapRegionInit(&pixregion,
+				 dirty->slave_dst->master_pixmap);
+		PixmapSyncDirtyHelper(dirty, &pixregion);
+
+		DamageRegionAppend(&dirty->slave_dst->drawable,
+				   &pixregion);
+		RegionUninit(&pixregion);
+
+		DamageEmpty(dirty->damage);
+	}
+#endif
+}
+
 static void sna_accel_flush(struct sna *sna)
 {
 	struct sna_pixmap *priv = sna_accel_scanout(sna);
@@ -13699,6 +13833,7 @@ static void sna_accel_flush(struct sna *sna)
 	}
 
 	sna_mode_redisplay(sna);
+	sna_accel_post_damage(sna);
 }
 
 static void sna_accel_throttle(struct sna *sna)
@@ -13859,7 +13994,7 @@ sna_get_window_pixmap(WindowPtr window)
 static void
 sna_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
 {
-	*(PixmapPtr *)window->devPrivates = pixmap;
+	*(PixmapPtr *)dixGetPrivateAddr(&window->devPrivates, &sna_window_key) = pixmap;
 }
 
 static Bool
@@ -13988,6 +14123,10 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 	screen->CreatePixmap = sna_create_pixmap;
 	assert(screen->DestroyPixmap == NULL);
 	screen->DestroyPixmap = sna_destroy_pixmap;
+#ifdef CREATE_PIXMAP_USAGE_SHARED
+	screen->SharePixmapBacking = sna_share_pixmap_backing;
+	screen->SetSharedPixmapBacking = sna_set_shared_pixmap_backing;
+#endif
 	screen->RealizeFont = sna_realize_font;
 	screen->UnrealizeFont = sna_unrealize_font;
 	assert(screen->CreateGC == NULL);
@@ -14002,6 +14141,11 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 	screen->StoreColors = sna_store_colors;
 	screen->BitmapToRegion = fbBitmapToRegion;
 
+#if HAS_PIXMAP_SHARING
+	screen->StartPixmapTracking = PixmapStartDirtyTracking;
+	screen->StopPixmapTracking = PixmapStopDirtyTracking;
+#endif
+
 	assert(screen->GetWindowPixmap == NULL);
 	screen->GetWindowPixmap = sna_get_window_pixmap;
 	assert(screen->SetWindowPixmap == NULL);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 3ec6dc1..7e87204 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -60,6 +60,7 @@
 struct sna_crtc {
 	struct drm_mode_modeinfo kmode;
 	int dpms_mode;
+	PixmapPtr scanout_pixmap;
 	struct kgem_bo *bo;
 	uint32_t cursor;
 	bool shadow;
@@ -960,6 +961,22 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
 
 		sna_crtc->transform = true;
 		return bo;
+	} else if (sna_crtc->scanout_pixmap) {
+		DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__));
+		if (!sna_crtc_enable_shadow(sna, sna_crtc))
+			return NULL;
+
+		bo = sna_pixmap_pin(sna_crtc->scanout_pixmap);
+		if (bo == NULL)
+			return NULL;
+
+		if (!get_fb(sna, bo,
+			    sna_crtc->scanout_pixmap->drawable.width,
+			    sna_crtc->scanout_pixmap->drawable.height))
+			return NULL;
+
+		sna_crtc->transform = true;
+		return kgem_bo_reference(bo);
 	} else if (sna->flags & SNA_TEAR_FREE) {
 		DBG(("%s: tear-free updates requested\n", __FUNCTION__));
 
@@ -1299,6 +1316,15 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
 	crtc->driver_private = NULL;
 }
 
+#if HAS_PIXMAP_SHARING
+static Bool
+sna_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
+{
+	to_sna_crtc(crtc)->scanout_pixmap = pixmap;
+	return TRUE;
+}
+#endif
+
 static const xf86CrtcFuncsRec sna_crtc_funcs = {
 	.dpms = sna_crtc_dpms,
 	.set_mode_major = sna_crtc_set_mode_major,
@@ -1309,6 +1335,9 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = {
 	.load_cursor_argb = sna_crtc_load_cursor_argb,
 	.gamma_set = sna_crtc_gamma_set,
 	.destroy = sna_crtc_destroy,
+#if HAS_PIXMAP_SHARING
+	.set_scanout_pixmap = sna_set_scanout_pixmap,
+#endif
 };
 
 static uint32_t
@@ -2412,6 +2441,9 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 	for (i = 0; i < mode->kmode->count_connectors; i++)
 		sna_output_init(scrn, mode, i);
 
+#if HAS_PIXMAP_SHARING
+	xf86ProviderSetup(scrn, NULL, "Intel");
+#endif
 	xf86InitialConfiguration(scrn, TRUE);
 
 	return true;
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 77e4e26..ff18fe3 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -195,12 +195,12 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 
 constant static inline void *sna_pixmap_get_buffer(PixmapPtr pixmap)
 {
-	return ((void **)pixmap->devPrivates)[2];
+	return ((void **)dixGetPrivateAddr(&pixmap->devPrivates, &sna_pixmap_key))[2];
 }
 
 static inline void sna_pixmap_set_buffer(PixmapPtr pixmap, void *ptr)
 {
-	((void **)pixmap->devPrivates)[2] = ptr;
+	((void **)dixGetPrivateAddr(&pixmap->devPrivates, &sna_pixmap_key))[2] = ptr;
 }
 
 static DRI2Buffer2Ptr
@@ -841,7 +841,7 @@ sna_dri_get_pipe(DrawablePtr pDraw)
 static struct sna_dri_frame_event *
 sna_dri_window_get_chain(WindowPtr win)
 {
-	return ((void **)win->devPrivates)[1];
+	return ((void **)dixGetPrivateAddr(&win->devPrivates, &sna_window_key))[1];
 }
 
 static void
@@ -850,7 +850,7 @@ sna_dri_window_set_chain(WindowPtr win,
 {
 	DBG(("%s: head now %p\n", __FUNCTION__, chain));
 	assert(win->drawable.type == DRAWABLE_WINDOW);
-	((void **)win->devPrivates)[1] = chain;
+	((void **)dixGetPrivateAddr(&win->devPrivates, &sna_window_key))[1] = chain;
 }
 
 static void
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 2eab460..a193607 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -75,10 +75,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "git_version.h"
 #endif
 
-static DevPrivateKeyRec sna_pixmap_key;
-static DevPrivateKeyRec sna_gc_key;
-static DevPrivateKeyRec sna_glyph_key;
-static DevPrivateKeyRec sna_window_key;
+DevPrivateKeyRec sna_pixmap_key;
+DevPrivateKeyRec sna_gc_key;
+DevPrivateKeyRec sna_window_key;
+DevPrivateKeyRec sna_glyph_key;
 
 static Bool sna_enter_vt(VT_FUNC_ARGS_DECL);
 
@@ -343,6 +343,21 @@ static bool has_pageflipping(struct sna *sna)
 	return v > 0;
 }
 
+static void sna_setup_capabilities(ScrnInfoPtr scrn, int fd)
+{
+#if HAS_PIXMAP_SHARING && defined(DRM_CAP_PRIME)
+	uint64_t value;
+
+	scrn->capabilities = 0;
+	if (drmGetCap(fd, DRM_CAP_PRIME, &value) == 0) {
+		if (value & DRM_PRIME_CAP_EXPORT)
+			scrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload;
+		if (value & DRM_PRIME_CAP_IMPORT)
+			scrn->capabilities |= RR_Capability_SinkOutput;
+	}
+#endif
+}
+
 /**
  * This is called before ScreenInit to do any require probing of screen
  * configuration.
@@ -442,6 +457,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 	if (sna->Options == NULL)
 		return FALSE;
 
+	sna_setup_capabilities(scrn, fd);
+
 	intel_detect_chipset(scrn, sna->pEnt, sna->PciInfo);
 
 	kgem_init(&sna->kgem, fd, sna->PciInfo, sna->info->gen);
@@ -777,22 +794,18 @@ sna_register_all_privates(void)
 	if (!dixRegisterPrivateKey(&sna_pixmap_key, PRIVATE_PIXMAP,
 				   3*sizeof(void *)))
 		return FALSE;
-	assert(sna_pixmap_key.offset == 0);
 
 	if (!dixRegisterPrivateKey(&sna_gc_key, PRIVATE_GC,
 				   sizeof(FbGCPrivate)))
 		return FALSE;
-	assert(sna_gc_key.offset == 0);
 
 	if (!dixRegisterPrivateKey(&sna_glyph_key, PRIVATE_GLYPH,
 				   sizeof(struct sna_glyph)))
 		return FALSE;
-	assert(sna_glyph_key.offset == 0);
 
 	if (!dixRegisterPrivateKey(&sna_window_key, PRIVATE_WINDOW,
 				   2*sizeof(void *)))
 		return FALSE;
-	assert(sna_window_key.offset == 0);
 
 	return TRUE;
 }
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 8cbe39c..f7331a5 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -104,9 +104,11 @@ static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char
 #define assert_pixmap_contains_box(p, b)
 #endif
 
+extern DevPrivateKeyRec sna_glyph_key;
+
 static inline struct sna_glyph *sna_glyph(GlyphPtr glyph)
 {
-	return (struct sna_glyph *)glyph->devPrivates;
+	return dixGetPrivateAddr(&glyph->devPrivates, &sna_glyph_key);
 }
 
 #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
commit e3ad18036b4dca29744ecfa4694006f01dd3fd18
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 3 20:53:30 2012 +0100

    sna: Enable platform probing
    
    Completing commit 0768ac4d195214825137152893deb74a87fcd11e
    Author: Dave Airlie <airlied at redhat.com>
    Date:   Wed Jul 25 16:11:23 2012 +1000
    
        intel: add platform probing support.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index a0beb4c..2eab460 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -371,7 +371,14 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 		return FALSE;
 
 	pEnt = xf86GetEntityInfo(scrn->entityList[0]);
-	if (pEnt == NULL || pEnt->location.type != BUS_PCI)
+	if (pEnt == NULL)
+		return FALSE;
+
+	if (pEnt->location.type != BUS_PCI
+#ifdef XSERVER_PLATFORM_BUS
+	    && pEnt->location.type != BUS_PLATFORM
+#endif
+		)
 		return FALSE;
 
 	if (flags & PROBE_DETECT)
commit 3dc644b2a959fc559e1138b332ed42d7235de42f
Author: Сковорода Никита Андреевич <chalkerx at gmail.com>
Date:   Mon Sep 3 13:44:21 2012 +0400

    uxa: Fix Backlight option support.
    
    Signed-off-by: Сковорода Никита Андреевич <chalkerx at gmail.com>

diff --git a/src/intel_display.c b/src/intel_display.c
index 4bc8a7b..233c6af 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -262,7 +262,7 @@ intel_output_backlight_init(xf86OutputPtr output)
 	int i;
 
 	str = xf86GetOptValString(intel->Options, OPTION_BACKLIGHT);
-	if (str == NULL) {
+	if (str != NULL) {
 		sprintf(path, "%s/%s", BACKLIGHT_CLASS, str);
 		if (!stat(path, &buf)) {
 			intel_output->backlight_iface = backlight_interfaces[i];
commit a972affe0c78b23a119d5dd14bb4446c89122af1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 2 17:43:33 2012 +0100

    sna/gen6+: Redirect fills if the destination is too large for 3D
    
    Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54134
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 6d5a6ce..363e8db 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -1287,7 +1287,8 @@ gen6_emit_composite_primitive_solid(struct sna *sna,
 	v = sna->render.vertices + sna->render.vertex_used;
 	sna->render.vertex_used += 9;
 	assert(sna->render.vertex_used <= sna->render.vertex_size);
-	assert(!too_large(r->dst.x + r->width, r->dst.y + r->height));
+	assert(!too_large(op->dst.x + r->dst.x + r->width,
+			  op->dst.y + r->dst.y + r->height));
 
 	dst.p.x = r->dst.x + r->width;
 	dst.p.y = r->dst.y + r->height;
@@ -3249,15 +3250,8 @@ static inline bool prefer_blt_copy(struct sna *sna,
 		prefer_blt_bo(sna, dst_bo));
 }
 
-static inline bool
-overlaps(struct sna *sna,
-	 struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
-	 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
-	 const BoxRec *box, int n, BoxRec *extents)
+inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents)
 {
-	if (src_bo != dst_bo)
-		return false;
-
 	*extents = box[0];
 	while (--n) {
 		box++;
@@ -3272,7 +3266,18 @@ overlaps(struct sna *sna,
 		if (box->y2 > extents->y2)
 			extents->y2 = box->y2;
 	}
+}
 
+static inline bool
+overlaps(struct sna *sna,
+	 struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
+	 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
+	 const BoxRec *box, int n, BoxRec *extents)
+{
+	if (src_bo != dst_bo)
+		return false;
+
+	boxes_extents(box, n, extents);
 	return (extents->x2 + src_dx > extents->x1 + dst_dx &&
 		extents->x1 + src_dx < extents->x2 + dst_dx &&
 		extents->y2 + src_dy > extents->y1 + dst_dy &&
@@ -3667,22 +3672,21 @@ gen6_render_fill_boxes(struct sna *sna,
 		return false;
 	}
 
-	if (op <= PictOpSrc &&
-	    (prefer_blt_fill(sna, dst_bo) ||
-	     too_large(dst->drawable.width, dst->drawable.height) ||
-	     !gen6_check_dst_format(format))) {
+	if (prefer_blt_fill(sna, dst_bo) || !gen6_check_dst_format(format)) {
 		uint8_t alu = GXinvalid;
 
-		pixel = 0;
-		if (op == PictOpClear)
-			alu = GXclear;
-		else if (sna_get_pixel_from_rgba(&pixel,
-						 color->red,
-						 color->green,
-						 color->blue,
-						 color->alpha,
-						 format))
-			alu = GXcopy;
+		if (op <= PictOpSrc) {
+			pixel = 0;
+			if (op == PictOpClear)
+				alu = GXclear;
+			else if (sna_get_pixel_from_rgba(&pixel,
+							 color->red,
+							 color->green,
+							 color->blue,
+							 color->alpha,
+							 format))
+				alu = GXcopy;
+		}
 
 		if (alu != GXinvalid &&
 		    sna_blt_fill_boxes(sna, alu,
@@ -3692,10 +3696,6 @@ gen6_render_fill_boxes(struct sna *sna,
 
 		if (!gen6_check_dst_format(format))
 			return false;
-
-		if (too_large(dst->drawable.width, dst->drawable.height))
-			return sna_tiling_fill_boxes(sna, op, format, color,
-						     dst, dst_bo, box, n);
 	}
 
 	if (op == PictOpClear) {
@@ -3720,6 +3720,19 @@ gen6_render_fill_boxes(struct sna *sna,
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = tmp.dst.y = 0;
 
+	sna_render_composite_redirect_init(&tmp);
+	if (too_large(dst->drawable.width, dst->drawable.height)) {
+		BoxRec extents;
+
+		boxes_extents(box, n, &extents);
+		if (!sna_render_composite_redirect(sna, &tmp,
+						   extents.x1, extents.y1,
+						   extents.x2 - extents.x1,
+						   extents.y2 - extents.y1))
+			return sna_tiling_fill_boxes(sna, op, format, color,
+						     dst, dst_bo, box, n);
+	}
+
 	tmp.src.bo = sna_render_get_solid(sna, pixel);
 	tmp.mask.bo = NULL;
 
@@ -3767,6 +3780,7 @@ gen6_render_fill_boxes(struct sna *sna,
 
 	gen6_vertex_flush(sna);
 	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+	sna_render_composite_redirect_done(sna, &tmp);
 	return true;
 }
 
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index ffe41cf..0cc4cba 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -1401,7 +1401,8 @@ gen7_emit_composite_primitive_solid(struct sna *sna,
 	v = sna->render.vertices + sna->render.vertex_used;
 	sna->render.vertex_used += 9;
 	assert(sna->render.vertex_used <= sna->render.vertex_size);
-	assert(!too_large(r->dst.x + r->width, r->dst.y + r->height));
+	assert(!too_large(op->dst.x + r->dst.x + r->width,
+			  op->dst.y + r->dst.y + r->height));
 
 	dst.p.x = r->dst.x + r->width;
 	dst.p.y = r->dst.y + r->height;
@@ -3338,15 +3339,8 @@ static inline bool prefer_blt_copy(struct sna *sna,
 		prefer_blt_bo(sna, dst_bo));
 }
 
-static inline bool
-overlaps(struct sna *sna,
-	 struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
-	 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
-	 const BoxRec *box, int n, BoxRec *extents)
+inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents)
 {
-	if (src_bo != dst_bo)
-		return false;
-
 	*extents = box[0];
 	while (--n) {
 		box++;
@@ -3361,7 +3355,18 @@ overlaps(struct sna *sna,
 		if (box->y2 > extents->y2)
 			extents->y2 = box->y2;
 	}
+}
 
+static inline bool
+overlaps(struct sna *sna,
+	 struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
+	 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
+	 const BoxRec *box, int n, BoxRec *extents)
+{
+	if (src_bo != dst_bo)
+		return false;
+
+	boxes_extents(box, n, extents);
 	return (extents->x2 + src_dx > extents->x1 + dst_dx &&
 		extents->x1 + src_dx < extents->x2 + dst_dx &&
 		extents->y2 + src_dy > extents->y1 + dst_dy &&
@@ -3742,22 +3747,21 @@ gen7_render_fill_boxes(struct sna *sna,
 		return false;
 	}
 
-	if (op <= PictOpSrc &&
-	    (prefer_blt_fill(sna, dst_bo) ||
-	     too_large(dst->drawable.width, dst->drawable.height) ||
-	     !gen7_check_dst_format(format))) {
+	if (prefer_blt_fill(sna, dst_bo) || !gen7_check_dst_format(format)) {
 		uint8_t alu = GXinvalid;
 
-		pixel = 0;
-		if (op == PictOpClear)
-			alu = GXclear;
-		else if (sna_get_pixel_from_rgba(&pixel,
-						 color->red,
-						 color->green,
-						 color->blue,
-						 color->alpha,
-						 format))
-			alu = GXcopy;
+		if (op <= PictOpSrc) {
+			pixel = 0;
+			if (op == PictOpClear)
+				alu = GXclear;
+			else if (sna_get_pixel_from_rgba(&pixel,
+							 color->red,
+							 color->green,
+							 color->blue,
+							 color->alpha,
+							 format))
+				alu = GXcopy;
+		}
 
 		if (alu != GXinvalid &&
 		    sna_blt_fill_boxes(sna, alu,
@@ -3767,10 +3771,6 @@ gen7_render_fill_boxes(struct sna *sna,
 
 		if (!gen7_check_dst_format(format))
 			return false;
-
-		if (too_large(dst->drawable.width, dst->drawable.height))
-			return sna_tiling_fill_boxes(sna, op, format, color,
-						     dst, dst_bo, box, n);
 	}
 
 	if (op == PictOpClear) {
@@ -3795,6 +3795,19 @@ gen7_render_fill_boxes(struct sna *sna,
 	tmp.dst.bo = dst_bo;
 	tmp.dst.x = tmp.dst.y = 0;
 
+	sna_render_composite_redirect_init(&tmp);
+	if (too_large(dst->drawable.width, dst->drawable.height)) {
+		BoxRec extents;
+
+		boxes_extents(box, n, &extents);
+		if (!sna_render_composite_redirect(sna, &tmp,
+						   extents.x1, extents.y1,
+						   extents.x2 - extents.x1,
+						   extents.y2 - extents.y1))
+			return sna_tiling_fill_boxes(sna, op, format, color,
+						     dst, dst_bo, box, n);
+	}
+
 	tmp.src.bo = sna_render_get_solid(sna, pixel);
 	tmp.mask.bo = NULL;
 
@@ -3839,6 +3852,7 @@ gen7_render_fill_boxes(struct sna *sna,
 
 	gen7_vertex_flush(sna);
 	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+	sna_render_composite_redirect_done(sna, &tmp);
 	return true;
 }
 
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index e048361..9e70833 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -648,7 +648,6 @@ sna_tiling_fill_boxes(struct sna *sna,
 				int16_t dy = this.extents.y1;
 
 				assert(kgem_bo_can_blt(&sna->kgem, bo));
-				assert(bo->pitch <= 8192);
 
 				if (!sna->render.copy_boxes(sna, GXcopy,
 							     dst, dst_bo, 0, 0,


More information about the xorg-commit mailing list