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