xf86-video-intel: 4 commits - src/intel_display.c src/intel_driver.c src/intel.h src/intel_module.c src/intel_uxa.c

Dave Airlie airlied at kemper.freedesktop.org
Sun Sep 2 19:29:00 PDT 2012


 src/intel.h         |    9 +++++
 src/intel_display.c |   60 ++++++++++++++++++++++++++++++++---
 src/intel_driver.c  |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/intel_module.c  |   50 ++++++++++++++++++++++++++++-
 src/intel_uxa.c     |   75 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 276 insertions(+), 7 deletions(-)

New commits:
commit d14ff42f2a205542df2ef723c6151d18db2bea8b
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Jul 26 10:43:29 2012 +1000

    intel: query kernel for caps to setup scrn capabilities.
    
    This queries the kernel for prime support before advertising
    the capabilities.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/intel_driver.c b/src/intel_driver.c
index 65fecfc..348d5df 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -432,6 +432,25 @@ static Bool can_accelerate_blt(struct intel_screen_private *intel)
 	return TRUE;
 }
 
+static void intel_setup_capabilities(ScrnInfoPtr scrn)
+{
+#ifdef INTEL_PIXMAP_SHARING
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	uint64_t value;
+	int ret;
+
+	scrn->capabilities = 0;
+
+	ret = drmGetCap(intel->drmSubFD, DRM_CAP_PRIME, &value);
+	if (ret == 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.
@@ -524,6 +543,7 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 	if (!I830GetEarlyOptions(scrn))
 		return FALSE;
 
+	intel_setup_capabilities(scrn);
 	intel_check_chipset_option(scrn);
 	intel_check_dri_option(scrn);
 
commit 6705d8237aca90964449e4dbee97b4f62b87c28b
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Jul 26 10:37:04 2012 +1000

    intel: add pixmap tracking and scanout support. (v2)
    
    This adds support for pixmap tracking and scanout of
    alternate pixmaps.
    
    v2: do dirty updates after uxa block handler, check if kernel
    can flush vmap for us so we don't have to.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/intel.h b/src/intel.h
index 0b57aaf..5b0c5df 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -80,6 +80,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define MONITOR_EDID_COMPLETE_RAWDATA EDID_COMPLETE_RAWDATA
 #endif
 
+#if XF86_CRTC_VERSION >= 5
+#define INTEL_PIXMAP_SHARING 1
+#endif
+
 struct intel_pixmap {
 	dri_bo *bo;
 
@@ -347,8 +351,13 @@ typedef struct intel_screen_private {
 	struct udev_monitor *uevent_monitor;
 	InputHandlerProc uevent_handler;
 #endif
+	Bool has_prime_vmap_flush;
 } intel_screen_private;
 
+#ifndef I915_PARAM_HAS_PRIME_VMAP_FLUSH
+#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21
+#endif
+
 enum {
 	DEBUG_FLUSH_BATCHES = 0x1,
 	DEBUG_FLUSH_CACHES = 0x2,
diff --git a/src/intel_display.c b/src/intel_display.c
index 6dfc8e6..4bc8a7b 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -86,6 +86,8 @@ struct intel_crtc {
 	uint32_t rotate_fb_id;
 	xf86CrtcPtr crtc;
 	struct list link;
+	PixmapPtr scanout_pixmap;
+	uint32_t scanout_fb_id;
 };
 
 struct intel_property {
@@ -378,6 +380,7 @@ intel_crtc_apply(xf86CrtcPtr crtc)
 	ScrnInfoPtr scrn = crtc->scrn;
 	struct intel_crtc *intel_crtc = crtc->driver_private;
 	struct intel_mode *mode = intel_crtc->mode;
+	intel_screen_private *intel = intel_get_screen_private(scrn);
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	uint32_t *output_ids;
 	int output_count = 0;
@@ -401,13 +404,15 @@ intel_crtc_apply(xf86CrtcPtr crtc)
 		output_count++;
 	}
 
+	if (!intel_crtc->scanout_fb_id) {
 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0)
-	if (!xf86CrtcRotate(crtc, mode, rotation))
-		goto done;
+		if (!xf86CrtcRotate(crtc, mode, rotation))
+			goto done;
 #else
-	if (!xf86CrtcRotate(crtc))
-		goto done;
+		if (!xf86CrtcRotate(crtc))
+			goto done;
 #endif
+	}
 
 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0)
 	crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
@@ -421,6 +426,10 @@ intel_crtc_apply(xf86CrtcPtr crtc)
 		fb_id = intel_crtc->rotate_fb_id;
 		x = 0;
 		y = 0;
+	} else if (intel_crtc->scanout_fb_id && intel_crtc->scanout_pixmap->drawable.width >= crtc->mode.HDisplay && intel_crtc->scanout_pixmap->drawable.height >= crtc->mode.VDisplay) {
+		fb_id = intel_crtc->scanout_fb_id;
+		x = 0;
+		y = 0;
 	}
 	ret = drmModeSetCrtc(mode->fd, crtc_id(intel_crtc),
 			     fb_id, x, y, output_ids, output_count,
@@ -684,6 +693,42 @@ intel_crtc_destroy(xf86CrtcPtr crtc)
 	crtc->driver_private = NULL;
 }
 
+#ifdef INTEL_PIXMAP_SHARING
+static Bool
+intel_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
+{
+	struct intel_crtc *intel_crtc = crtc->driver_private;
+	ScrnInfoPtr scrn = crtc->scrn;
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	dri_bo *bo;
+	int ret;
+
+	if (ppix == intel_crtc->scanout_pixmap)
+		return TRUE;
+
+	if (!ppix) {
+		intel_crtc->scanout_pixmap = NULL;
+		if (intel_crtc->scanout_fb_id) {
+			drmModeRmFB(intel->drmSubFD, intel_crtc->scanout_fb_id);
+			intel_crtc->scanout_fb_id = 0;
+		}
+		return TRUE;
+	}
+
+	bo = intel_get_pixmap_bo(ppix);
+	if (intel->front_buffer) {
+		ErrorF("have front buffer\n");
+	}
+
+	intel_crtc->scanout_pixmap = ppix;
+	ret = drmModeAddFB(intel->drmSubFD, ppix->drawable.width,
+			   ppix->drawable.height, ppix->drawable.depth,
+			   ppix->drawable.bitsPerPixel, ppix->devKind,
+			   bo->handle, &intel_crtc->scanout_fb_id);
+	return TRUE;
+}
+#endif
+
 static const xf86CrtcFuncsRec intel_crtc_funcs = {
 	.dpms = intel_crtc_dpms,
 	.set_mode_major = intel_crtc_set_mode_major,
@@ -697,6 +742,9 @@ static const xf86CrtcFuncsRec intel_crtc_funcs = {
 	.shadow_destroy = intel_crtc_shadow_destroy,
 	.gamma_set = intel_crtc_gamma_set,
 	.destroy = intel_crtc_destroy,
+#ifdef INTEL_PIXMAP_SHARING
+	.set_scanout_pixmap = intel_set_scanout_pixmap,
+#endif
 };
 
 static void
@@ -1662,6 +1710,10 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
 	for (i = 0; i < mode->mode_res->count_connectors; i++)
 		intel_output_init(scrn, mode, i);
 
+#ifdef INTEL_PIXMAP_SHARING
+	xf86ProviderSetup(scrn, NULL, "Intel");
+#endif
+
 	xf86InitialConfiguration(scrn, TRUE);
 
 	mode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 76d56d9..65fecfc 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -385,6 +385,11 @@ static Bool has_relaxed_fencing(struct intel_screen_private *intel)
 	return drm_has_boolean_param(intel, I915_PARAM_HAS_RELAXED_FENCING);
 }
 
+static Bool has_prime_vmap_flush(struct intel_screen_private *intel)
+{
+	return drm_has_boolean_param(intel, I915_PARAM_HAS_PRIME_VMAP_FLUSH);
+}
+
 static Bool can_accelerate_blt(struct intel_screen_private *intel)
 {
 	if (INTEL_INFO(intel)->gen == -1)
@@ -545,6 +550,8 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 
 	intel->has_kernel_flush = has_kernel_flush(intel);
 
+	intel->has_prime_vmap_flush = has_prime_vmap_flush(intel);
+
 	intel->has_relaxed_fencing =
 		xf86ReturnOptValBool(intel->Options,
 				     OPTION_RELAXED_FENCING,
@@ -645,6 +652,51 @@ void IntelEmitInvarientState(ScrnInfoPtr scrn)
 		I915EmitInvarientState(scrn);
 }
 
+#ifdef INTEL_PIXMAP_SHARING
+static Bool
+redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	RegionRec pixregion;
+	int was_blocked;
+
+	PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap);
+
+	PixmapSyncDirtyHelper(dirty, &pixregion);
+	intel_batch_submit(scrn);
+	if (!intel->has_prime_vmap_flush) {
+		drm_intel_bo *bo = intel_get_pixmap_bo(dirty->slave_dst->master_pixmap);
+		was_blocked = xf86BlockSIGIO();
+		drm_intel_bo_map(bo, FALSE);
+		drm_intel_bo_unmap(bo);
+		xf86UnblockSIGIO(was_blocked);
+        }
+        DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
+        RegionUninit(&pixregion);
+	return 0;
+}
+
+static void
+intel_dirty_update(ScreenPtr screen)
+{
+	RegionPtr region;
+	PixmapDirtyUpdatePtr ent;
+
+	if (xorg_list_is_empty(&screen->pixmap_dirty_list))
+	    return;
+
+	ErrorF("list is not empty\n");
+	xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
+		region = DamageRegion(ent->damage);
+		if (RegionNotEmpty(region)) {
+			redisplay_dirty(screen, ent);
+			DamageEmpty(ent->damage);
+		}
+	}
+}
+#endif
+
 static void
 I830BlockHandler(BLOCKHANDLER_ARGS_DECL)
 {
@@ -661,6 +713,9 @@ I830BlockHandler(BLOCKHANDLER_ARGS_DECL)
 
 	intel_uxa_block_handler(intel);
 	intel_video_block_handler(intel);
+#ifdef INTEL_PIXMAP_SHARING
+	intel_dirty_update(screen);
+#endif
 }
 
 static Bool
