[PATCH 2/4] Add glamor back into the driver
Keith Packard
keithp at keithp.com
Fri Sep 26 20:35:33 PDT 2014
This adds glamor support back into the driver, but instad of going
through UXA, this uses it directly instead. Supports DRI2 directly and
DRI3 via glamor.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
configure.ac | 42 ++++++-
src/intel_driver.h | 2 +-
src/intel_module.c | 5 +-
src/uxa/Makefile.am | 46 +++++--
src/uxa/intel.h | 11 ++
src/uxa/intel_display.c | 66 +++++++---
src/uxa/intel_dri.c | 188 +++++++++++++---------------
src/uxa/intel_driver.c | 322 +++++++++++++++++++++++++++++++++++++-----------
src/uxa/intel_glamor.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++
src/uxa/intel_glamor.h | 63 ++++++++++
src/uxa/intel_uxa.c | 122 ++++++++++++++++++
src/uxa/intel_uxa.h | 11 ++
src/uxa/intel_video.c | 65 +++++++---
13 files changed, 1033 insertions(+), 231 deletions(-)
create mode 100644 src/uxa/intel_glamor.c
create mode 100644 src/uxa/intel_glamor.h
diff --git a/configure.ac b/configure.ac
index b762da9..36f6e63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -424,6 +424,22 @@ if test "x$UXA" != "xno"; then
UXA=yes
fi
+AC_ARG_ENABLE(glamor,
+ AS_HELP_STRING([--enable-glamor],
+ [Enable glamor, a new GL-based acceleration [default=no]]),
+ [GLAMOR="$enableval"],
+ [GLAMOR="no"])
+if test "x$GLAMOR" != "xno"; then
+ if pkg-config --exists "xorg-server >= 1.15.99.901"; then
+ GLAMOR="yes (using Xorg glamor module)"
+ else
+ PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.6.0])
+ PKG_CHECK_MODULES(LIBGLAMOR_EGL, [glamor-egl])
+ GLAMOR="yes (using libglamor)"
+ fi
+ AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration])
+fi
+
PKG_CHECK_MODULES(XORG, [xorg-server >= $required_xorg_server_version xproto fontsproto pixman-1 >= $required_pixman_version $REQUIRED_MODULES])
ABI_VERSION=`$PKG_CONFIG --variable=abi_videodrv xorg-server`
@@ -626,6 +642,10 @@ AC_MSG_CHECKING([whether to include UXA support])
AC_MSG_RESULT([$UXA])
AM_CONDITIONAL(UXA, test "x$UXA" != "xno")
+AC_MSG_CHECKING([whether to include GLAMOR support])
+AC_MSG_RESULT([$GLAMOR])
+AM_CONDITIONAL(GLAMOR, test "x$GLAMOR" != "xno")
+
AC_MSG_CHECKING([whether to include SNA support])
AM_CONDITIONAL(SNA, test "x$SNA" != "xno")
AC_MSG_RESULT([$SNA])
@@ -646,7 +666,7 @@ fi
AC_ARG_WITH(default-accel,
AS_HELP_STRING([--with-default-accel],
- [Select the default acceleration method out of none, sna, or uxa [default is sna if enabled, otherwise uxa]]),
+ [Select the default acceleration method out of glamor, none, sna, or uxa [default is sna if enabled, otherwise uxa]]),
[accel="$withval"],
[accel="auto"])
if test "x$accel" = "xyes"; then
@@ -661,6 +681,10 @@ if test "x$accel" = "xauto"; then
else
if test "x$UXA" != "xno"; then
accel="uxa"
+ else
+ if test "x$GLAMOR" != "xno"; then
+ accel="glamor"
+ fi
fi
fi
if test "x$accel" = "xauto" -a "x$KMS" = "xyes"; then
@@ -687,6 +711,15 @@ if test "x$accel" = "xuxa"; then
fi
fi
+if test "x$accel" = "xglamor"; then
+ if test "x$GLAMOR" != "xno"; then
+ AC_DEFINE(DEFAULT_ACCEL_METHOD, GLAMOR, [Default acceleration method])
+ have_accel="yes"
+ else
+ AC_MSG_ERROR([glamor acceleration requested as default, but is not enabled])
+ fi
+fi
+
if test "x$have_accel" = "xnone"; then
if test "x$KMS" = "xyes"; then
if test "x$SNA" != "xno" -o "x$UXA" != "xno"; then
@@ -874,6 +907,13 @@ if test "x$UXA" != "xno"; then
accel_msg="$accel_msg uxa"
fi
fi
+if test "x$GLAMOR" != "xno"; then
+ if test "$accel" = "glamor"; then
+ accel_msg="$accel_msg *glamor"
+ else
+ accel_msg="$accel_msg glamor"
+ fi
+fi
if test "x$dri_msg" = "x"; then
dri_msg=" none"
diff --git a/src/intel_driver.h b/src/intel_driver.h
index 172ebc4..13e2688 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -136,7 +136,7 @@ int intel_put_master(ScrnInfoPtr scrn);
void intel_put_device(ScrnInfoPtr scrn);
#define IS_DEFAULT_ACCEL_METHOD(x) ({ \
- enum { NOACCEL, SNA, UXA } default_accel_method__ = DEFAULT_ACCEL_METHOD; \
+ enum { NOACCEL, SNA, UXA, GLAMOR } default_accel_method__ = DEFAULT_ACCEL_METHOD; \
default_accel_method__ == x; \
})
diff --git a/src/intel_module.c b/src/intel_module.c
index d7b42f6..57ac5ef 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -489,7 +489,7 @@ _xf86findDriver(const char *ident, XF86ConfDevicePtr p)
return NULL;
}
-static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
+static enum accel_method { NOACCEL, SNA, UXA, GLAMOR } get_accel_method(void)
{
enum accel_method accel_method = DEFAULT_ACCEL_METHOD;
XF86ConfDevicePtr dev;
@@ -509,6 +509,8 @@ static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
accel_method = SNA;
else if (strcasecmp(s, "uxa") == 0)
accel_method = UXA;
+ else if (strcasecmp(s, "glamor") == 0)
+ accel_method = GLAMOR;
}
}
@@ -570,6 +572,7 @@ intel_scrn_create(DriverPtr driver,
#if !USE_SNA
case NOACCEL:
#endif
+ case GLAMOR:
case UXA:
return intel_init_scrn(scrn);
#endif
diff --git a/src/uxa/Makefile.am b/src/uxa/Makefile.am
index 426f598..5d342d3 100644
--- a/src/uxa/Makefile.am
+++ b/src/uxa/Makefile.am
@@ -25,21 +25,26 @@ AM_CFLAGS += -I$(top_srcdir)/xvmc -I$(top_srcdir)/src -I$(top_srcdir)/src/render
noinst_LTLIBRARIES = libuxa.la
libuxa_la_LIBADD = $(UDEV_LIBS) $(DRMINTEL_LIBS) $(DRM_LIBS)
libuxa_la_SOURCES = \
- intel_uxa.h \
- brw_defines.h \
- brw_structs.h \
common.h \
intel.h \
- intel_batchbuffer.c \
- intel_batchbuffer.h \
intel_display.c \
intel_driver.c \
+ intel_glamor.h \
intel_memory.c \
- intel_uxa.c \
intel_video.c \
intel_video.h \
intel_video_overlay.c \
intel_video_overlay.h \
+ $(NULL)
+
+if UXA
+libuxa_la_SOURCES += \
+ intel_uxa.h \
+ intel_batchbuffer.c \
+ intel_batchbuffer.h \
+ brw_defines.h \
+ brw_structs.h \
+ intel_uxa.c \
intel_uxa_video.c \
i830_3d.c \
i830_render.c \
@@ -60,8 +65,18 @@ libuxa_la_SOURCES = \
uxa-glyphs.c \
uxa-render.c \
uxa-priv.h \
- uxa-unaccel.c
+ uxa-unaccel.c \
+ $(NULL)
+endif
+
+if GLAMOR
+AM_CFLAGS += $(LIBGLAMOR_CFLAGS)
+libuxa_la_LIBADD += $(LIBGLAMOR_LIBS)
+libuxa_la_SOURCES += \
+ intel_glamor.h \
+ intel_glamor.c \
$(NULL)
+endif
if DRI2
AM_CFLAGS += $(DRI2_CFLAGS)
@@ -74,6 +89,17 @@ libuxa_la_LIBADD += \
$(NULL)
endif
+if UXA
+
+if XVMC
+AM_CFLAGS += -I$(top_srcdir)/xvmc
+libuxa_la_SOURCES += \
+ intel_hwmc.c \
+ $(NULL)
+endif
+
+endif
+
if DRI3
libuxa_la_SOURCES += \
intel_dri3.c \
@@ -87,9 +113,3 @@ libuxa_la_SOURCES += \
$(NULL)
endif
-if XVMC
-AM_CFLAGS += -I$(top_srcdir)/xvmc
-libuxa_la_SOURCES += \
- intel_hwmc.c \
- $(NULL)
-endif
diff --git a/src/uxa/intel.h b/src/uxa/intel.h
index 52de980..3c1a321 100644
--- a/src/uxa/intel.h
+++ b/src/uxa/intel.h
@@ -111,10 +111,21 @@ enum dri_type {
DRI_ACTIVE
};
+enum accel_type {
+#if USE_GLAMOR
+ ACCEL_GLAMOR,
+#endif
+#if USE_UXA
+ ACCEL_UXA,
+#endif
+};
+
typedef struct intel_screen_private {
ScrnInfoPtr scrn;
int cpp;
+ enum accel_type accel;
+
#define RENDER_BATCH I915_EXEC_RENDER
#define BLT_BATCH I915_EXEC_BLT
unsigned int current_batch;
diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index 395774a..e9efa0d 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -60,6 +60,10 @@
#include "intel_uxa.h"
#endif
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
+
#define KNOWN_MODE_FLAGS ((1<<14)-1)
struct intel_drm_queue {
@@ -688,7 +692,10 @@ intel_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
return TRUE;
}
- bo = intel_get_pixmap_bo(ppix);
+ bo = intel_get_pixmap_bo(ppix);
+ if (!bo)
+ return FALSE;
+
if (intel->front_buffer) {
ErrorF("have front buffer\n");
}
@@ -1611,8 +1618,20 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
scrn->virtualX = width;
scrn->virtualY = height;
- if (!intel_uxa_create_screen_resources(scrn->pScreen))
- goto fail;
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ if (!intel_glamor_create_screen_resources(scrn->pScreen))
+ goto fail;
+ break;
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
+ if (!intel_uxa_create_screen_resources(scrn->pScreen))
+ goto fail;
+ break;
+#endif
+ }
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
@@ -2440,6 +2459,27 @@ out_free_fb:
return pixmap;
}
+static Bool
+intel_copy_pixmap(PixmapPtr src, PixmapPtr dst) {
+ ScrnInfoPtr scrn = xf86ScreenToScrn(dst->drawable.pScreen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ Bool ret = FALSE;
+
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ ret = intel_glamor_copy_pixmap(src, dst);
+ break;
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
+ ret = intel_uxa_copy_pixmap(src, dst);
+ break;
+#endif
+ }
+ return ret;
+}
+
void intel_copy_fb(ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -2450,9 +2490,6 @@ void intel_copy_fb(ScrnInfoPtr scrn)
struct intel_crtc *intel_crtc;
int i, fbcon_id;
- if (intel->force_fallback)
- return;
-
fbcon_id = 0;
for (i = 0; i < xf86_config->num_crtc; i++) {
intel_crtc = xf86_config->crtc[i]->driver_private;
@@ -2474,22 +2511,13 @@ void intel_copy_fb(ScrnInfoPtr scrn)
if (dst == NullPixmap)
goto cleanup_src;
- if (!intel->uxa_driver->prepare_copy(src, dst,
- -1, -1,
- GXcopy, FB_ALLONES))
- goto cleanup_dst;
-
- intel->uxa_driver->copy(dst,
- 0, 0,
- 0, 0,
- scrn->virtualX, scrn->virtualY);
- intel->uxa_driver->done_copy(dst);
+ if (intel_copy_pixmap(src, dst)) {
#if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0)
- pScreen->canDoBGNoneRoot = TRUE;
+ pScreen->canDoBGNoneRoot = TRUE;
#endif
+ }
-cleanup_dst:
- (*pScreen->DestroyPixmap)(dst);
+ (*pScreen->DestroyPixmap)(dst);
cleanup_src:
(*pScreen->DestroyPixmap)(src);
}
diff --git a/src/uxa/intel_dri.c b/src/uxa/intel_dri.c
index b302221..f191af7 100644
--- a/src/uxa/intel_dri.c
+++ b/src/uxa/intel_dri.c
@@ -69,6 +69,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#if USE_UXA
#include "intel_uxa.h"
#endif
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
typedef struct {
int refcnt;
@@ -83,16 +86,28 @@ static int i830_client_key;
static uint32_t pixmap_flink(PixmapPtr pixmap)
{
- struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap);
+ dri_bo *bo = intel_get_pixmap_bo(pixmap);
uint32_t name;
- if (priv == NULL || priv->bo == NULL)
+ if (bo == NULL)
return 0;
- if (dri_bo_flink(priv->bo, &name) != 0)
+ if (dri_bo_flink(bo, &name) != 0)
return 0;
- priv->pinned |= PIN_DRI2;
+#if USE_UXA
+ switch (intel_get_screen_private(xf86ScreenToScrn(pixmap->drawable.pScreen))->accel) {
+ case ACCEL_UXA:
+ {
+ struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap);
+ priv->pinned |= PIN_DRI2;
+
+ break;
+ }
+ default:
+ break;
+ }
+#endif
return name;
}
@@ -381,81 +396,15 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
(*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0);
ValidateGC(dst, gc);
- /* Wait for the scanline to be outside the region to be copied */
- if (scrn->vtSema &&
- pixmap_is_scanout(get_drawable_pixmap(dst)) &&
- intel->swapbuffers_wait && INTEL_INFO(intel)->gen < 060) {
- BoxPtr box;
- BoxRec crtcbox;
- int y1, y2;
- int event, load_scan_lines_pipe;
- xf86CrtcPtr crtc;
- Bool full_height = FALSE;
-
- box = REGION_EXTENTS(unused, gc->pCompositeClip);
- crtc = intel_covering_crtc(scrn, box, NULL, &crtcbox);
-
- /*
- * Make sure the CRTC is valid and this is the real front
- * buffer
- */
- if (crtc != NULL && !crtc->rotatedData) {
- int pipe = intel_crtc_to_pipe(crtc);
-
- /*
- * Make sure we don't wait for a scanline that will
- * never occur
- */
- y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0;
- y2 = (box->y2 <= crtcbox.y2) ?
- box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1;
-
- if (y1 == 0 && y2 == (crtcbox.y2 - crtcbox.y1))
- full_height = TRUE;
-
- /*
- * Pre-965 doesn't have SVBLANK, so we need a bit
- * of extra time for the blitter to start up and
- * do its job for a full height blit
- */
- if (full_height && INTEL_INFO(intel)->gen < 040)
- y2 -= 2;
-
- if (pipe == 0) {
- event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
- load_scan_lines_pipe =
- MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
- if (full_height && INTEL_INFO(intel)->gen >= 040)
- event = MI_WAIT_FOR_PIPEA_SVBLANK;
- } else {
- event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
- load_scan_lines_pipe =
- MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
- if (full_height && INTEL_INFO(intel)->gen >= 040)
- event = MI_WAIT_FOR_PIPEB_SVBLANK;
- }
-
- if (crtc->mode.Flags & V_INTERLACE) {
- /* DSL count field lines */
- y1 /= 2;
- y2 /= 2;
- }
-
- BEGIN_BATCH(5);
- /*
- * The documentation says that the LOAD_SCAN_LINES
- * command always comes in pairs. Don't ask me why.
- */
- OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
- load_scan_lines_pipe);
- OUT_BATCH((y1 << 16) | (y2-1));
- OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
- load_scan_lines_pipe);
- OUT_BATCH((y1 << 16) | (y2-1));
- OUT_BATCH(MI_WAIT_FOR_EVENT | event);
- ADVANCE_BATCH();
- }
- }
+ switch (intel->accel) {
+#if USE_UXA
+ case ACCEL_UXA:
+ intel_uxa_wait_scanline(dst, gc);
+ break;
+#endif
+ default:
+ break;
+ }
/* It's important that this copy gets submitted before the
* direct rendering client submits rendering for the next
@@ -477,7 +426,7 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
/* And make sure the WAIT_FOR_EVENT is queued before any
* modesetting/dpms operations on the pipe.
*/
- intel_batch_submit(scrn);
+ intel_flush(intel);
}
static void
@@ -671,10 +620,9 @@ i830_dri2_del_frame_event(DRI2FrameEventPtr info)
free(info);
}
-static struct intel_uxa_pixmap *
+static void
intel_exchange_pixmap_buffers(struct intel_screen_private *intel, PixmapPtr front, PixmapPtr back)
{
- struct intel_uxa_pixmap *new_front = NULL, *new_back;
RegionRec region;
/* Post damage on the front buffer so that listeners, such
@@ -687,16 +635,20 @@ intel_exchange_pixmap_buffers(struct intel_screen_private *intel, PixmapPtr fron
region.data = NULL;
DamageRegionAppend(&front->drawable, ®ion);
- new_front = intel_uxa_get_pixmap_private(back);
- new_back = intel_uxa_get_pixmap_private(front);
- intel_uxa_set_pixmap_private(front, new_front);
- intel_uxa_set_pixmap_private(back, new_back);
- new_front->busy = 1;
- new_back->busy = -1;
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ intel_glamor_exchange_buffers(intel, front, back);
+ break;
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
+ intel_uxa_exchange_buffers(intel, front, back);
+ break;
+#endif
+ }
DamageRegionProcessPending(&front->drawable);
-
- return new_front;
}
static void
@@ -704,7 +656,6 @@ I830DRI2ExchangeBuffers(struct intel_screen_private *intel, DRI2BufferPtr front,
{
I830DRI2BufferPrivatePtr front_priv, back_priv;
int tmp;
- struct intel_uxa_pixmap *new_front;
front_priv = front->driverPrivate;
back_priv = back->driverPrivate;
@@ -715,11 +666,12 @@ I830DRI2ExchangeBuffers(struct intel_screen_private *intel, DRI2BufferPtr front,
back->name = tmp;
/* Swap pixmap bos */
- new_front = intel_exchange_pixmap_buffers(intel,
- front_priv->pixmap,
- back_priv->pixmap);
+ intel_exchange_pixmap_buffers(intel,
+ front_priv->pixmap,
+ back_priv->pixmap);
+
dri_bo_unreference (intel->front_buffer);
- intel->front_buffer = new_front->bo;
+ intel->front_buffer = intel_get_pixmap_bo(front_priv->pixmap);
dri_bo_reference (intel->front_buffer);
}
@@ -797,6 +749,26 @@ I830DRI2ScheduleFlip(struct intel_screen_private *intel,
drm_intel_bo_disable_reuse(new_back);
dri_bo_flink(new_back, &intel->back_name);
+#if USE_GLAMOR
+ if (intel->accel == ACCEL_GLAMOR) {
+ I830DRI2BufferPrivatePtr drvpriv;
+ PixmapPtr front_pixmap, back_pixmap;
+ ScreenPtr screen;
+
+ screen = draw->pScreen;
+ drvpriv = info->front->driverPrivate;
+ front_pixmap = drvpriv->pixmap;
+
+ back_pixmap = intel_glamor_create_back_pixmap(screen,
+ front_pixmap,
+ new_back);
+ if (back_pixmap == NULL) {
+ drm_intel_bo_unreference(new_back);
+ return FALSE;
+ }
+ intel->back_pixmap = back_pixmap;
+ }
+#endif
} else {
new_back = intel->back_buffer;
intel->back_buffer = NULL;
@@ -841,8 +813,6 @@ can_exchange(DrawablePtr drawable, DRI2BufferPtr front, DRI2BufferPtr back)
I830DRI2BufferPrivatePtr back_priv = back->driverPrivate;
PixmapPtr front_pixmap = front_priv->pixmap;
PixmapPtr back_pixmap = back_priv->pixmap;
- struct intel_uxa_pixmap *front_intel = intel_uxa_get_pixmap_private(front_pixmap);
- struct intel_uxa_pixmap *back_intel = intel_uxa_get_pixmap_private(back_pixmap);
if (!pScrn->vtSema)
return FALSE;
@@ -874,12 +844,24 @@ can_exchange(DrawablePtr drawable, DRI2BufferPtr front, DRI2BufferPtr back)
return FALSE;
#endif
- /* prevent an implicit tiling mode change */
- if (front_intel->tiling != back_intel->tiling)
- return FALSE;
-
- if (front_intel->pinned & ~(PIN_SCANOUT | PIN_DRI2))
- return FALSE;
+ switch (intel->accel) {
+#if USE_UXA
+ case ACCEL_UXA:
+ {
+ struct intel_uxa_pixmap *front_intel = intel_uxa_get_pixmap_private(front_pixmap);
+ struct intel_uxa_pixmap *back_intel = intel_uxa_get_pixmap_private(back_pixmap);
+ /* prevent an implicit tiling mode change */
+ if (front_intel->tiling != back_intel->tiling)
+ return FALSE;
+
+ if (front_intel->pinned & ~(PIN_SCANOUT | PIN_DRI2))
+ return FALSE;
+ break;
+ }
+#endif
+ default:
+ break;
+ }
return TRUE;
}
diff --git a/src/uxa/intel_driver.c b/src/uxa/intel_driver.c
index eb9dc45..2e78fb3 100644
--- a/src/uxa/intel_driver.c
+++ b/src/uxa/intel_driver.c
@@ -72,6 +72,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "intel_uxa.h"
#endif
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
+
#include "intel_options.h"
#include "i915_drm.h"
@@ -162,8 +166,20 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
if (!(*screen->CreateScreenResources) (screen))
return FALSE;
- if (!intel_uxa_create_screen_resources(screen))
- return FALSE;
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ if (!intel_glamor_create_screen_resources(screen))
+ return FALSE;
+ break;
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
+ if (!intel_uxa_create_screen_resources(screen))
+ return FALSE;
+ break;
+#endif
+ }
intel_copy_fb(scrn);
return TRUE;
@@ -172,19 +188,62 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
void
intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo)
{
- intel_uxa_set_pixmap_bo(pixmap, bo);
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ intel_glamor_set_pixmap_bo(pixmap, bo);
+ break;
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
+ intel_uxa_set_pixmap_bo(pixmap, bo);
+ break;
+#endif
+ default:
+ ErrorF("No accel architecture, cannot set pixmap bo\n");
+ break;
+ }
}
dri_bo *
intel_get_pixmap_bo(PixmapPtr pixmap)
{
- return intel_uxa_get_pixmap_bo(pixmap);
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ return intel_glamor_get_pixmap_bo(pixmap);
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
+ return intel_uxa_get_pixmap_bo(pixmap);
+#endif
+ default:
+ ErrorF("No accel architecture, cannot set pixmap bo\n");
+ return NULL;
+ }
}
void
intel_flush(intel_screen_private *intel)
{
- intel_batch_submit(intel->scrn);
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ intel_glamor_flush(intel);
+ break;
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
+ intel_batch_submit(intel->scrn);
+ break;
+#endif
+ }
}
static void PreInitCleanup(ScrnInfoPtr scrn)
@@ -202,6 +261,41 @@ static void intel_check_chipset_option(ScrnInfoPtr scrn)
intel_detect_chipset(scrn, intel->pEnt);
}
+static void intel_check_accel_option(ScrnInfoPtr scrn)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ enum { NOACCEL, SNA, UXA, GLAMOR } accel_method = DEFAULT_ACCEL_METHOD;
+ const char *s;
+
+ s = xf86GetOptValString(intel->Options, OPTION_ACCEL_METHOD);
+ if (s != NULL) {
+#if USE_GLAMOR
+ if (strcasecmp(s, "glamor") == 0)
+ accel_method = GLAMOR;
+ else
+#endif
+#if USE_UXA
+ if (strcasecmp(s, "uxa") == 0)
+ accel_method = UXA;
+ else
+#endif
+ accel_method = DEFAULT_ACCEL_METHOD;
+ }
+ switch (accel_method) {
+ default:
+#if USE_GLAMOR
+ case GLAMOR:
+ intel->accel = ACCEL_GLAMOR;
+ break;
+#endif
+#if USE_UXA
+ case UXA:
+ intel->accel = ACCEL_UXA;
+ break;
+#endif
+ }
+}
+
static Bool I830GetEarlyOptions(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -526,6 +620,7 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
intel_setup_capabilities(scrn);
intel_check_chipset_option(scrn);
intel_check_dri_option(scrn);
+ intel_check_accel_option(scrn);
if (!intel_init_bufmgr(intel)) {
PreInitCleanup(scrn);
@@ -612,14 +707,37 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
return FALSE;
}
- /* Load the dri modules if requested. */
-#if HAVE_DRI2
- if (intel->dri2 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri2"))
- intel->dri2 = DRI_DISABLED;
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ if (!intel_glamor_pre_init(scrn)) {
+ PreInitCleanup(scrn);
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to pre init glamor display.\n");
+ intel->accel = ACCEL_UXA;
+ }
+ break;
#endif
+ default:
+ break;
+ }
+
+ switch (intel->accel) {
+#if USE_UXA
+ case ACCEL_UXA:
#if HAVE_DRI3
- if (intel->dri3 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri3"))
- intel->dri3 = DRI_DISABLED;
+ if (intel->dri3 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri3"))
+ intel->dri3 = DRI_DISABLED;
+#endif
+ break;
+#endif
+ default:
+ break;
+ }
+
+#if HAVE_DRI2
+ if (intel->dri2 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri2"))
+ intel->dri2 = DRI_DISABLED;
#endif
return TRUE;
@@ -849,9 +967,11 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
intel_screen_private *intel = intel_get_screen_private(scrn);
VisualPtr visual;
+#if USE_UXA
#ifdef INTEL_XVMC
MessageType from;
#endif
+#endif
struct pci_device *const device = intel->PciInfo;
int fb_bar = IS_GEN2(intel) ? 0 : 2;
@@ -903,22 +1023,40 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
xf86SetBlackWhitePixels(screen);
- if (!intel_uxa_init(screen)) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Hardware acceleration initialization failed\n");
- return FALSE;
- }
-
-#if HAVE_DRI2
- if (intel->dri2 == DRI_NONE && I830DRI2ScreenInit(screen))
- intel->dri2 = DRI_ACTIVE;
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ if (!intel_glamor_init(screen)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Glamor acceleration initialization failed\n");
+ return FALSE;
+ }
+ /* XXX indirect GL under Glamor doesn't work because of recursion during
+ * buffer creation
+ */
+ enableIndirectGLX = FALSE;
+ break;
#endif
-
+#if USE_UXA
+ case ACCEL_UXA:
+ if (!intel_uxa_init(screen)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Hardware acceleration initialization failed\n");
+ return FALSE;
+ }
#if HAVE_DRI3
- if (!intel_sync_init(screen))
- intel->dri3 = DRI_DISABLED;
- if (intel->dri3 == DRI_NONE && intel_dri3_screen_init(screen))
- intel->dri3 = DRI_ACTIVE;
+ if (!intel_sync_init(screen))
+ intel->dri3 = DRI_DISABLED;
+ if (intel->dri3 == DRI_NONE && intel_dri3_screen_init(screen))
+ intel->dri3 = DRI_ACTIVE;
+#endif
+ break;
+#endif
+ }
+
+#if HAVE_DRI2
+ if (intel->dri2 == DRI_NONE && I830DRI2ScreenInit(screen))
+ intel->dri2 = DRI_ACTIVE;
#endif
if (xf86ReturnOptValBool(intel->Options, OPTION_PRESENT, TRUE))
@@ -973,19 +1111,6 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
xf86DPMSInit(screen, xf86DPMSSet, 0);
-#ifdef INTEL_XVMC
- if (INTEL_INFO(intel)->gen >= 040)
- intel->XvMCEnabled = TRUE;
- from = (intel->dri2 == DRI_ACTIVE &&
- xf86GetOptValBool(intel->Options, OPTION_XVMC,
- &intel->XvMCEnabled) ? X_CONFIG : X_DEFAULT);
- xf86DrvMsg(scrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
- intel->XvMCEnabled ? "en" : "dis");
-#endif
- /* Init video */
- if (intel->XvEnabled)
- intel_video_init(screen);
-
#if HAVE_DRI2
switch (intel->dri2) {
case DRI_ACTIVE:
@@ -1006,25 +1131,46 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
"DRI2: Not available\n");
#endif
+ switch (intel->accel) {
+#if USE_UXA
+ case ACCEL_UXA:
+#ifdef INTEL_XVMC
+ if (INTEL_INFO(intel)->gen >= 040)
+ intel->XvMCEnabled = TRUE;
+ from = (intel->dri2 == DRI_ACTIVE &&
+ xf86GetOptValBool(intel->Options, OPTION_XVMC,
+ &intel->XvMCEnabled) ? X_CONFIG : X_DEFAULT);
+ xf86DrvMsg(scrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
+ intel->XvMCEnabled ? "en" : "dis");
+#endif
#if HAVE_DRI3
- switch (intel->dri3) {
- case DRI_ACTIVE:
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "DRI3: Enabled\n");
- break;
- case DRI_DISABLED:
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "DRI3: Disabled\n");
- break;
- case DRI_NONE:
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "DRI3: Failed\n");
- break;
- }
+ switch (intel->dri3) {
+ case DRI_ACTIVE:
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "DRI3: Enabled\n");
+ break;
+ case DRI_DISABLED:
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "DRI3: Disabled\n");
+ break;
+ case DRI_NONE:
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "DRI3: Failed\n");
+ break;
+ }
#else
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "DRI3: Not available\n");
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "DRI3: Not available\n");
#endif
+#endif
+ break;
+ default:
+ break;
+ }
+
+ /* Init video */
+ if (intel->XvEnabled)
+ intel_video_init(screen);
if (serverGeneration == 1)
xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options);
@@ -1117,14 +1263,33 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
DeleteCallback(&FlushCallback, intel_flush_callback, scrn);
- TimerFree(intel->cache_expire);
- intel->cache_expire = NULL;
+ switch (intel->accel) {
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ intel_glamor_close_screen(screen);
+ break;
+#endif
+#if USE_UXA
+ case ACCEL_UXA:
- if (intel->uxa_driver) {
- uxa_driver_fini(screen);
- free(intel->uxa_driver);
- intel->uxa_driver = NULL;
- }
+ TimerFree(intel->cache_expire);
+ intel->cache_expire = NULL;
+
+ intel_batch_teardown(scrn);
+
+ if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100)
+ gen4_render_state_cleanup(scrn);
+
+ if (intel->uxa_driver) {
+ uxa_driver_fini(screen);
+ free(intel->uxa_driver);
+ intel->uxa_driver = NULL;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
if (intel->back_pixmap) {
screen->DestroyPixmap(intel->back_pixmap);
@@ -1146,11 +1311,6 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
I830LeaveVT(VT_FUNC_ARGS(0));
}
- intel_batch_teardown(scrn);
-
- if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100)
- gen4_render_state_cleanup(scrn);
-
xf86_cursors_fini(screen);
i965_free_video(scrn);
@@ -1158,17 +1318,29 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
screen->CloseScreen = intel->CloseScreen;
(*screen->CloseScreen) (CLOSE_SCREEN_ARGS);
- if (intel->dri2 == DRI_ACTIVE) {
- I830DRI2CloseScreen(screen);
- intel->dri2 = DRI_NONE;
- }
+#if HAVE_DRI2
+ if (intel->dri2 == DRI_ACTIVE) {
+ I830DRI2CloseScreen(screen);
+ intel->dri2 = DRI_NONE;
+ }
+#endif
- if (intel->dri3 == DRI_ACTIVE) {
- /* nothing to do here? */
- intel->dri3 = DRI_NONE;
- }
+ switch (intel->accel) {
+#if USE_UXA
+ case ACCEL_UXA:
+#if HAVE_DRI3
+ if (intel->dri3 == DRI_ACTIVE) {
+ /* nothing to do here? */
+ intel->dri3 = DRI_NONE;
+ }
+ intel_sync_close(screen);
+#endif
- intel_sync_close(screen);
+ break;
+#endif
+ default:
+ break;
+ }
xf86GARTCloseScreen(scrn->scrnIndex);
diff --git a/src/uxa/intel_glamor.c b/src/uxa/intel_glamor.c
new file mode 100644
index 0000000..893ba9f
--- /dev/null
+++ b/src/uxa/intel_glamor.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright © 2011 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xorg-server.h"
+#include <xf86.h>
+#define GLAMOR_FOR_XORG 1
+#include <glamor.h>
+#include <unistd.h>
+
+#include "intel.h"
+#include "i915_drm.h"
+#include "intel_glamor.h"
+#include "intel_options.h"
+
+struct intel_glamor_pixmap {
+ dri_bo *bo;
+};
+
+static DevPrivateKeyRec intel_glamor_pixmap_key;
+
+static inline struct intel_glamor_pixmap *intel_glamor_get_pixmap(PixmapPtr pixmap)
+{
+ return dixGetPrivateAddr(&pixmap->devPrivates, &intel_glamor_pixmap_key);
+}
+
+dri_bo *
+intel_glamor_get_pixmap_bo(PixmapPtr pixmap)
+{
+ dri_bo *bo = intel_glamor_get_pixmap(pixmap)->bo;
+
+ if (!bo) {
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ CARD16 stride;
+ CARD32 size;
+ int fd;
+
+ fd = glamor_fd_from_pixmap(screen,
+ pixmap,
+ &stride,
+ &size);
+
+ if (fd >= 0) {
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr,
+ fd,
+ size);
+ close(fd);
+ intel_glamor_get_pixmap(pixmap)->bo = bo;
+ }
+ }
+ return bo;
+}
+
+static void
+intel_glamor_reference_pixmap_bo(PixmapPtr pixmap, drm_intel_bo *bo)
+{
+ struct intel_glamor_pixmap *glamor_pixmap = intel_glamor_get_pixmap(pixmap);
+
+ if (glamor_pixmap->bo) {
+ ErrorF("Unreference bo %d size %lu from pixmap %d x %d\n",
+ glamor_pixmap->bo->handle, glamor_pixmap->bo->size, pixmap->drawable.width, pixmap->drawable.height);
+ drm_intel_bo_unreference(glamor_pixmap->bo);
+ glamor_pixmap->bo = NULL;
+ }
+
+ if (bo) {
+ ErrorF("Reference bo %d size %lu from pixmap %d x %d\n",
+ bo->handle, bo->size, pixmap->drawable.width, pixmap->drawable.height);
+ drm_intel_bo_reference(bo);
+ glamor_pixmap->bo = bo;
+ }
+}
+
+Bool
+intel_glamor_set_pixmap_bo(PixmapPtr pixmap, drm_intel_bo *bo)
+{
+ if (bo == NULL || glamor_egl_create_textured_pixmap(pixmap,
+ bo->handle,
+ intel_pixmap_pitch(pixmap)))
+ {
+ intel_glamor_reference_pixmap_bo(pixmap, bo);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+XF86VideoAdaptorPtr intel_glamor_xv_init(ScreenPtr screen, int num_ports)
+{
+ return glamor_xv_init(screen, num_ports);
+}
+
+Bool
+intel_glamor_create_screen_resources(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+ int old_width, old_height, old_pitch;
+ Bool ret;
+
+ if (!glamor_glyphs_init(screen))
+ return FALSE;
+
+ old_width = pixmap->drawable.width;
+ old_height = pixmap->drawable.height;
+ old_pitch = pixmap->devKind;
+
+ if (!screen->ModifyPixmapHeader(pixmap,
+ scrn->virtualX,
+ scrn->virtualY,
+ -1, -1,
+ intel->front_pitch,
+ NULL))
+ return FALSE;
+
+ ret = glamor_egl_create_textured_screen_ext(screen,
+ intel->front_buffer->handle,
+ intel->front_pitch,
+ &intel->back_pixmap);
+
+ if (!ret)
+ goto fail;
+
+ intel_glamor_reference_pixmap_bo(pixmap, intel->front_buffer);
+
+ return TRUE;
+
+fail:
+ screen->ModifyPixmapHeader(pixmap,
+ old_width, old_height, -1, -1, old_pitch, NULL);
+
+ return FALSE;
+}
+
+Bool
+intel_glamor_pre_init(ScrnInfoPtr scrn)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ pointer glamor_module;
+ CARD32 version;
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,0,0,0)
+ if (!xf86LoaderCheckSymbol("glamor_egl_init")) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "glamor requires Load \"glamoregl\" in "
+ "Section \"Module\", disabling.\n");
+ return TRUE;
+ }
+#endif
+
+ /* Load glamor module */
+ glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME);
+ if (!glamor_module) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "glamor not available\n");
+ return TRUE;
+ }
+
+ version = xf86GetModuleVersion(glamor_module);
+ if (version < MODULE_VERSION_NUMERIC(0,3,1)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Incompatible glamor version, required >= 0.3.0.\n");
+ return TRUE;
+ }
+ if (!glamor_egl_init(scrn, intel->drmSubFD)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "glamor detected, failed to initialize egl.\n");
+ return TRUE;
+ }
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "glamor detected, initialising egl layer.\n");
+
+ return TRUE;
+}
+
+Bool
+intel_glamor_init(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+ if (!dixRegisterPrivateKey(&intel_glamor_pixmap_key, PRIVATE_PIXMAP, sizeof (struct intel_glamor_pixmap)))
+ return FALSE;
+
+ if (!glamor_init(screen,
+ GLAMOR_INVERTED_Y_AXIS |
+ GLAMOR_USE_EGL_SCREEN |
+ GLAMOR_USE_SCREEN |
+ GLAMOR_USE_PICTURE_SCREEN))
+ {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to initialize glamor.\n");
+ return FALSE;
+ }
+
+ if (!glamor_egl_init_textured_pixmap(screen)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to initialize textured pixmap of screen for glamor.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+intel_glamor_flush(intel_screen_private * intel)
+{
+ ScreenPtr screen;
+
+ screen = xf86ScrnToScreen(intel->scrn);
+ glamor_block_handler(screen);
+}
+
+Bool
+intel_glamor_close_screen(ScreenPtr screen)
+{
+ return TRUE;
+}
+
+Bool
+intel_glamor_copy_pixmap(PixmapPtr src, PixmapPtr dst)
+{
+ Bool ret = FALSE;
+#if HAS_GLAMOR_COPY
+ int width, height;
+
+ BoxRec box;
+
+ width = min (src->drawable.width, dst->drawable.width);
+ height = min (src->drawable.height, dst->drawable.height);
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = width;
+ box.y2 = height;
+ glamor_copy(&src->drawable,
+ &dst->drawable,
+ NULL,
+ &box,
+ 1,
+ 0, 0,
+ FALSE,
+ FALSE,
+ 0,
+ NULL);
+
+ ret = TRUE;
+#endif
+ return ret;
+}
+
+#if HAVE_DRI2
+void
+intel_glamor_exchange_buffers(struct intel_screen_private *intel,
+ PixmapPtr src,
+ PixmapPtr dst)
+{
+ glamor_egl_exchange_buffers(src, dst);
+}
+
+PixmapPtr
+intel_glamor_create_back_pixmap(ScreenPtr screen,
+ PixmapPtr front_pixmap,
+ drm_intel_bo *back_bo)
+{
+ PixmapPtr back_pixmap;
+
+ back_pixmap = screen->CreatePixmap(screen,
+ 0,
+ 0,
+ front_pixmap->drawable.depth,
+ 0);
+ if (back_pixmap == NULL)
+ return NULL;
+
+ screen->ModifyPixmapHeader(back_pixmap,
+ front_pixmap->drawable.width,
+ front_pixmap->drawable.height,
+ 0, 0,
+ front_pixmap->devKind,
+ 0);
+ if (!intel_glamor_set_pixmap_bo(back_pixmap, back_bo)) {
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Failed to create textured back pixmap.\n");
+ screen->DestroyPixmap(back_pixmap);
+ return NULL;
+ }
+ return back_pixmap;
+}
+#endif
diff --git a/src/uxa/intel_glamor.h b/src/uxa/intel_glamor.h
new file mode 100644
index 0000000..3b05c54
--- /dev/null
+++ b/src/uxa/intel_glamor.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2011 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
+#ifndef INTEL_GLAMOR_H
+#define INTEL_GLAMOR_H
+
+#include <xf86xv.h>
+
+Bool intel_glamor_pre_init(ScrnInfoPtr scrn);
+Bool intel_glamor_init(ScreenPtr screen);
+Bool intel_glamor_create_screen_resources(ScreenPtr screen);
+Bool intel_glamor_close_screen(ScreenPtr screen);
+void intel_glamor_free_screen(int scrnIndex, int flags);
+
+void intel_glamor_flush(intel_screen_private * intel);
+
+#if HAVE_DRI2
+PixmapPtr
+intel_glamor_create_back_pixmap(ScreenPtr screen,
+ PixmapPtr front_pixmap,
+ drm_intel_bo *back_bo);
+
+void intel_glamor_exchange_buffers(struct intel_screen_private *intel, PixmapPtr src, PixmapPtr dst);
+#endif
+
+XF86VideoAdaptorPtr intel_glamor_xv_init(ScreenPtr screen, int num_ports);
+
+dri_bo *
+intel_glamor_get_pixmap_bo(PixmapPtr pixmap);
+
+Bool
+intel_glamor_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo);
+
+Bool
+intel_glamor_copy_pixmap(PixmapPtr src, PixmapPtr dst);
+
+#endif /* INTEL_GLAMOR_H */
diff --git a/src/uxa/intel_uxa.c b/src/uxa/intel_uxa.c
index 657c2b5..b078921 100644
--- a/src/uxa/intel_uxa.c
+++ b/src/uxa/intel_uxa.c
@@ -1396,3 +1396,125 @@ Bool intel_uxa_init(ScreenPtr screen)
intel->flush_rendering = intel_flush_rendering;
return TRUE;
}
+
+void
+intel_uxa_wait_scanline(DrawablePtr dst, GCPtr gc)
+{
+ ScreenPtr screen = dst->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ /* Wait for the scanline to be outside the region to be copied */
+ if (scrn->vtSema &&
+ pixmap_is_scanout(get_drawable_pixmap(dst)) &&
+ intel->swapbuffers_wait && INTEL_INFO(intel)->gen < 060) {
+ BoxPtr box;
+ BoxRec crtcbox;
+ int y1, y2;
+ int event, load_scan_lines_pipe;
+ xf86CrtcPtr crtc;
+ Bool full_height = FALSE;
+
+ box = REGION_EXTENTS(unused, gc->pCompositeClip);
+ crtc = intel_covering_crtc(scrn, box, NULL, &crtcbox);
+
+ /*
+ * Make sure the CRTC is valid and this is the real front
+ * buffer
+ */
+ if (crtc != NULL && !crtc->rotatedData) {
+ int pipe = intel_crtc_to_pipe(crtc);
+
+ /*
+ * Make sure we don't wait for a scanline that will
+ * never occur
+ */
+ y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0;
+ y2 = (box->y2 <= crtcbox.y2) ?
+ box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1;
+
+ if (y1 == 0 && y2 == (crtcbox.y2 - crtcbox.y1))
+ full_height = TRUE;
+
+ /*
+ * Pre-965 doesn't have SVBLANK, so we need a bit
+ * of extra time for the blitter to start up and
+ * do its job for a full height blit
+ */
+ if (full_height && INTEL_INFO(intel)->gen < 040)
+ y2 -= 2;
+
+ if (pipe == 0) {
+ event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
+ load_scan_lines_pipe =
+ MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
+ if (full_height && INTEL_INFO(intel)->gen >= 040)
+ event = MI_WAIT_FOR_PIPEA_SVBLANK;
+ } else {
+ event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
+ load_scan_lines_pipe =
+ MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
+ if (full_height && INTEL_INFO(intel)->gen >= 040)
+ event = MI_WAIT_FOR_PIPEB_SVBLANK;
+ }
+
+ if (crtc->mode.Flags & V_INTERLACE) {
+ /* DSL count field lines */
+ y1 /= 2;
+ y2 /= 2;
+ }
+
+ BEGIN_BATCH(5);
+ /*
+ * The documentation says that the LOAD_SCAN_LINES
+ * command always comes in pairs. Don't ask me why.
+ */
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
+ load_scan_lines_pipe);
+ OUT_BATCH((y1 << 16) | (y2-1));
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
+ load_scan_lines_pipe);
+ OUT_BATCH((y1 << 16) | (y2-1));
+ OUT_BATCH(MI_WAIT_FOR_EVENT | event);
+ ADVANCE_BATCH();
+ }
+ }
+}
+
+void
+intel_uxa_exchange_buffers(struct intel_screen_private *intel,
+ PixmapPtr front,
+ PixmapPtr back)
+{
+ struct intel_uxa_pixmap *new_front = NULL, *new_back;
+
+ new_front = intel_uxa_get_pixmap_private(back);
+ new_back = intel_uxa_get_pixmap_private(front);
+ intel_uxa_set_pixmap_private(front, new_front);
+ intel_uxa_set_pixmap_private(back, new_back);
+ new_front->busy = 1;
+ new_back->busy = -1;
+
+}
+
+Bool
+intel_uxa_copy_pixmap(PixmapPtr src, PixmapPtr dst)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(dst->drawable.pScreen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ if (intel->force_fallback)
+ return FALSE;
+
+ if (!intel->uxa_driver->prepare_copy(src, dst,
+ -1, -1,
+ GXcopy, FB_ALLONES))
+ return FALSE;
+
+ intel->uxa_driver->copy(dst,
+ 0, 0,
+ 0, 0,
+ dst->drawable.width, dst->drawable.height);
+ intel->uxa_driver->done_copy(dst);
+ return TRUE;
+}
diff --git a/src/uxa/intel_uxa.h b/src/uxa/intel_uxa.h
index 3d495ba..e04e911 100644
--- a/src/uxa/intel_uxa.h
+++ b/src/uxa/intel_uxa.h
@@ -296,4 +296,15 @@ void Gen6DisplayVideoTextured(ScrnInfoPtr scrn,
void i965_free_video(ScrnInfoPtr scrn);
+void
+intel_uxa_wait_scanline(DrawablePtr dst, GCPtr gc);
+
+void
+intel_uxa_exchange_buffers(struct intel_screen_private *intel,
+ PixmapPtr front,
+ PixmapPtr back);
+
+Bool
+intel_uxa_copy_pixmap(PixmapPtr src, PixmapPtr dst);
+
#endif /* _INTEL_UXA_H_ */
diff --git a/src/uxa/intel_video.c b/src/uxa/intel_video.c
index ba76453..73920e6 100644
--- a/src/uxa/intel_video.c
+++ b/src/uxa/intel_video.c
@@ -78,7 +78,13 @@
#define _INTEL_XVMC_SERVER_
#include "intel_xvmc.h"
#endif
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
+#if USE_UXA
#include "intel_uxa.h"
+#endif
+
#include "intel_video_overlay.h"
Atom intel_xv_Brightness, intel_xv_Contrast, intel_xv_Saturation, intel_xv_ColorKey, intel_xv_Pipe;
@@ -169,7 +175,7 @@ void intel_video_init(ScreenPtr screen)
* adaptors.
*/
newAdaptors = realloc(adaptors,
- (num_adaptors + 3) * sizeof(XF86VideoAdaptorPtr));
+ (num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr));
if (newAdaptors == NULL) {
free(adaptors);
@@ -183,21 +189,37 @@ void intel_video_init(ScreenPtr screen)
intel_xv_Brightness = MAKE_ATOM("XV_BRIGHTNESS");
intel_xv_Contrast = MAKE_ATOM("XV_CONTRAST");
- /* Set up textured video if we can do it at this depth and we are on
- * supported hardware.
- */
- if (!intel->force_fallback &&
- scrn->bitsPerPixel >= 16 &&
- INTEL_INFO(intel)->gen >= 030 &&
- INTEL_INFO(intel)->gen < 0100) {
- texturedAdaptor = intel_uxa_video_setup_image_textured(screen);
- if (texturedAdaptor != NULL) {
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "Set up textured video\n");
- } else {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Failed to set up textured video\n");
+ switch (intel->accel) {
+#if USE_UXA
+ case ACCEL_UXA:
+ /* Set up textured video if we can do it at this depth and we are on
+ * supported hardware.
+ */
+ if (!intel->force_fallback &&
+ scrn->bitsPerPixel >= 16 &&
+ INTEL_INFO(intel)->gen >= 030 &&
+ INTEL_INFO(intel)->gen < 0100) {
+ texturedAdaptor = intel_uxa_video_setup_image_textured(screen);
+ if (texturedAdaptor != NULL) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "Set up textured video\n");
+ } else {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to set up textured video\n");
+ }
}
+ break;
+#endif
+#if USE_GLAMOR
+ case ACCEL_GLAMOR:
+ texturedAdaptor = intel_glamor_xv_init(screen, 16);
+ if (texturedAdaptor != NULL)
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "Set up textured video using glamor\n");
+ break;
+#endif
+ default:
+ break;
}
overlayAdaptor = intel_video_overlay_setup_image(screen);
@@ -229,9 +251,16 @@ void intel_video_init(ScreenPtr screen)
intel->XvEnabled = FALSE;
}
- if (texturedAdaptor)
- intel_xvmc_adaptor_init(screen);
-
+#if defined(INTEL_XVMC) && defined(USE_UXA)
+ switch (intel->accel) {
+ case ACCEL_UXA:
+ if (texturedAdaptor)
+ intel_xvmc_adaptor_init(screen);
+ break;
+ default:
+ break;
+ }
+#endif
free(adaptors);
}
--
2.1.1
More information about the xorg-devel
mailing list