rpms/xorg-x11-drv-intel/devel dri2-page-flip.patch, NONE, 1.1 xorg-x11-drv-intel.spec, 1.19, 1.20
Kristian Høgsberg
krh at fedoraproject.org
Sun Aug 9 00:53:26 UTC 2009
- Previous message (by thread): rpms/xfce4-xkb-plugin/F-10 xxp-0.5.2-xklavier-api.patch, NONE, 1.1 .cvsignore, 1.10, 1.11 sources, 1.10, 1.11 xfce4-xkb-plugin.spec, 1.17, 1.18
- Next message (by thread): rpms/kdepim/devel kdepim.spec,1.228,1.229
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: krh
Update of /cvs/pkgs/rpms/xorg-x11-drv-intel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv28330
Modified Files:
xorg-x11-drv-intel.spec
Added Files:
dri2-page-flip.patch
Log Message:
* Fri Aug 7 2009 Kristian Høgsberg <krh at redhat.com> - 2.8.0-4
- Add dri2-page-flip.patch to enable full screen pageflipping.
Fixes XKCD #619.
dri2-page-flip.patch:
drmmode_display.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
i830.h | 6 ++
i830_dri.c | 62 ++++++++++++++++++++++++--
i830_dri.h | 6 ++
4 files changed, 194 insertions(+), 6 deletions(-)
--- NEW FILE dri2-page-flip.patch ---
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 814743b..05541de 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -30,6 +30,7 @@
#endif
#include <errno.h>
+#include <poll.h>
#include <sys/ioctl.h>
@@ -43,6 +44,11 @@ typedef struct {
uint32_t fb_id;
drmModeResPtr mode_res;
int cpp;
+
+ drmEventContext event_context;
+ void *swap_data;
+ int old_fb_id;
+ int flip_count;
} drmmode_rec, *drmmode_ptr;
typedef struct {
@@ -343,6 +349,7 @@ static PixmapPtr
drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
{
ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
unsigned long rotate_pitch;
@@ -375,12 +382,16 @@ drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
if (drmmode_crtc->rotate_bo)
i830_set_pixmap_bo(rotate_pixmap, drmmode_crtc->rotate_bo);
+ pI830->shadow_present = TRUE;
+
return rotate_pixmap;
}
static void
drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
@@ -398,6 +409,7 @@ drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *dat
dri_bo_unreference(drmmode_crtc->rotate_bo);
drmmode_crtc->rotate_bo = NULL;
}
+ pI830->shadow_present = FALSE;
}
static void
@@ -1085,15 +1097,111 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
return FALSE;
}
+Bool
+drmmode_do_pageflip(DrawablePtr pDraw, dri_bo *new_front, dri_bo *old_front,
+ void *data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+ int i;
+ unsigned int crtc_id;
+
+ /*
+ * Create a new handle for the back buffer
+ */
+ drmmode->old_fb_id = drmmode->fb_id;
+ if (drmModeAddFB(drmmode->fd, pScrn->virtualX, pScrn->virtualY,
+ pScrn->depth, pScrn->bitsPerPixel, pitch,
+ new_front->handle, &drmmode->fb_id))
+ goto error_out;
+
+ /*
+ * Queue flips on all enabled CRTCs
+ * Note that if/when we get per-CRTC buffers, we'll have to update this.
+ * Right now it assumes a single shared fb across all CRTCs, with the
+ * kernel fixing up the offset of each CRTC as necessary.
+ *
+ * Also, flips queued on disabled or incorrectly configured displays
+ * may never complete; this is a configuration error.
+ */
+ drmmode->flip_count = 0;
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ drmmode_crtc = crtc->driver_private;
+ crtc_id = drmmode_crtc->mode_crtc->crtc_id;
+ drmmode->swap_data = data;
+ if (drmModePageFlip(drmmode->fd, crtc_id, drmmode->fb_id, drmmode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "flip queue failed: %s\n", strerror(errno));
+ goto error_undo;
+ }
+ drmmode->flip_count++;
+ }
+
+ pScrn->fbOffset = new_front->offset;
+ pI830->front_buffer->bo = new_front;
+ pI830->front_buffer->offset = new_front->offset;
+
+ return TRUE;
+
+error_undo:
+ drmModeRmFB(drmmode->fd, drmmode->fb_id);
+ drmmode->fb_id = drmmode->old_fb_id;
+
+error_out:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
+ strerror(errno));
+ return FALSE;
+}
+
static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
drmmode_xf86crtc_resize
};
+static void
+drmmode_page_flip_handler(int fd,
+ unsigned int frame,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data)
+{
+ drmmode_ptr drmmode = user_data;
+
+ drmmode->flip_count--;
+ if (drmmode->flip_count > 0)
+ return;
+
+ drmModeRmFB(drmmode->fd, drmmode->old_fb_id);
+
+ DRI2SwapComplete(drmmode->swap_data);
+}
+
+static void
+drm_wakeup_handler(pointer data, int err, pointer p)
+{
+ drmmode_ptr drmmode = data;
+ fd_set *read_mask = p;
+
+ if (err >= 0 && FD_ISSET(drmmode->fd, read_mask))
+ drmHandleEvent(drmmode->fd, &drmmode->event_context);
+}
+
Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
{
xf86CrtcConfigPtr xf86_config;
+ I830Ptr pI830 = I830PTR(pScrn);
drmmode_ptr drmmode;
- int i;
+ unsigned int i, bad_crtc = 0;
+ int ret;
drmmode = xnfalloc(sizeof *drmmode);
drmmode->fd = fd;
@@ -1120,6 +1227,22 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
xf86InitialConfiguration(pScrn, TRUE);
+ /* Check for swapbuffers support */
+ ret = drmModePageFlip(drmmode->fd, bad_crtc, 1, NULL);
+ if (ret < 0 && errno == ENOENT) { /* bad CRTC or FB number */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Kernel page flipping support detected, enabling\n");
+ pI830->use_swap_buffers = TRUE;
+
+ drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
+ drmmode->event_context.page_flip_handler =
+ drmmode_page_flip_handler;
+ AddGeneralSocket(fd);
+ RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+ drm_wakeup_handler,
+ drmmode);
+ }
+
return TRUE;
}
diff --git a/src/i830.h b/src/i830.h
index 58afe76..16e3c55 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -65,6 +65,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "sarea.h"
#define _XF86DRI_SERVER_
#include "dri.h"
+#include "dri2.h"
#include "GL/glxint.h"
#include "i830_dri.h"
#include "intel_bufmgr.h"
@@ -395,6 +396,7 @@ typedef struct _I830Rec {
#endif
XF86ModReqInfo shadowReq; /* to test for later libshadow */
+ Bool shadow_present;
Rotation rotation;
void (*PointerMoved)(int, int, int);
CreateScreenResourcesProcPtr CreateScreenResources;
@@ -496,6 +498,8 @@ typedef struct _I830Rec {
int drmSubFD;
char deviceName[64];
+ Bool use_swap_buffers;
+
/* Broken-out options. */
OptionInfoPtr Options;
@@ -691,6 +695,8 @@ void I830DRI2CloseScreen(ScreenPtr pScreen);
extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
extern int drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
extern int drmmode_output_dpms_status(xf86OutputPtr output);
+extern Bool drmmode_do_pageflip(DrawablePtr pDraw, dri_bo *new_front,
+ dri_bo *old_front, void *data);
extern void drmmode_copy_fb(ScrnInfoPtr pScrn);
extern Bool i830_crtc_on(xf86CrtcPtr crtc);
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 40d11e4..b34b9b7 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -45,6 +45,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -73,11 +75,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
extern XF86ModuleData dri2ModuleData;
#endif
-typedef struct {
- PixmapPtr pPixmap;
- unsigned int attachment;
-} I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr;
-
#ifndef USE_DRI2_1_1_0
static DRI2BufferPtr
I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
@@ -359,6 +356,54 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
}
+#if DRI2INFOREC_VERSION >= 4
+
+/*
+ * DRI2SwapBuffers should try to do a buffer swap if possible, however:
+ * - if we're swapping buffers smaller than the screen, we have to blit
+ * - if the back buffer doesn't match the screen depth, we have to blit
+ * - otherwise we try to swap, and return to the caller the new front
+ * and back buffers
+ */
+static Bool
+I830DRI2SwapBuffers(DrawablePtr pDraw,
+ DRI2BufferPtr front, DRI2BufferPtr back, void *data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830DRI2BufferPrivatePtr front_priv, back_priv;
+ dri_bo *tmp_bo;
+ int tmp;
+
+ front_priv = front->driverPrivate;
+ back_priv = back->driverPrivate;
+
+ if (pI830->shadow_present)
+ return FALSE;
+
+ /* Swap BO names so DRI works */
+ tmp = front->name;
+ front->name = back->name;
+ back->name = tmp;
+
+ /* Swap pixmap bos */
+ dri_bo_reference(i830_get_pixmap_bo(front_priv->pPixmap));
+
+ tmp_bo = i830_get_pixmap_bo(front_priv->pPixmap);
+ i830_set_pixmap_bo(front_priv->pPixmap,
+ i830_get_pixmap_bo(back_priv->pPixmap));
+ i830_set_pixmap_bo(back_priv->pPixmap, tmp_bo); /* should be screen */
+
+ if (front_priv->pPixmap != pScreen->GetScreenPixmap(pScreen))
+ FatalError("swapbuffers with bad front\n");
+
+ /* Page flip the full screen buffer */
+ return drmmode_do_pageflip(pDraw, i830_get_pixmap_bo(front_priv->pPixmap),
+ i830_get_pixmap_bo(back_priv->pPixmap), data);
+}
+#endif
+
Bool I830DRI2ScreenInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -428,6 +473,13 @@ Bool I830DRI2ScreenInit(ScreenPtr pScreen)
# endif
#endif
+#if DRI2INFOREC_VERSION >= 4
+ if (pI830->use_swap_buffers) {
+ info.version = 4;
+ info.SwapBuffers = I830DRI2SwapBuffers;
+ }
+#endif
+
info.CopyRegion = I830DRI2CopyRegion;
return DRI2ScreenInit(pScreen, &info);
diff --git a/src/i830_dri.h b/src/i830_dri.h
index bedbcbe..e35e940 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -2,6 +2,7 @@
#ifndef _I830_DRI_H
#define _I830_DRI_H
+#include "xorg-server.h"
#include "xf86drm.h"
#include "i830_common.h"
@@ -58,4 +59,9 @@ typedef struct {
int dummy;
} I830DRIContextRec, *I830DRIContextPtr;
+typedef struct {
+ PixmapPtr pPixmap;
+ unsigned int attachment;
+} I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr;
+
#endif
Index: xorg-x11-drv-intel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/xorg-x11-drv-intel/devel/xorg-x11-drv-intel.spec,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -p -r1.19 -r1.20
--- xorg-x11-drv-intel.spec 4 Aug 2009 05:58:19 -0000 1.19
+++ xorg-x11-drv-intel.spec 9 Aug 2009 00:53:25 -0000 1.20
@@ -8,7 +8,7 @@
Summary: Xorg X11 Intel video driver
Name: xorg-x11-drv-intel
Version: 2.8.0
-Release: 3%{?dist}
+Release: 4%{?dist}
URL: http://www.x.org
License: MIT
Group: User Interface/X Hardware Support
@@ -30,6 +30,7 @@ Patch4: intel-abi-fix.patch
Patch20: intel-2.8.0-kms-get-crtc.patch
Patch30: intel-chip-names.patch
+Patch40: dri2-page-flip.patch
ExclusiveArch: %{ix86} x86_64 ia64
@@ -82,6 +83,7 @@ Debugging tools for Intel graphics chips
%patch4 -p1 -b .abi
%patch20 -p1 -b .get-crtc
%patch30 -p1 -b .names
+%patch40 -p1 -b .flip
%build
@@ -137,6 +139,10 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/intel_*.1*
%changelog
+* Fri Aug 7 2009 Kristian Høgsberg <krh at redhat.com> - 2.8.0-4
+- Add dri2-page-flip.patch to enable full screen pageflipping.
+ Fixes XKCD #619.
+
* Tue Aug 04 2009 Dave Airlie <airlied at redhat.com> 2.8.0-3
- add ABI fixes for RAC removal
- Previous message (by thread): rpms/xfce4-xkb-plugin/F-10 xxp-0.5.2-xklavier-api.patch, NONE, 1.1 .cvsignore, 1.10, 1.11 sources, 1.10, 1.11 xfce4-xkb-plugin.spec, 1.17, 1.18
- Next message (by thread): rpms/kdepim/devel kdepim.spec,1.228,1.229
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list