@@ -906,6 +961,11 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 	intel->BlockHandler = screen->BlockHandler;
 	screen->BlockHandler = I830BlockHandler;
 
+#ifdef INTEL_PIXMAP_SHARING
+	screen->StartPixmapTracking = PixmapStartDirtyTracking;
+	screen->StopPixmapTracking = PixmapStopDirtyTracking;
+#endif
+
 	if (!AddCallback(&FlushCallback, intel_flush_callback, scrn))
 		return FALSE;
 
commit 69827126abdfa289417b55fe7db8ae0535037185
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jul 25 16:22:57 2012 +1000

    intel/uxa: add pixmap sharing support.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 3745ff0..9bb0e0a 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <xaarop.h>
 #include <string.h>
 #include <errno.h>
+#include <unistd.h>
 
 #include "intel.h"
 #include "intel_glamor.h"
@@ -1040,6 +1041,10 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage & INTEL_CREATE_PIXMAP_TILING_NONE)
 			tiling = I915_TILING_NONE;
 
+#ifdef CREATE_PIXMAP_USAGE_SHARED
+		if (usage == CREATE_PIXMAP_USAGE_SHARED)
+			tiling = I915_TILING_NONE;
+#endif
 		/* if tiling is off force to none */
 		if (!intel->tiling)
 			tiling = I915_TILING_NONE;
@@ -1138,7 +1143,7 @@ static Bool intel_uxa_destroy_pixmap(PixmapPtr pixmap)
 Bool intel_uxa_create_screen_resources(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+	PixmapPtr pixmap;
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	dri_bo *bo = intel->front_buffer;
 
@@ -1165,6 +1170,69 @@ Bool intel_uxa_create_screen_resources(ScreenPtr screen)
 	return TRUE;
 }
 
+#ifdef CREATE_PIXMAP_USAGE_SHARED
+static Bool
+intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(ppix->drawable.pScreen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	struct intel_pixmap *priv = intel_get_pixmap_private(ppix);
+	unsigned int size, tiling, swizzle;
+	dri_bo *bo = intel_get_pixmap_bo(ppix), *newbo;
+	int stride;
+	int handle;
+
+	if (drm_intel_bo_references(intel->batch_bo, bo))
+		intel_batch_submit(intel->scrn);
+
+	drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
+
+	if (tiling == I915_TILING_X) {
+	        tiling = I915_TILING_NONE;
+
+		size = intel_uxa_pixmap_compute_size(ppix, ppix->drawable.width, ppix->drawable.height, &tiling, &stride, INTEL_CREATE_PIXMAP_DRI2);
+
+		newbo = drm_intel_bo_alloc_for_render(intel->bufmgr,
+						      "pixmap",
+						      size, 0);
+
+		if (tiling != I915_TILING_NONE)
+			drm_intel_bo_set_tiling(newbo, &tiling, stride);
+		priv->stride = stride;
+		priv->tiling = tiling;
+		intel_set_pixmap_bo(ppix, newbo);
+
+		ppix->drawable.pScreen->ModifyPixmapHeader(ppix, ppix->drawable.width,
+					   ppix->drawable.height, 0, 0,
+					   stride, NULL);
+		bo = newbo;
+	}
+	drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
+	drm_intel_bo_gem_export_to_prime(bo, &handle);
+
+	*fd_handle = (void *)(long)handle;
+	return TRUE;
+}
+
+static Bool
+intel_uxa_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(ppix->drawable.pScreen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	dri_bo *bo;
+	int ihandle = (int)(long)fd_handle;
+
+	/* force untiled for now */
+	bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, ihandle, 0);
+	if (!bo)
+		return FALSE;
+
+	intel_set_pixmap_bo(ppix, bo);
+	close(ihandle);
+	return TRUE;
+}
+#endif
+
 static void
 intel_limits_init(intel_screen_private *intel)
 {
@@ -1314,6 +1382,11 @@ Bool intel_uxa_init(ScreenPtr screen)
 	screen->CreatePixmap = intel_uxa_create_pixmap;
 	screen->DestroyPixmap = intel_uxa_destroy_pixmap;
 
+#ifdef CREATE_PIXMAP_USAGE_SHARED
+	screen->SharePixmapBacking = intel_uxa_share_pixmap_backing;
+	screen->SetSharedPixmapBacking = intel_uxa_set_shared_pixmap_backing;
+#endif
+
 	if (!uxa_driver_init(screen, intel->uxa_driver)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "UXA initialization failed\n");
commit 0768ac4d195214825137152893deb74a87fcd11e
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jul 25 16:11:23 2012 +1000

    intel: add platform probing support.
    
    This allows the driver to be loaded by the platform loading code.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/intel_driver.c b/src/intel_driver.c
index c5be679..76d56d9 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -452,7 +452,14 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 		return FALSE;
 
 	pEnt = xf86GetEntityInfo(scrn->entityList[0]);
-	if (pEnt == NULL || pEnt->location.type != BUS_PCI)
+	if (pEnt == NULL)
+		return NULL;
+
+	if (pEnt->location.type != BUS_PCI
+#ifdef XSERVER_PLATFORM_BUS
+	    && pEnt->location.type != BUS_PLATFORM
+#endif
+		)
 		return FALSE;
 
 	if (flags & PROBE_DETECT)
diff --git a/src/intel_module.c b/src/intel_module.c
index e5f98d4..cfd92e9 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -47,6 +47,10 @@
 #include "legacy/legacy.h"
 #include "sna/sna_module.h"
 
+#ifdef XSERVER_PLATFORM_BUS
+#include <xf86platformBus.h>
+#endif
+
 static const struct intel_device_info intel_generic_info = {
 	.gen = -1,
 };
@@ -525,6 +529,47 @@ static Bool intel_pci_probe(DriverPtr		driver,
 	}
 }
 
+#ifdef XSERVER_PLATFORM_BUS
+static Bool
+intel_platform_probe(DriverPtr driver,
+		     int entity_num, int flags,
+		     struct xf86_platform_device *dev,
+		     intptr_t match_data)
+{
+	ScrnInfoPtr scrn = NULL;
+	char *path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH);
+
+	if (!dev->pdev)
+		return FALSE;
+	/* if we get any flags we don't understand fail to probe for now */
+	if (flags)
+		return FALSE;
+
+	scrn = xf86AllocateScreen(driver, 0);
+	xf86AddEntityToScreen(scrn, entity_num);
+
+	scrn->driverVersion = INTEL_VERSION;
+	scrn->driverName = INTEL_DRIVER_NAME;
+	scrn->name = INTEL_NAME;
+	scrn->driverPrivate = (void *)(match_data | 1);
+	scrn->Probe = NULL;
+	switch (get_accel_method()) {
+#if USE_SNA
+        case SNA: sna_init_scrn(scrn, entity_num); break;
+#endif
+
+#if USE_UXA
+        case UXA: intel_init_scrn(scrn); break;
+#endif
+	default: break;
+	}
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO,
+		   "using drv %s\n", path ? path : "Default device");
+	return scrn != NULL;
+}
+#endif
+
 #ifdef XFree86LOADER
 
 static MODULESETUPPROTO(intel_setup);
@@ -569,7 +614,10 @@ static DriverRec intel = {
 	0,
 	intel_driver_func,
 	intel_device_match,
-	intel_pci_probe
+	intel_pci_probe,
+#ifdef XSERVER_PLATFORM_BUS
+	intel_platform_probe
+#endif
 };
 
 static pointer intel_setup(pointer module,


More information about the xorg-commit mailing list