xf86-video-intel: 6 commits - configure.ac Makefile.am src/common.h src/i915_video.c src/intel_batchbuffer.c src/intel_display.c src/intel_dri.c src/intel_driver.c src/intel.h src/intel_module.c src/intel_uxa.c src/Makefile.am src/sna/blt.c src/sna/kgem.c src/sna/kgem.h src/sna/Makefile.am src/sna/rop.h src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_composite.c src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_io.c
Chris Wilson
ickle at kemper.freedesktop.org
Wed Nov 16 14:16:57 PST 2011
Makefile.am | 8
configure.ac | 20 -
src/Makefile.am | 14
src/common.h | 2
src/i915_video.c | 1
src/intel.h | 6
src/intel_batchbuffer.c | 2
src/intel_display.c | 2
src/intel_dri.c | 2
src/intel_driver.c | 6
src/intel_module.c | 8
src/intel_uxa.c | 2
src/sna/Makefile.am | 3
src/sna/blt.c | 46 ++
src/sna/kgem.c | 38 +
src/sna/kgem.h | 1
src/sna/rop.h | 264 +++++++++++++
src/sna/sna.h | 13
src/sna/sna_accel.c | 2
src/sna/sna_blt.c | 2
src/sna/sna_composite.c | 1
src/sna/sna_display.c | 24 -
src/sna/sna_dri.c | 954 ++++++++++++++++++++++++++----------------------
src/sna/sna_driver.c | 36 -
src/sna/sna_io.c | 1
25 files changed, 942 insertions(+), 516 deletions(-)
New commits:
commit c259144e3fc52d078b0a78107c38f0f3d3a2bbc1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Nov 16 10:28:23 2011 +0000
sna: The block handler is passed an indirect pointer to the timeval
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 4c9f298..45e8fb2 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -582,13 +582,14 @@ static void
sna_block_handler(int i, pointer data, pointer timeout, pointer read_mask)
{
struct sna *sna = data;
- struct timeval *tv = timeout;
+ struct timeval **tv = timeout;
- DBG(("%s\n", __FUNCTION__));
+ DBG(("%s (tv=%ld.%06ld)\n", __FUNCTION__,
+ *tv ? (*tv)->tv_sec : -1, *tv ? (*tv)->tv_usec : 0));
sna->BlockHandler(i, sna->BlockData, timeout, read_mask);
- if (tv == NULL || (tv->tv_usec | tv->tv_sec))
+ if (*tv == NULL || ((*tv)->tv_usec | (*tv)->tv_sec))
sna_accel_block_handler(sna);
}
commit bfd2bb40274d1242001d295a4010211fd51b0fc3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 15 10:38:09 2011 +0000
sna: Correct dependencies for DRI2
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/configure.ac b/configure.ac
index 2c40760..3fd28b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -175,7 +175,7 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
PKG_CHECK_MODULES(XORG, [xorg-server >= $required_xorg_xserver_version xproto fontsproto pixman-1 >= $required_pixman_version $REQUIRED_MODULES])
PKG_CHECK_MODULES(DRM, [libdrm >= 2.4.23])
PKG_CHECK_MODULES(DRI, [xf86driproto], , DRI=no)
-PKG_CHECK_MODULES(DRI2, [dri2proto >= 2.6])
+PKG_CHECK_MODULES(DRI2, [dri2proto >= 2.6],, DRI2=no)
PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10])
sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server`
@@ -218,6 +218,10 @@ else
AC_MSG_ERROR([DRI requested but prerequisites not found])
fi
fi
+AM_CONDITIONAL(DRI2, test x$DRI2 != xno)
+if test "x$DRI2" != "xno"; then
+ AC_DEFINE(USE_DRI2,1,[Enable DRI2 driver support])
+fi
if test "$XVMC" = yes; then
PKG_CHECK_MODULES(XVMCLIB,
diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index 30cedc6..65e85bf 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -74,7 +74,7 @@ libsna_la_SOURCES = \
gen7_render.h \
$(NULL)
-if DRI
+if DRI2
libsna_la_SOURCES += \
sna_dri.c \
$(NULL)
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 19413a9..4c9f298 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -925,7 +925,7 @@ sna_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
xf86DPMSInit(screen, xf86DPMSSet, 0);
sna_video_init(sna, screen);
-#ifdef DRI2
+#if USE_DRI2
sna->directRenderingOpen = sna_dri_open(sna, screen);
if (sna->directRenderingOpen)
xf86DrvMsg(scrn->scrnIndex, X_INFO,
commit 3771387ad11b5842a83e58a4b373c2acdd827bd2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 15 10:32:34 2011 +0000
Compile out UXA if so desired
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/Makefile.am b/Makefile.am
index 29c04fd..48c3477 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,7 +20,13 @@
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
-SUBDIRS = uxa src man
+SUBDIRS = man
+
+if UXA
+SUBDIRS += uxa
+endif
+
+SUBDIRS += src
MAINTAINERCLEANFILES = ChangeLog INSTALL
if HAVE_X11
diff --git a/configure.ac b/configure.ac
index 831f6b3..2c40760 100644
--- a/configure.ac
+++ b/configure.ac
@@ -120,14 +120,13 @@ AC_ARG_ENABLE(kms-only, AS_HELP_STRING([--enable-kms-only],
[KMS_ONLY="$enableval"],
[KMS_ONLY=no])
+AC_MSG_CHECKING([whether to include SNA support])
AC_ARG_ENABLE(sna,
AS_HELP_STRING([--enable-sna],
[Enable SandyBridge's New Acceleration (SNA) [default=no]]),
[SNA="$enableval"],
[SNA=no])
AM_CONDITIONAL(SNA, test x$SNA != xno)
-AC_MSG_CHECKING([whether to include SNA support])
-
required_xorg_xserver_version=1.6
required_pixman_version=0.16
if test "x$SNA" != "xno"; then
@@ -137,6 +136,17 @@ if test "x$SNA" != "xno"; then
fi
AC_MSG_RESULT([$SNA])
+AC_MSG_CHECKING([whether to include UXA support])
+AC_ARG_ENABLE(uxa,
+ AS_HELP_STRING([--enable-uxa],
+ [Enable Unified Acceleration Architecture (UXA) [default=yes]]),
+ [UXA="$enableval"],
+ [UXA=yes])
+AM_CONDITIONAL(UXA, test x$UXA != xno)
+if test "x$UXA" != "xno"; then
+ AC_DEFINE(USE_UXA, 1, [Enable UXA support])
+fi
+AC_MSG_RESULT([$UXA])
AC_ARG_ENABLE(vmap,
AS_HELP_STRING([--enable-vmap],
diff --git a/src/Makefile.am b/src/Makefile.am
index cd1bb36..e5097da 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,13 +27,12 @@ SUBDIRS = xvmc render_program legacy
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = @CWARNFLAGS@ @XORG_CFLAGS@ @UDEV_CFLAGS@ @DRM_CFLAGS@ @DRI_CFLAGS@ \
- @PCIACCESS_CFLAGS@ -I$(top_srcdir)/uxa -I$(top_srcdir)/src/render_program
+ @PCIACCESS_CFLAGS@
intel_drv_la_LTLIBRARIES = intel_drv.la
intel_drv_la_LDFLAGS = -module -avoid-version
intel_drv_ladir = @moduledir@/drivers
-intel_drv_la_LIBADD = @UDEV_LIBS@ -lm @DRM_LIBS@ -ldrm_intel ../uxa/libuxa.la legacy/liblegacy.la
-intel_drv_la_LIBADD += @PCIACCESS_LIBS@
+intel_drv_la_LIBADD = legacy/liblegacy.la @PCIACCESS_LIBS@
if SNA
SUBDIRS += sna
@@ -43,11 +42,17 @@ endif
NULL:=#
intel_drv_la_SOURCES = \
+ intel_module.c \
+ $(NULL)
+
+if UXA
+AM_CFLAGS += -I$(top_srcdir)/uxa -I$(top_srcdir)/src/render_program
+intel_drv_la_LIBADD += @UDEV_LIBS@ @DRM_LIBS@ -ldrm_intel ../uxa/libuxa.la
+intel_drv_la_SOURCES += \
brw_defines.h \
brw_structs.h \
common.h \
intel.h \
- intel_module.c \
intel_batchbuffer.c \
intel_batchbuffer.h \
intel_display.c \
@@ -87,3 +92,4 @@ intel_drv_la_SOURCES += \
intel_hwmc.c \
$(NULL)
endif
+endif
diff --git a/src/i915_video.c b/src/i915_video.c
index d46c6d1..c73615e 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -33,6 +33,7 @@
#include "xf86_OSproc.h"
#include "xf86xv.h"
#include "fourcc.h"
+#include "gcstruct.h"
#include "intel.h"
#include "intel_video.h"
diff --git a/src/intel.h b/src/intel.h
index ed95063..1a002e2 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -75,7 +75,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <libudev.h>
#endif
-#include "uxa.h"
/* XXX
* The X server gained an *almost* identical implementation in 1.9.
*
@@ -316,7 +315,7 @@ typedef struct intel_screen_private {
void (*batch_flush) (struct intel_screen_private *intel);
void (*batch_commit_notify) (struct intel_screen_private *intel);
- uxa_driver_t *uxa_driver;
+ struct _UxaDriver *uxa_driver;
Bool need_sync;
int accel_pixmap_offset_alignment;
int accel_max_x;
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index 89a9969..2b8fbb6 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -40,6 +40,8 @@
#include "i915_drm.h"
#include "i965_reg.h"
+#include "uxa.h"
+
#define DUMP_BATCHBUFFERS NULL // "/tmp/i915-batchbuffers.dump"
static void intel_end_vertex(intel_screen_private *intel)
diff --git a/src/intel_dri.c b/src/intel_dri.c
index 1227dbb..135ba4e 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -56,8 +56,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "windowstr.h"
#include "shadow.h"
-
#include "xaarop.h"
+#include "fb.h"
#include "intel.h"
#include "i830_reg.h"
diff --git a/src/intel_driver.c b/src/intel_driver.c
index f385819..188c512 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -70,6 +70,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
#include "legacy/legacy.h"
+#include "uxa.h"
#include <sys/ioctl.h>
#include "i915_drm.h"
diff --git a/src/intel_module.c b/src/intel_module.c
index 3a0ecc9..80b5da8 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -346,8 +346,10 @@ static Bool intel_pci_probe(DriverPtr driver,
default:
#if USE_SNA
sna_init_scrn(scrn, entity_num);
-#else
+#elif USE_UXA
intel_init_scrn(scrn);
+#else
+ scrn = NULL;
#endif
break;
}
@@ -387,8 +389,10 @@ intel_available_options(int chipid, int busid)
default:
#if USE_SNA
return sna_available_options(chipid, busid);
-#else
+#elif USE_UXA
return intel_uxa_available_options(chipid, busid);
+#else
+ return NULL;
#endif
}
}
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 8c6f754..94dfb86 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -40,6 +40,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string.h>
#include <errno.h>
+#include "uxa.h"
+
static const int I830CopyROP[16] = {
ROP_0, /* GXclear */
ROP_DSa, /* GXand */
commit edbeab8c4edf9e0e89d85add485fe659795b6350
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 15 10:17:06 2011 +0000
sna: Reduce and clarify dependencies
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/common.h b/src/common.h
index 6b9c315..f9f2300 100644
--- a/src/common.h
+++ b/src/common.h
@@ -109,7 +109,7 @@ static inline void memcpy_volatile(volatile void *dst, const void *src,
size_t i;
for (i = 0; i < len; i++)
- ((volatile char *)dst)[i] = ((volatile char *)src)[i];
+ ((volatile char *)dst)[i] = ((const volatile char *)src)[i];
}
/* Memory mapped register access macros */
diff --git a/src/intel.h b/src/intel.h
index 3b3f87d..ed95063 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -57,7 +57,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86Pci.h"
#include "xf86Cursor.h"
#include "xf86xv.h"
-#include "vgaHW.h"
#include "xf86Crtc.h"
#include "xf86RandR12.h"
@@ -636,7 +635,7 @@ intel_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
float *x_out, float *y_out, float *z_out);
static inline void
-intel_debug_fallback(ScrnInfoPtr scrn, char *format, ...)
+intel_debug_fallback(ScrnInfoPtr scrn, const char *format, ...)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
va_list ap;
diff --git a/src/intel_display.c b/src/intel_display.c
index 84c7c08..542dc20 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -42,6 +42,8 @@
#include "intel_bufmgr.h"
#include "xf86drmMode.h"
#include "X11/Xatom.h"
+#include "X11/extensions/dpmsconst.h"
+#include "xf86DDC.h"
struct intel_mode {
int fd;
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 24696da..f385819 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -50,11 +50,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86cmap.h"
#include "compiler.h"
#include "mibstore.h"
-#include "vgaHW.h"
#include "mipointer.h"
#include "micmap.h"
#include "shadowfb.h"
#include <X11/extensions/randr.h>
+#include <X11/extensions/dpmsconst.h>
#include "fb.h"
#include "miscstruct.h"
#include "dixstruct.h"
@@ -1118,9 +1118,6 @@ static void I830FreeScreen(int scrnIndex, int flags)
free(intel);
scrn->driverPrivate = NULL;
}
-
- if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
- vgaHWFreeHWRec(xf86Screens[scrnIndex]);
}
static void I830LeaveVT(int scrnIndex, int flags)
diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index ac60988..30cedc6 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -35,6 +35,7 @@ libsna_la_SOURCES = \
compiler.h \
kgem.c \
kgem.h \
+ rop.h \
sna.h \
sna_accel.c \
sna_blt.c \
diff --git a/src/sna/rop.h b/src/sna/rop.h
new file mode 100644
index 0000000..9db15cf
--- /dev/null
+++ b/src/sna/rop.h
@@ -0,0 +1,264 @@
+#ifndef ROP_H
+#define ROP_H
+
+#define ROP_0 0x00
+#define ROP_DPSoon 0x01
+#define ROP_DPSona 0x02
+#define ROP_PSon 0x03
+#define ROP_SDPona 0x04
+#define ROP_DPon 0x05
+#define ROP_PDSxnon 0x06
+#define ROP_PDSaon 0x07
+#define ROP_SDPnaa 0x08
+#define ROP_PDSxon 0x09
+#define ROP_DPna 0x0A
+#define ROP_PSDnaon 0x0B
+#define ROP_SPna 0x0C
+#define ROP_PDSnaon 0x0D
+#define ROP_PDSonon 0x0E
+#define ROP_Pn 0x0F
+#define ROP_PDSona 0x10
+#define ROP_DSon 0x11
+#define ROP_SDPxnon 0x12
+#define ROP_SDPaon 0x13
+#define ROP_DPSxnon 0x14
+#define ROP_DPSaon 0x15
+#define ROP_PSDPSanaxx 0x16
+#define ROP_SSPxDSxaxn 0x17
+#define ROP_SPxPDxa 0x18
+#define ROP_SDPSanaxn 0x19
+#define ROP_PDSPaox 0x1A
+#define ROP_SDPSxaxn 0x1B
+#define ROP_PSDPaox 0x1C
+#define ROP_DSPDxaxn 0x1D
+#define ROP_PDSox 0x1E
+#define ROP_PDSoan 0x1F
+#define ROP_DPSnaa 0x20
+#define ROP_SDPxon 0x21
+#define ROP_DSna 0x22
+#define ROP_SPDnaon 0x23
+#define ROP_SPxDSxa 0x24
+#define ROP_PDSPanaxn 0x25
+#define ROP_SDPSaox 0x26
+#define ROP_SDPSxnox 0x27
+#define ROP_DPSxa 0x28
+#define ROP_PSDPSaoxxn 0x29
+#define ROP_DPSana 0x2A
+#define ROP_SSPxPDxaxn 0x2B
+#define ROP_SPDSoax 0x2C
+#define ROP_PSDnox 0x2D
+#define ROP_PSDPxox 0x2E
+#define ROP_PSDnoan 0x2F
+#define ROP_PSna 0x30
+#define ROP_SDPnaon 0x31
+#define ROP_SDPSoox 0x32
+#define ROP_Sn 0x33
+#define ROP_SPDSaox 0x34
+#define ROP_SPDSxnox 0x35
+#define ROP_SDPox 0x36
+#define ROP_SDPoan 0x37
+#define ROP_PSDPoax 0x38
+#define ROP_SPDnox 0x39
+#define ROP_SPDSxox 0x3A
+#define ROP_SPDnoan 0x3B
+#define ROP_PSx 0x3C
+#define ROP_SPDSonox 0x3D
+#define ROP_SPDSnaox 0x3E
+#define ROP_PSan 0x3F
+#define ROP_PSDnaa 0x40
+#define ROP_DPSxon 0x41
+#define ROP_SDxPDxa 0x42
+#define ROP_SPDSanaxn 0x43
+#define ROP_SDna 0x44
+#define ROP_DPSnaon 0x45
+#define ROP_DSPDaox 0x46
+#define ROP_PSDPxaxn 0x47
+#define ROP_SDPxa 0x48
+#define ROP_PDSPDaoxxn 0x49
+#define ROP_DPSDoax 0x4A
+#define ROP_PDSnox 0x4B
+#define ROP_SDPana 0x4C
+#define ROP_SSPxDSxoxn 0x4D
+#define ROP_PDSPxox 0x4E
+#define ROP_PDSnoan 0x4F
+#define ROP_PDna 0x50
+#define ROP_DSPnaon 0x51
+#define ROP_DPSDaox 0x52
+#define ROP_SPDSxaxn 0x53
+#define ROP_DPSonon 0x54
+#define ROP_Dn 0x55
+#define ROP_DPSox 0x56
+#define ROP_DPSoan 0x57
+#define ROP_PDSPoax 0x58
+#define ROP_DPSnox 0x59
+#define ROP_DPx 0x5A
+#define ROP_DPSDonox 0x5B
+#define ROP_DPSDxox 0x5C
+#define ROP_DPSnoan 0x5D
+#define ROP_DPSDnaox 0x5E
+#define ROP_DPan 0x5F
+#define ROP_PDSxa 0x60
+#define ROP_DSPDSaoxxn 0x61
+#define ROP_DSPDoax 0x62
+#define ROP_SDPnox 0x63
+#define ROP_SDPSoax 0x64
+#define ROP_DSPnox 0x65
+#define ROP_DSx 0x66
+#define ROP_SDPSonox 0x67
+#define ROP_DSPDSonoxxn 0x68
+#define ROP_PDSxxn 0x69
+#define ROP_DPSax 0x6A
+#define ROP_PSDPSoaxxn 0x6B
+#define ROP_SDPax 0x6C
+#define ROP_PDSPDoaxxn 0x6D
+#define ROP_SDPSnoax 0x6E
+#define ROP_PDSxnan 0x6F
+#define ROP_PDSana 0x70
+#define ROP_SSDxPDxaxn 0x71
+#define ROP_SDPSxox 0x72
+#define ROP_SDPnoan 0x73
+#define ROP_DSPDxox 0x74
+#define ROP_DSPnoan 0x75
+#define ROP_SDPSnaox 0x76
+#define ROP_DSan 0x77
+#define ROP_PDSax 0x78
+#define ROP_DSPDSoaxxn 0x79
+#define ROP_DPSDnoax 0x7A
+#define ROP_SDPxnan 0x7B
+#define ROP_SPDSnoax 0x7C
+#define ROP_DPSxnan 0x7D
+#define ROP_SPxDSxo 0x7E
+#define ROP_DPSaan 0x7F
+#define ROP_DPSaa 0x80
+#define ROP_SPxDSxon 0x81
+#define ROP_DPSxna 0x82
+#define ROP_SPDSnoaxn 0x83
+#define ROP_SDPxna 0x84
+#define ROP_PDSPnoaxn 0x85
+#define ROP_DSPDSoaxx 0x86
+#define ROP_PDSaxn 0x87
+#define ROP_DSa 0x88
+#define ROP_SDPSnaoxn 0x89
+#define ROP_DSPnoa 0x8A
+#define ROP_DSPDxoxn 0x8B
+#define ROP_SDPnoa 0x8C
+#define ROP_SDPSxoxn 0x8D
+#define ROP_SSDxPDxax 0x8E
+#define ROP_PDSanan 0x8F
+#define ROP_PDSxna 0x90
+#define ROP_SDPSnoaxn 0x91
+#define ROP_DPSDPoaxx 0x92
+#define ROP_SPDaxn 0x93
+#define ROP_PSDPSoaxx 0x94
+#define ROP_DPSaxn 0x95
+#define ROP_DPSxx 0x96
+#define ROP_PSDPSonoxx 0x97
+#define ROP_SDPSonoxn 0x98
+#define ROP_DSxn 0x99
+#define ROP_DPSnax 0x9A
+#define ROP_SDPSoaxn 0x9B
+#define ROP_SPDnax 0x9C
+#define ROP_DSPDoaxn 0x9D
+#define ROP_DSPDSaoxx 0x9E
+#define ROP_PDSxan 0x9F
+#define ROP_DPa 0xA0
+#define ROP_PDSPnaoxn 0xA1
+#define ROP_DPSnoa 0xA2
+#define ROP_DPSDxoxn 0xA3
+#define ROP_PDSPonoxn 0xA4
+#define ROP_PDxn 0xA5
+#define ROP_DSPnax 0xA6
+#define ROP_PDSPoaxn 0xA7
+#define ROP_DPSoa 0xA8
+#define ROP_DPSoxn 0xA9
+#define ROP_D 0xAA
+#define ROP_DPSono 0xAB
+#define ROP_SPDSxax 0xAC
+#define ROP_DPSDaoxn 0xAD
+#define ROP_DSPnao 0xAE
+#define ROP_DPno 0xAF
+#define ROP_PDSnoa 0xB0
+#define ROP_PDSPxoxn 0xB1
+#define ROP_SSPxDSxox 0xB2
+#define ROP_SDPanan 0xB3
+#define ROP_PSDnax 0xB4
+#define ROP_DPSDoaxn 0xB5
+#define ROP_DPSDPaoxx 0xB6
+#define ROP_SDPxan 0xB7
+#define ROP_PSDPxax 0xB8
+#define ROP_DSPDaoxn 0xB9
+#define ROP_DPSnao 0xBA
+#define ROP_DSno 0xBB
+#define ROP_SPDSanax 0xBC
+#define ROP_SDxPDxan 0xBD
+#define ROP_DPSxo 0xBE
+#define ROP_DPSano 0xBF
+#define ROP_Psa 0xC0
+#define ROP_SPDSnaoxn 0xC1
+#define ROP_SPDSonoxn 0xC2
+#define ROP_PSxn 0xC3
+#define ROP_SPDnoa 0xC4
+#define ROP_SPDSxoxn 0xC5
+#define ROP_SDPnax 0xC6
+#define ROP_PSDPoaxn 0xC7
+#define ROP_SDPoa 0xC8
+#define ROP_SPDoxn 0xC9
+#define ROP_DPSDxax 0xCA
+#define ROP_SPDSaoxn 0xCB
+#define ROP_S 0xCC
+#define ROP_SDPono 0xCD
+#define ROP_SDPnao 0xCE
+#define ROP_SPno 0xCF
+#define ROP_PSDnoa 0xD0
+#define ROP_PSDPxoxn 0xD1
+#define ROP_PDSnax 0xD2
+#define ROP_SPDSoaxn 0xD3
+#define ROP_SSPxPDxax 0xD4
+#define ROP_DPSanan 0xD5
+#define ROP_PSDPSaoxx 0xD6
+#define ROP_DPSxan 0xD7
+#define ROP_PDSPxax 0xD8
+#define ROP_SDPSaoxn 0xD9
+#define ROP_DPSDanax 0xDA
+#define ROP_SPxDSxan 0xDB
+#define ROP_SPDnao 0xDC
+#define ROP_SDno 0xDD
+#define ROP_SDPxo 0xDE
+#define ROP_SDPano 0xDF
+#define ROP_PDSoa 0xE0
+#define ROP_PDSoxn 0xE1
+#define ROP_DSPDxax 0xE2
+#define ROP_PSDPaoxn 0xE3
+#define ROP_SDPSxax 0xE4
+#define ROP_PDSPaoxn 0xE5
+#define ROP_SDPSanax 0xE6
+#define ROP_SPxPDxan 0xE7
+#define ROP_SSPxDSxax 0xE8
+#define ROP_DSPDSanaxxn 0xE9
+#define ROP_DPSao 0xEA
+#define ROP_DPSxno 0xEB
+#define ROP_SDPao 0xEC
+#define ROP_SDPxno 0xED
+#define ROP_DSo 0xEE
+#define ROP_SDPnoo 0xEF
+#define ROP_P 0xF0
+#define ROP_PDSono 0xF1
+#define ROP_PDSnao 0xF2
+#define ROP_PSno 0xF3
+#define ROP_PSDnao 0xF4
+#define ROP_PDno 0xF5
+#define ROP_PDSxo 0xF6
+#define ROP_PDSano 0xF7
+#define ROP_PDSao 0xF8
+#define ROP_PDSxno 0xF9
+#define ROP_DPo 0xFA
+#define ROP_DPSnoo 0xFB
+#define ROP_PSo 0xFC
+#define ROP_PSDnoo 0xFD
+#define ROP_DPSoo 0xFE
+#define ROP_1 0xFF
+
+#define NO_SRC_ROP(rop) \
+ ((rop == GXnoop) || (rop == GXset) || (rop == GXclear) || (rop == GXinvert))
+
+#endif /* ROP_H */
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 573fe0e..9492fc2 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -49,7 +49,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <xf86Pci.h>
#include <xf86Cursor.h>
#include <xf86xv.h>
-#include <vgaHW.h>
#include <xf86Crtc.h>
#include <xf86RandR12.h>
#include <gcstruct.h>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e0990c5..46992f6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -31,11 +31,11 @@
#include "sna.h"
#include "sna_reg.h"
+#include "rop.h"
#include <X11/fonts/font.h>
#include <X11/fonts/fontstruct.h>
-#include <xaarop.h>
#include <fb.h>
#include <dixfontstr.h>
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 0290a33..4c7beab 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -36,10 +36,10 @@
#include "sna_render.h"
#include "sna_render_inline.h"
#include "sna_reg.h"
+#include "rop.h"
#include <mipict.h>
#include <fbpict.h>
-#include <xaarop.h>
#if DEBUG_BLT
#undef DBG
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 532dd80..1d66a8d 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -726,7 +726,6 @@ fallback:
sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, true);
if (op == PictOpSrc || op == PictOpClear) {
- PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable);
int nbox = REGION_NUM_RECTS(®ion);
BoxPtr box = REGION_RECTS(®ion);
uint32_t pixel;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index b1275ed..32162ef 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -39,6 +39,8 @@
#include <xorgVersion.h>
#include <X11/Xatom.h>
+#include <X11/extensions/dpmsconst.h>
+#include <xf86DDC.h>
#include "sna.h"
#include "sna_reg.h"
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 693febc..19413a9 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -45,21 +45,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <stdio.h>
#include <errno.h>
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86cmap.h"
+#include <xf86cmap.h>
+#include <micmap.h>
+#include <fb.h>
+
#include "compiler.h"
-#include "mibstore.h"
-#include "vgaHW.h"
-#include "mipointer.h"
-#include "micmap.h"
-#include "shadowfb.h"
-#include <X11/extensions/randr.h>
-#include "fb.h"
-#include "miscstruct.h"
-#include "dixstruct.h"
-#include "xf86xv.h"
-#include <X11/extensions/Xv.h>
#include "sna.h"
#include "sna_module.h"
#include "sna_video.h"
@@ -973,9 +963,6 @@ static void sna_free_screen(int scrnIndex, int flags)
}
sna_close_drm_master(scrn);
-
- if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
- vgaHWFreeHWRec(xf86Screens[scrnIndex]);
}
/*
commit 78d4e99fc916e6477edb01c6f24b69ad73adc552
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 15 11:06:04 2011 +0000
sna: And keep unity happy
Rewrite the DRI layer to avoid the various bugs and shortcomings of the
Xserver and interfacing with mesa.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38732
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=39044
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index c854846..89caf96 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -263,7 +263,6 @@ static struct kgem_bo *__kgem_bo_init(struct kgem_bo *bo,
bo->handle = handle;
bo->size = size;
bo->reusable = true;
- bo->purgeable = true;
bo->cpu_read = true;
bo->cpu_write = true;
list_init(&bo->request);
@@ -577,6 +576,8 @@ static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
{
struct kgem_bo_binding *b;
+ DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
+
b = bo->binding.next;
while (b) {
struct kgem_bo_binding *next = b->next;
@@ -592,6 +593,8 @@ static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
{
+ DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
+
assert(list_is_empty(&bo->list));
assert(bo->refcnt == 0);
@@ -603,9 +606,11 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
if(!bo->reusable)
goto destroy;
- if (bo->purgeable && !bo->rq && !bo->needs_flush) {
+ if (!bo->rq && !bo->needs_flush) {
assert(!bo->purged);
+ DBG(("%s: handle=%d, purged\n", __FUNCTION__, bo->handle));
+
if (!gem_madvise(kgem->fd, bo->handle, I915_MADV_DONTNEED)) {
kgem->need_purge |= bo->gpu;
goto destroy;
@@ -616,10 +621,13 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
kgem->need_expire = true;
if (bo->rq) {
+ DBG(("%s: handle=%d -> active\n", __FUNCTION__, bo->handle));
list_move(&bo->list, active(kgem, bo->size));
} else if (bo->purged) {
+ DBG(("%s: handle=%d -> inactive\n", __FUNCTION__, bo->handle));
list_move(&bo->list, inactive(kgem, bo->size));
} else {
+ DBG(("%s: handle=%d -> flushing\n", __FUNCTION__, bo->handle));
assert(list_is_empty(&bo->request));
list_add(&bo->request, &kgem->flushing);
list_move(&bo->list, active(kgem, bo->size));
@@ -651,8 +659,7 @@ bool kgem_retire(struct kgem *kgem)
DBG(("%s: moving %d from flush to inactive\n",
__FUNCTION__, bo->handle));
- if (bo->purgeable &&
- gem_madvise(kgem->fd, bo->handle, I915_MADV_DONTNEED)) {
+ if (gem_madvise(kgem->fd, bo->handle, I915_MADV_DONTNEED)) {
bo->purged = true;
bo->needs_flush = false;
bo->gpu = false;
@@ -692,7 +699,7 @@ bool kgem_retire(struct kgem *kgem)
if (bo->refcnt == 0) {
if (bo->reusable) {
- if (bo->needs_flush || !bo->purgeable) {
+ if (bo->needs_flush) {
DBG(("%s: moving %d to flushing\n",
__FUNCTION__, bo->handle));
list_add(&bo->request, &kgem->flushing);
@@ -813,7 +820,6 @@ static void kgem_finish_partials(struct kgem *kgem)
if (base) {
memcpy(base, &bo->base, sizeof (*base));
base->reusable = true;
- base->purgeable = true;
list_init(&base->list);
list_replace(&bo->base.request, &base->request);
free(bo);
@@ -1269,7 +1275,6 @@ search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
use_active ? "active" : "inactive"));
assert(bo->refcnt == 0);
assert(bo->reusable);
- assert(use_active || bo->purgeable);
assert(use_active || bo->gpu == 0);
//assert(use_active || !kgem_busy(kgem, bo->handle));
return bo;
@@ -1298,7 +1303,6 @@ struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name)
}
bo->reusable = false;
- bo->purgeable = false;
return bo;
}
@@ -1613,7 +1617,6 @@ skip_active_search:
bo->pitch, bo->tiling, bo->handle, bo->unique_id));
assert(bo->refcnt == 0);
assert(bo->reusable);
- assert(bo->purgeable);
assert((flags & CREATE_INACTIVE) == 0 || bo->gpu == 0);
assert((flags & CREATE_INACTIVE) == 0 ||
!kgem_busy(kgem, bo->handle));
@@ -1846,7 +1849,16 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo)
* on the buffer, and *presuming* they do not pass it on to a third
* party, we track the lifetime accurately.
*/
- bo->purgeable = false;
+ bo->reusable = false;
+
+ /* The bo is outside of our control, so presume it is written to */
+ bo->needs_flush = true;
+ bo->gpu = true;
+ bo->cpu_read = bo->cpu_write = false;
+ bo->flush = 1;
+ if (bo->exec)
+ kgem->flush = 1;
+
return flink.name;
}
@@ -1888,7 +1900,7 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
return NULL;
}
- bo->purgeable = bo->reusable = false;
+ bo->reusable = false;
bo->sync = true;
DBG(("%s(ptr=%p, size=%d, read_only=%d) => handle=%d\n",
__FUNCTION__, ptr, size, read_only, handle));
@@ -2017,7 +2029,7 @@ struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
if (bo == NULL)
return NULL;
- bo->purgeable = bo->reusable = false;
+ bo->reusable = false;
bo->proxy = kgem_bo_reference(target);
bo->delta = offset;
return bo;
@@ -2146,7 +2158,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
bo->base.vmap = true;
bo->need_io = 0;
}
- bo->base.purgeable = bo->base.reusable = false;
+ bo->base.reusable = false;
bo->alloc = alloc;
bo->used = size;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 0f142b7..112a91c 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -75,7 +75,6 @@ struct kgem_bo {
uint32_t vmap : 1;
uint32_t flush : 1;
uint32_t sync : 1;
- uint32_t purgeable : 1;
uint32_t purged : 1;
};
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 52142cb..573fe0e 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -305,15 +305,15 @@ extern void sna_mode_fini(struct sna *sna);
extern int sna_crtc_id(xf86CrtcPtr crtc);
extern int sna_output_dpms_status(xf86OutputPtr output);
-extern int sna_do_pageflip(struct sna *sna,
- PixmapPtr pixmap,
- void *data,
- int ref_crtc_hw_id,
- uint32_t *old_fb);
+extern int sna_page_flip(struct sna *sna,
+ struct kgem_bo *bo,
+ void *data,
+ int ref_crtc_hw_id,
+ uint32_t *old_fb);
extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap);
-void sna_mode_delete_fb(struct sna *sna, PixmapPtr pixmap, uint32_t fb);
+void sna_mode_delete_fb(struct sna *sna, uint32_t fb);
static inline struct sna *
to_sna(ScrnInfoPtr scrn)
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e8d2c2a..b1275ed 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1773,21 +1773,16 @@ PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap)
}
int
-sna_do_pageflip(struct sna *sna,
- PixmapPtr pixmap,
- void *data,
- int ref_crtc_hw_id,
- uint32_t *old_fb)
+sna_page_flip(struct sna *sna,
+ struct kgem_bo *bo,
+ void *data,
+ int ref_crtc_hw_id,
+ uint32_t *old_fb)
{
ScrnInfoPtr scrn = sna->scrn;
struct sna_mode *mode = &sna->mode;
- struct kgem_bo *bo;
int count;
- bo = sna_pixmap_pin(pixmap);
- if (!bo)
- return 0;
-
*old_fb = mode->fb_id;
/*
@@ -1822,7 +1817,6 @@ sna_do_pageflip(struct sna *sna,
count = do_page_flip(sna, data, ref_crtc_hw_id);
DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count));
if (count) {
- sna->mode.fb_pixmap = pixmap->drawable.serialNumber;
bo->cpu_read = bo->cpu_write = false;
bo->gpu = true;
@@ -1832,6 +1826,7 @@ sna_do_pageflip(struct sna *sna,
* upon release.
*/
bo->needs_flush = true;
+ bo->reusable = true;
} else {
drmModeRmFB(sna->kgem.fd, mode->fb_id);
mode->fb_id = *old_fb;
@@ -1840,13 +1835,10 @@ sna_do_pageflip(struct sna *sna,
return count;
}
-void sna_mode_delete_fb(struct sna *sna, PixmapPtr pixmap, uint32_t fb)
+void sna_mode_delete_fb(struct sna *sna, uint32_t fb)
{
if (fb)
drmModeRmFB(sna->kgem.fd, fb);
-
- if (pixmap)
- pixmap->drawable.pScreen->DestroyPixmap(pixmap);
}
static const xf86CrtcConfigFuncsRec sna_crtc_config_funcs = {
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 61a7b12..941da87 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -36,35 +36,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "config.h"
#endif
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <time.h>
+#include <xf86.h>
+#include <xf86_OSproc.h>
#include <errno.h>
+#include <string.h>
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-
-#include "windowstr.h"
-#include "gcstruct.h"
+#include <i915_drm.h>
+#include <dri2.h>
#include "sna.h"
#include "sna_reg.h"
-#include "i915_drm.h"
-
-#include "dri2.h"
-
#if DRI2INFOREC_VERSION <= 2
#error DRI2 version supported by the Xserver is too old
#endif
@@ -74,8 +56,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DBG(x) ErrorF x
#endif
-#define NO_TRIPPLE_BUFFER 0
-
enum frame_event_type {
DRI2_SWAP,
DRI2_SWAP_THROTTLE,
@@ -113,11 +93,13 @@ struct sna_dri_frame_event {
unsigned int fe_tv_sec;
unsigned int fe_tv_usec;
- PixmapPtr old_front;
- PixmapPtr next_front;
+ struct {
+ struct kgem_bo *bo;
+ uint32_t name;
+ } old_front, next_front, cache;
uint32_t old_fb;
- struct sna_dri_frame_event *chain;
+ int off_delay;
};
static DevPrivateKeyRec sna_client_key;
@@ -128,11 +110,16 @@ to_frame_event(void *data)
return (struct sna_dri_frame_event *)((uintptr_t)data & ~1);
}
-static inline PixmapPtr
-get_pixmap(DRI2Buffer2Ptr buffer)
+static inline struct sna_dri_private *
+get_private(DRI2Buffer2Ptr buffer)
{
- struct sna_dri_private *priv = buffer->driverPrivate;
- return priv->pixmap;
+ return (struct sna_dri_private *)(buffer+1);
+}
+
+static inline struct kgem_bo *ref(struct kgem_bo *bo)
+{
+ bo->refcnt++;
+ return bo;
}
static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
@@ -145,29 +132,22 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
return NULL;
if (priv->flush)
- return priv->gpu_bo;
+ return ref(priv->gpu_bo);
if (priv->cpu_damage)
list_add(&priv->list, &sna->dirty_pixmaps);
- /* The bo is outside of our control, so presume it is written to */
- priv->gpu_bo->needs_flush = true;
- priv->gpu_bo->gpu = true;
-
/* We need to submit any modifications to and reads from this
* buffer before we send any reply to the Client.
*
* As we don't track which Client, we flush for all.
*/
priv->flush = 1;
- priv->gpu_bo->flush = 1;
- if (priv->gpu_bo->exec)
- sna->kgem.flush = 1;
/* Don't allow this named buffer to be replaced */
priv->pinned = 1;
- return priv->gpu_bo;
+ return ref(priv->gpu_bo);
}
static DRI2Buffer2Ptr
@@ -175,14 +155,12 @@ sna_dri_create_buffer(DrawablePtr drawable,
unsigned int attachment,
unsigned int format)
{
- ScreenPtr screen = drawable->pScreen;
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- struct sna *sna = to_sna(scrn);
+ struct sna *sna = to_sna_from_drawable(drawable);
DRI2Buffer2Ptr buffer;
struct sna_dri_private *private;
PixmapPtr pixmap;
struct kgem_bo *bo;
- int bpp, usage;
+ int bpp;
DBG(("%s(attachment=%d, format=%d, drawable=%dx%d)\n",
__FUNCTION__, attachment, format,
@@ -191,11 +169,9 @@ sna_dri_create_buffer(DrawablePtr drawable,
buffer = calloc(1, sizeof *buffer + sizeof *private);
if (buffer == NULL)
return NULL;
- private = (struct sna_dri_private *)(buffer + 1);
pixmap = NULL;
bo = NULL;
- usage = SNA_CREATE_SCRATCH;
switch (attachment) {
case DRI2BufferFrontLeft:
pixmap = get_drawable_pixmap(drawable);
@@ -211,25 +187,14 @@ sna_dri_create_buffer(DrawablePtr drawable,
case DRI2BufferBackLeft:
case DRI2BufferBackRight:
case DRI2BufferFrontRight:
- /* Allocate a normal window, perhaps flippable */
- usage = 0;
- if (drawable->width == sna->front->drawable.width &&
- drawable->height == sna->front->drawable.height &&
- drawable->depth == sna->front->drawable.depth)
- usage = SNA_CREATE_FB;
-
case DRI2BufferFakeFrontLeft:
case DRI2BufferFakeFrontRight:
- pixmap = screen->CreatePixmap(screen,
- drawable->width,
- drawable->height,
- drawable->depth,
- usage);
- if (!pixmap)
- goto err;
-
- bo = sna_pixmap_set_dri(sna, pixmap);
- bpp = pixmap->drawable.bitsPerPixel;
+ bpp = drawable->bitsPerPixel;
+ bo = kgem_create_2d(&sna->kgem,
+ drawable->width,
+ drawable->height,
+ drawable->bitsPerPixel,
+ I915_TILING_X, CREATE_EXACT);
break;
case DRI2BufferStencil:
@@ -282,6 +247,7 @@ sna_dri_create_buffer(DrawablePtr drawable,
if (bo == NULL)
goto err;
+ private = get_private(buffer);
buffer->attachment = attachment;
buffer->pitch = bo->pitch;
buffer->cpp = bpp / 8;
@@ -296,7 +262,7 @@ sna_dri_create_buffer(DrawablePtr drawable,
if (buffer->name == 0) {
/* failed to name buffer */
if (pixmap)
- screen->DestroyPixmap(pixmap);
+ pixmap->drawable.pScreen->DestroyPixmap(pixmap);
else
kgem_bo_destroy(&sna->kgem, bo);
goto err;
@@ -311,12 +277,12 @@ err:
static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
{
- struct sna_dri_private *private = buffer->driverPrivate;
+ struct sna_dri_private *private = get_private(buffer);
- if (--private->refcnt == 0) {
- private->bo->gpu = private->bo->needs_flush || private->bo->rq != NULL;
- private->bo->flush = 0;
+ if (buffer == NULL)
+ return;
+ if (--private->refcnt == 0) {
if (private->pixmap) {
ScreenPtr screen = private->pixmap->drawable.pScreen;
struct sna_pixmap *priv = sna_pixmap(private->pixmap);
@@ -327,8 +293,12 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
priv->flush = 0;
screen->DestroyPixmap(private->pixmap);
- } else
- kgem_bo_destroy(&sna->kgem, private->bo);
+ }
+
+ private->bo->gpu =
+ private->bo->needs_flush || private->bo->rq != NULL;
+ private->bo->flush = 0;
+ kgem_bo_destroy(&sna->kgem, private->bo);
free(buffer);
}
@@ -336,16 +306,12 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
static void sna_dri_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
{
- if (buffer && buffer->driverPrivate)
- _sna_dri_destroy_buffer(to_sna_from_drawable(drawable), buffer);
- else
- free(buffer);
+ _sna_dri_destroy_buffer(to_sna_from_drawable(drawable), buffer);
}
static void sna_dri_reference_buffer(DRI2Buffer2Ptr buffer)
{
- struct sna_dri_private *private = buffer->driverPrivate;
- private->refcnt++;
+ get_private(buffer)->refcnt++;
}
static void damage(PixmapPtr pixmap, RegionPtr region)
@@ -375,65 +341,39 @@ damage_all:
}
}
-static void damage_all(PixmapPtr pixmap)
+static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
{
struct sna_pixmap *priv;
priv = sna_pixmap(pixmap);
- if (priv->gpu_only)
- return;
-
- sna_damage_all(&priv->gpu_damage,
- pixmap->drawable.width,
- pixmap->drawable.height);
- sna_damage_destroy(&priv->cpu_damage);
+ if (!priv->gpu_only) {
+ sna_damage_all(&priv->gpu_damage,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
+ sna_damage_destroy(&priv->cpu_damage);
+ }
+ assert(priv->gpu_bo->refcnt > 1);
+ priv->gpu_bo->refcnt--;
+ priv->gpu_bo = ref(bo);
}
static void
sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
- DRI2BufferPtr dst_buffer, DRI2BufferPtr src_buffer,
+ struct kgem_bo *dst_bo,struct kgem_bo *src_bo,
bool sync)
{
- struct sna_dri_private *src_priv = src_buffer->driverPrivate;
- struct sna_dri_private *dst_priv = dst_buffer->driverPrivate;
- PixmapPtr src = src_priv->pixmap;
- PixmapPtr dst = dst_priv->pixmap;
- struct kgem_bo *dst_bo = dst_priv->bo;
+ PixmapPtr pixmap = get_drawable_pixmap(draw);
pixman_region16_t clip;
bool flush = false;
BoxRec box, *boxes;
- int16_t dx, dy, sx, sy;
+ int16_t dx, dy;
int n;
- DBG(("%s: dst -- attachment=%d, name=%d, handle=%d [screen=%d, sync=%d]\n",
- __FUNCTION__,
- dst_buffer->attachment,
- dst_buffer->name,
- dst_priv->bo->handle,
- sna_pixmap_get_bo(sna->front)->handle,
- sync));
- DBG(("%s: src -- attachment=%d, name=%d, handle=%d\n",
- __FUNCTION__,
- src_buffer->attachment,
- src_buffer->name,
- src_priv->bo->handle));
- if (region) {
- DBG(("%s: clip (%d, %d), (%d, %d) x %d\n",
- __FUNCTION__,
- region->extents.x1, region->extents.y1,
- region->extents.x2, region->extents.y2,
- REGION_NUM_RECTS(region)));
- }
-
box.x1 = draw->x;
box.y1 = draw->y;
box.x2 = draw->x + draw->width;
box.y2 = draw->y + draw->height;
- get_drawable_deltas(draw, src, &sx, &sy);
- sx -= draw->x;
- sy -= draw->y;
-
if (region) {
pixman_region_translate(region, draw->x, draw->y);
pixman_region_init_rects(&clip, &box, 1);
@@ -467,11 +407,11 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
return;
}
- if (dst == sna->front && sync)
- flush = sna_wait_for_scanline(sna, dst, NULL,
+ if (pixmap == sna->front && sync)
+ flush = sna_wait_for_scanline(sna, pixmap, NULL,
®ion->extents);
- get_drawable_deltas(draw, dst, &dx, &dy);
+ get_drawable_deltas(draw, pixmap, &dx, &dy);
}
if (sna->kgem.gen >= 60) {
@@ -490,7 +430,7 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
kgem_set_mode(&sna->kgem, KGEM_RENDER);
}
- damage(dst, region);
+ damage(pixmap, region);
if (region) {
boxes = REGION_RECTS(region);
n = REGION_NUM_RECTS(region);
@@ -512,8 +452,8 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
* again.
*/
sna->render.copy_boxes(sna, GXcopy,
- src, src_priv->bo, sx, sy,
- dst, dst_bo, dx, dy,
+ pixmap, src_bo, -draw->x, -draw->y,
+ pixmap, dst_bo, dx, dy,
boxes, n);
DBG(("%s: flushing? %d\n", __FUNCTION__, flush));
@@ -521,8 +461,8 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
kgem_submit(&sna->kgem);
pixman_region_translate(region, dx, dy);
- DamageRegionAppend(&dst->drawable, region);
- DamageRegionProcessPending(&dst->drawable);
+ DamageRegionAppend(&pixmap->drawable, region);
+ DamageRegionProcessPending(&pixmap->drawable);
if (region == &clip)
pixman_region_fini(&clip);
@@ -534,8 +474,32 @@ sna_dri_copy_region(DrawablePtr draw,
DRI2BufferPtr dst_buffer,
DRI2BufferPtr src_buffer)
{
- sna_dri_copy(to_sna_from_drawable(draw), draw,region,
- dst_buffer, src_buffer, false);
+ struct kgem_bo *src, *dst;
+
+ if (dst_buffer->attachment == DRI2BufferFrontLeft)
+ dst = sna_pixmap_get_bo(get_drawable_pixmap(draw));
+ else
+ dst = get_private(dst_buffer)->bo;
+
+ if (src_buffer->attachment == DRI2BufferFrontLeft)
+ src = sna_pixmap_get_bo(get_drawable_pixmap(draw));
+ else
+ src = get_private(src_buffer)->bo;
+
+ DBG(("%s: dst -- attachment=%d, name=%d, handle=%d [screen=%d]\n",
+ __FUNCTION__,
+ dst_buffer->attachment, dst_buffer->name, dst->handle,
+ sna_pixmap_get_bo(to_sna_from_drawable(draw)->front)->handle));
+ DBG(("%s: src -- attachment=%d, name=%d, handle=%d\n",
+ __FUNCTION__,
+ src_buffer->attachment, src_buffer->name, src->handle));
+ DBG(("%s: clip (%d, %d), (%d, %d) x %d\n",
+ __FUNCTION__,
+ region->extents.x1, region->extents.y1,
+ region->extents.x2, region->extents.y2,
+ REGION_NUM_RECTS(region)));
+
+ sna_dri_copy(to_sna_from_drawable(draw), draw, region, dst, src, false);
}
#if DRI2INFOREC_VERSION >= 4
@@ -721,15 +685,21 @@ sna_dri_frame_event_info_free(struct sna_dri_frame_event *info)
list_del(&info->client_resource);
list_del(&info->drawable_resource);
- if (info->front)
- _sna_dri_destroy_buffer(info->sna, info->front);
- if (info->back)
- _sna_dri_destroy_buffer(info->sna, info->back);
+ _sna_dri_destroy_buffer(info->sna, info->front);
+ _sna_dri_destroy_buffer(info->sna, info->back);
+
+ if (info->old_front.bo)
+ kgem_bo_destroy(&info->sna->kgem, info->old_front.bo);
+ if (info->next_front.bo)
+ kgem_bo_destroy(&info->sna->kgem, info->next_front.bo);
+ if (info->cache.bo)
+ kgem_bo_destroy(&info->sna->kgem, info->cache.bo);
+
free(info);
}
static void
-sna_dri_exchange_buffers(DRI2BufferPtr front, DRI2BufferPtr back)
+sna_dri_exchange_attachment(DRI2BufferPtr front, DRI2BufferPtr back)
{
int tmp;
@@ -746,20 +716,26 @@ sna_dri_exchange_buffers(DRI2BufferPtr front, DRI2BufferPtr back)
* flipping buffers as necessary.
*/
static Bool
-sna_dri_schedule_flip(struct sna *sna, struct sna_dri_frame_event *info)
+sna_dri_page_flip(struct sna *sna, struct sna_dri_frame_event *info)
{
- struct sna_dri_private *back_priv;
+ struct kgem_bo *bo = get_private(info->back)->bo;
DBG(("%s()\n", __FUNCTION__));
- /* Page flip the full screen buffer */
- back_priv = info->back->driverPrivate;
- damage_all(back_priv->pixmap);
- info->count = sna_do_pageflip(sna,
- back_priv->pixmap,
- info, info->pipe,
- &info->old_fb);
- return info->count != 0;
+ info->count = sna_page_flip(sna, bo,
+ info, info->pipe,
+ &info->old_fb);
+ if (info->count == 0)
+ return FALSE;
+
+ set_bo(sna->front, bo);
+
+ info->old_front.name = info->front->name;
+ info->old_front.bo = get_private(info->front)->bo;
+
+ info->front->name = info->back->name;
+ get_private(info->front)->bo = bo;
+ return TRUE;
}
static Bool
@@ -768,14 +744,8 @@ can_flip(struct sna * sna,
DRI2BufferPtr front,
DRI2BufferPtr back)
{
- struct sna_dri_private *back_priv = back->driverPrivate;
- struct sna_dri_private *front_priv = front->driverPrivate;
- struct sna_pixmap *front_sna, *back_sna;
WindowPtr win = (WindowPtr)draw;
- PixmapPtr front_pixmap = front_priv->pixmap;
- PixmapPtr back_pixmap = back_priv->pixmap;
-
- ScreenPtr screen = draw->pScreen;
+ PixmapPtr pixmap;
if (draw->type == DRAWABLE_PIXMAP)
return FALSE;
@@ -799,7 +769,8 @@ can_flip(struct sna * sna,
return FALSE;
}
- if (front_pixmap != sna->front) {
+ pixmap = get_drawable_pixmap(draw);
+ if (pixmap != sna->front) {
DBG(("%s: no, window is not on the front buffer\n",
__FUNCTION__));
return FALSE;
@@ -810,75 +781,41 @@ can_flip(struct sna * sna,
win->drawable.width, win->drawable.height,
win->clipList.extents.x1, win->clipList.extents.y1,
win->clipList.extents.x2, win->clipList.extents.y2));
- if (!RegionEqual(&win->clipList, &screen->root->winSize)) {
+ if (!RegionEqual(&win->clipList, &draw->pScreen->root->winSize)) {
DBG(("%s: no, window is clipped: clip region=(%d, %d), (%d, %d), root size=(%d, %d), (%d, %d)\n",
__FUNCTION__,
win->clipList.extents.x1,
win->clipList.extents.y1,
win->clipList.extents.x2,
win->clipList.extents.y2,
- screen->root->winSize.extents.x1,
- screen->root->winSize.extents.y1,
- screen->root->winSize.extents.x2,
- screen->root->winSize.extents.y2));
+ draw->pScreen->root->winSize.extents.x1,
+ draw->pScreen->root->winSize.extents.y1,
+ draw->pScreen->root->winSize.extents.x2,
+ draw->pScreen->root->winSize.extents.y2));
return FALSE;
}
if (draw->x != 0 || draw->y != 0 ||
#ifdef COMPOSITE
- draw->x != front_pixmap->screen_x ||
- draw->y != front_pixmap->screen_y ||
+ draw->x != pixmap->screen_x ||
+ draw->y != pixmap->screen_y ||
#endif
- draw->width != front_pixmap->drawable.width ||
- draw->height != front_pixmap->drawable.height) {
+ draw->width != pixmap->drawable.width ||
+ draw->height != pixmap->drawable.height) {
DBG(("%s: no, window is not full size (%dx%d)!=(%dx%d)\n",
__FUNCTION__,
draw->width, draw->height,
- front_pixmap->drawable.width,
- front_pixmap->drawable.height));
- return FALSE;
- }
-
- if (front_pixmap->drawable.width != back_pixmap->drawable.width) {
- DBG(("%s -- no, size mismatch: front width=%d, back=%d\n",
- __FUNCTION__,
- front_pixmap->drawable.width,
- back_pixmap->drawable.width));
- return FALSE;
- }
-
- if (front_pixmap->drawable.height != back_pixmap->drawable.height) {
- DBG(("%s -- no, size mismatch: front height=%d, back=%d\n",
- __FUNCTION__,
- front_pixmap->drawable.height,
- back_pixmap->drawable.height));
- return FALSE;
- }
-
- if (front_pixmap->drawable.depth != back_pixmap->drawable.depth) {
- DBG(("%s -- no, depth mismatch: front bpp=%d/%d, back=%d/%d\n",
- __FUNCTION__,
- front_pixmap->drawable.depth,
- front_pixmap->drawable.bitsPerPixel,
- back_pixmap->drawable.depth,
- back_pixmap->drawable.bitsPerPixel));
+ pixmap->drawable.width,
+ pixmap->drawable.height));
return FALSE;
}
/* prevent an implicit tiling mode change */
- front_sna = sna_pixmap(front_pixmap);
- back_sna = sna_pixmap(back_pixmap);
- if (front_sna->gpu_bo->tiling != back_sna->gpu_bo->tiling) {
+ if (get_private(front)->bo->tiling != get_private(back)->bo->tiling) {
DBG(("%s -- no, tiling mismatch: front %d, back=%d\n",
__FUNCTION__,
- front_sna->gpu_bo->tiling,
- back_sna->gpu_bo->tiling));
- return FALSE;
- }
-
- if (front_sna->gpu_only != back_sna->gpu_only) {
- DBG(("%s -- no, mismatch in gpu_only: front %d, back=%d\n",
- __FUNCTION__, front_sna->gpu_only, back_sna->gpu_only));
+ get_private(front)->bo->tiling,
+ get_private(back)->bo->tiling));
return FALSE;
}
@@ -913,13 +850,18 @@ static void sna_dri_vblank_handle(int fd,
case DRI2_FLIP:
/* If we can still flip... */
if (can_flip(sna, draw, info->front, info->back) &&
- sna_dri_schedule_flip(sna, info)) {
- sna_dri_exchange_buffers(info->front, info->back);
+ sna_dri_page_flip(sna, info)) {
+ info->back->name = info->old_front.name;
+ get_private(info->back)->bo = info->old_front.bo;
+ info->old_front.bo = NULL;
return;
}
/* else fall through to exchange/blit */
case DRI2_SWAP:
- sna_dri_copy(sna, draw, NULL, info->front, info->back, true);
+ sna_dri_copy(sna, draw, NULL,
+ get_private(info->front)->bo,
+ get_private(info->back)->bo,
+ true);
case DRI2_SWAP_THROTTLE:
DBG(("%s: %d complete, frame=%d tv=%d.%06d\n",
__FUNCTION__, info->type, frame, tv_sec, tv_usec));
@@ -947,68 +889,38 @@ done:
sna_dri_frame_event_info_free(info);
}
-static void set_pixmap(struct sna *sna, DRI2BufferPtr buffer, PixmapPtr pixmap)
-{
- struct sna_dri_private *priv = buffer->driverPrivate;
-
- assert(priv->pixmap->refcnt > 1);
- priv->pixmap->refcnt--;
- priv->pixmap = pixmap;
- priv->bo = sna_pixmap_set_dri(sna, pixmap);
- buffer->name = kgem_bo_flink(&sna->kgem, priv->bo);
- buffer->pitch = priv->bo->pitch;
-}
-
static int
-sna_dri_flip(struct sna *sna, DrawablePtr draw, struct sna_dri_frame_event *info)
+sna_dri_flip_continue(struct sna *sna,
+ DrawablePtr draw,
+ struct sna_dri_frame_event *info)
{
- struct sna_dri_frame_event *pending;
- ScreenPtr screen = draw->pScreen;
- PixmapPtr pixmap;
+ struct kgem_bo *bo;
+ int name;
- if (NO_TRIPPLE_BUFFER)
- return sna_dri_schedule_flip(sna, info);
+ DBG(("%s()\n", __FUNCTION__));
- info->type = DRI2_FLIP_THROTTLE;
+ name = info->back->name;
+ bo = get_private(info->back)->bo;
- pending = sna->dri.flip_pending[info->pipe];
- if (pending) {
- if (pending->type != DRI2_FLIP_THROTTLE) {
- /* We need to first wait (one vblank) for the
- * async flips to complete beofore this client can
- * take over.
- */
- info->type = DRI2_FLIP;
- return sna_dri_schedule_flip(sna, info);
- }
+ info->count = sna_page_flip(sna, bo, info, info->pipe, &info->old_fb);
+ if (info->count == 0)
+ return FALSE;
- DBG(("%s: chaining flip\n", __FUNCTION__));
- assert(pending->chain == NULL);
- pending->chain = info;
- return TRUE;
- }
+ set_bo(sna->front, bo);
- if (!sna_dri_schedule_flip(sna, info))
- return FALSE;
+ get_private(info->back)->bo = info->old_front.bo;
+ info->back->name = info->old_front.name;
- info->old_front =
- sna_set_screen_pixmap(sna, get_pixmap(info->back));
- sna->dri.flip_pending[info->pipe] = info;
+ info->old_front.name = info->front->name;
+ info->old_front.bo = get_private(info->front)->bo;
- if ((pixmap = screen->CreatePixmap(screen,
- draw->width,
- draw->height,
- draw->depth,
- SNA_CREATE_FB))) {
- DBG(("%s: new back buffer\n", __FUNCTION__));
- set_pixmap(sna, info->front, pixmap);
- }
+ info->front->name = name;
+ get_private(info->front)->bo = bo;
+
+ info->next_front.name = 0;
+
+ sna->dri.flip_pending[info->pipe] = info;
- sna_dri_exchange_buffers(info->front, info->back);
- DRI2SwapComplete(info->client, draw, 0, 0, 0,
- DRI2_EXCHANGE_COMPLETE,
- info->event_complete,
- info->event_data);
return TRUE;
}
@@ -1016,8 +928,6 @@ static void sna_dri_flip_event(struct sna *sna,
struct sna_dri_frame_event *flip)
{
DrawablePtr drawable;
- struct sna_dri_frame_event *chain;
- int status;
DBG(("%s(frame=%d, tv=%d.%06d, type=%d)\n",
__FUNCTION__,
@@ -1034,108 +944,119 @@ static void sna_dri_flip_event(struct sna *sna,
* into account. This usually means some defective kms pageflip completion,
* causing wrong (msc, ust) return values and possible visual corruption.
*/
- if (flip->drawable_id) {
- status = dixLookupDrawable(&drawable,
- flip->drawable_id,
- serverClient,
- M_ANY, DixWriteAccess);
- if (status == Success) {
- if ((flip->fe_frame < flip->frame) &&
- (flip->frame - flip->fe_frame < 5)) {
- static int limit = 5;
-
- /* XXX we are currently hitting this path with older
- * kernels, so make it quieter.
- */
- if (limit) {
- xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
- "%s: Pageflip completion has impossible msc %d < target_msc %d\n",
- __func__, flip->fe_frame, flip->frame);
- limit--;
- }
-
- /* All-0 values signal timestamping failure. */
- flip->fe_frame = flip->fe_tv_sec = flip->fe_tv_usec = 0;
+ if (flip->drawable_id &&
+ dixLookupDrawable(&drawable,
+ flip->drawable_id,
+ serverClient,
+ M_ANY, DixWriteAccess) == Success) {
+ if ((flip->fe_frame < flip->frame) &&
+ (flip->frame - flip->fe_frame < 5)) {
+ static int limit = 5;
+
+ /* XXX we are currently hitting this path with older
+ * kernels, so make it quieter.
+ */
+ if (limit) {
+ xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
+ "%s: Pageflip completion has impossible msc %d < target_msc %d\n",
+ __func__, flip->fe_frame, flip->frame);
+ limit--;
}
- DBG(("%s: flip complete\n", __FUNCTION__));
- DRI2SwapComplete(flip->client, drawable,
- flip->fe_frame,
- flip->fe_tv_sec,
- flip->fe_tv_usec,
- DRI2_FLIP_COMPLETE,
- flip->client ? flip->event_complete : NULL,
- flip->event_data);
+ /* All-0 values signal timestamping failure. */
+ flip->fe_frame = flip->fe_tv_sec = flip->fe_tv_usec = 0;
}
+
+ DBG(("%s: flip complete\n", __FUNCTION__));
+ DRI2SwapComplete(flip->client, drawable,
+ flip->fe_frame,
+ flip->fe_tv_sec,
+ flip->fe_tv_usec,
+ DRI2_FLIP_COMPLETE,
+ flip->client ? flip->event_complete : NULL,
+ flip->event_data);
}
- sna_mode_delete_fb(flip->sna, flip->old_front, flip->old_fb);
+ sna_mode_delete_fb(flip->sna, flip->old_fb);
sna_dri_frame_event_info_free(flip);
break;
case DRI2_FLIP_THROTTLE:
+ sna_mode_delete_fb(sna, flip->old_fb);
+
assert(sna->dri.flip_pending[flip->pipe] == flip);
sna->dri.flip_pending[flip->pipe] = NULL;
- chain = flip->chain;
-
- sna_mode_delete_fb(flip->sna, flip->old_front, flip->old_fb);
- sna_dri_frame_event_info_free(flip);
-
- if (chain) {
- status = dixLookupDrawable(&drawable,
- chain->drawable_id,
- serverClient,
- M_ANY, DixWriteAccess);
- if (status == Success) {
- if (!(can_flip(chain->sna, drawable,
- chain->front, chain->back) &&
- sna_dri_flip(chain->sna, drawable, chain))) {
- sna_dri_copy(sna, drawable, NULL,
- chain->front, chain->back, true);
- DRI2SwapComplete(chain->client,
- drawable,
- 0, 0, 0,
- DRI2_BLIT_COMPLETE,
- chain->client ? chain->event_complete : NULL,
- chain->event_data);
- sna_dri_frame_event_info_free(chain);
- }
- } else
- sna_dri_frame_event_info_free(chain);
+ if (flip->next_front.name &&
+ flip->drawable_id &&
+ dixLookupDrawable(&drawable,
+ flip->drawable_id,
+ serverClient,
+ M_ANY, DixWriteAccess) == Success) {
+ if (!sna_dri_flip_continue(sna, drawable, flip)) {
+ DRI2SwapComplete(flip->client, drawable,
+ 0, 0, 0,
+ DRI2_BLIT_COMPLETE,
+ flip->client ? flip->event_complete : NULL,
+ flip->event_data);
+ sna_dri_frame_event_info_free(flip);
+ } else {
+ DRI2SwapComplete(flip->client, drawable,
+ 0, 0, 0,
+ DRI2_FLIP_COMPLETE,
+ flip->client ? flip->event_complete : NULL,
+ flip->event_data);
+ }
+ } else {
+ sna_dri_frame_event_info_free(flip);
}
break;
+#if DRI2INFOREC_VERSION >= 7
case DRI2_ASYNC_FLIP:
DBG(("%s: async swap flip completed on pipe %d, pending? %d, new? %d\n",
__FUNCTION__, flip->pipe,
sna->dri.flip_pending[flip->pipe] != NULL,
- flip->next_front != sna->front));
+ flip->front->name != flip->old_front.name));
assert(sna->dri.flip_pending[flip->pipe] == flip);
- sna_mode_delete_fb(flip->sna, flip->old_front, flip->old_fb);
-
- if (sna->front != flip->next_front) {
- PixmapPtr next = sna->front;
+ sna_mode_delete_fb(flip->sna, flip->old_fb);
+ if (flip->front->name != flip->next_front.name) {
DBG(("%s: async flip continuing\n", __FUNCTION__));
- flip->count = sna_do_pageflip(sna, next,
- flip, flip->pipe,
- &flip->old_fb);
- if (flip->count) {
- flip->old_front = flip->next_front;
- flip->next_front = next;
- flip->next_front->refcnt++;
- } else
+
+ flip->cache = flip->old_front;
+ flip->old_front = flip->next_front;
+ flip->next_front.bo = NULL;
+
+ flip->count = sna_page_flip(sna,
+ get_private(flip->front)->bo,
+ flip, flip->pipe,
+ &flip->old_fb);
+ if (flip->count == 0)
+ goto finish_async_flip;
+
+ flip->next_front.bo = get_private(flip->front)->bo;
+ flip->next_front.name = flip->front->name;
+ flip->off_delay = 5;
+ } else if (--flip->off_delay) {
+ /* Just queue a no-op flip to trigger another event */
+ flip->count = sna_page_flip(sna,
+ get_private(flip->front)->bo,
+ flip, flip->pipe,
+ &flip->old_fb);
+ if (flip->count == 0)
goto finish_async_flip;
} else {
finish_async_flip:
+ flip->next_front.bo = NULL;
+
DBG(("%s: async flip completed\n", __FUNCTION__));
- flip->next_front->drawable.pScreen->DestroyPixmap(flip->next_front);
sna->dri.flip_pending[flip->pipe] = NULL;
sna_dri_frame_event_info_free(flip);
}
break;
+#endif
default:
xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
@@ -1167,6 +1088,202 @@ sna_dri_page_flip_handler(int fd, unsigned int frame, unsigned int tv_sec,
sna_dri_flip_event(info->sna, info);
}
+static int
+sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
+ DRI2BufferPtr back, CARD64 *target_msc, CARD64 divisor,
+ CARD64 remainder, DRI2SwapEventPtr func, void *data)
+{
+ struct sna *sna = to_sna_from_drawable(draw);
+ struct sna_dri_frame_event *info;
+ drmVBlank vbl;
+ int pipe;
+ CARD64 current_msc;
+
+ DBG(("%s(target_msc=%llu, divisor=%llu, remainder=%llu)\n",
+ __FUNCTION__,
+ (long long)*target_msc,
+ (long long)divisor,
+ (long long)remainder));
+
+ /* Drawable not displayed... just complete the swap */
+ pipe = sna_dri_get_pipe(draw);
+ if (pipe == -1) {
+ DBG(("%s: off-screen, immediate update\n", __FUNCTION__));
+
+ sna_dri_exchange_attachment(front, back);
+ get_private(back)->pixmap = get_private(front)->pixmap;
+ get_private(front)->pixmap = NULL;
+ set_bo(get_private(back)->pixmap, get_private(back)->bo);
+ DRI2SwapComplete(client, draw, 0, 0, 0,
+ DRI2_EXCHANGE_COMPLETE, func, data);
+ return TRUE;
+ }
+
+ /* Truncate to match kernel interfaces; means occasional overflow
+ * misses, but that's generally not a big deal */
+ divisor &= 0xffffffff;
+ if (divisor == 0) {
+ int type = DRI2_FLIP_THROTTLE;
+
+ DBG(("%s: performing immediate swap on pipe %d, pending? %d\n",
+ __FUNCTION__, pipe, sna->dri.flip_pending[pipe] != NULL));
+
+ info = sna->dri.flip_pending[pipe];
+ if (info) {
+ if (info->drawable_id == draw->id) {
+ DBG(("%s: chaining flip\n", __FUNCTION__));
+ info->next_front.name = 1;
+ return TRUE;
+ } else {
+ /* We need to first wait (one vblank) for the
+ * async flips to complete before this client can
+ * take over.
+ */
+ type = DRI2_FLIP;
+ }
+ }
+
+ info = calloc(1, sizeof(struct sna_dri_frame_event));
+ if (!info)
+ return FALSE;
+
+ info->type = type;
+
+ info->sna = sna;
+ info->drawable_id = draw->id;
+ info->client = client;
+ info->event_complete = func;
+ info->event_data = data;
+ info->front = front;
+ info->back = back;
+ info->pipe = pipe;
+
+ if (!sna_dri_add_frame_event(info)) {
+ DBG(("%s: failed to hook up frame event\n", __FUNCTION__));
+ free(info);
+ return FALSE;
+ }
+
+ if (!sna_dri_page_flip(sna, info)) {
+ DBG(("%s: failed to queue page flip\n", __FUNCTION__));
+ free(info);
+ return FALSE;
+ }
+
+ sna_dri_reference_buffer(front);
+ sna_dri_reference_buffer(back);
+
+ get_private(info->back)->bo =
+ kgem_create_2d(&sna->kgem,
+ draw->width,
+ draw->height,
+ draw->bitsPerPixel,
+ get_private(info->front)->bo->tiling,
+ CREATE_EXACT);
+ info->back->name = kgem_bo_flink(&sna->kgem,
+ get_private(info->back)->bo);
+ sna->dri.flip_pending[info->pipe] = info;
+
+ DRI2SwapComplete(info->client, draw, 0, 0, 0,
+ DRI2_EXCHANGE_COMPLETE,
+ info->event_complete,
+ info->event_data);
+ } else {
+ info = calloc(1, sizeof(struct sna_dri_frame_event));
+ if (info)
+ return FALSE;
+
+ info->sna = sna;
+ info->drawable_id = draw->id;
+ info->client = client;
+ info->event_complete = func;
+ info->event_data = data;
+ info->front = front;
+ info->back = back;
+ info->pipe = pipe;
+ info->type = DRI2_FLIP;
+
+ if (!sna_dri_add_frame_event(info)) {
+ DBG(("%s: failed to hook up frame event\n", __FUNCTION__));
+ free(info);
+ return FALSE;
+ }
+
+ sna_dri_reference_buffer(front);
+ sna_dri_reference_buffer(back);
+
+ /* Get current count */
+ vbl.request.type = DRM_VBLANK_RELATIVE;
+ if (pipe > 0)
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
+ vbl.request.sequence = 0;
+ if (drmWaitVBlank(sna->kgem.fd, &vbl)) {
+ free(info);
+ return FALSE;
+ }
+
+ current_msc = vbl.reply.sequence;
+ *target_msc &= 0xffffffff;
+ remainder &= 0xffffffff;
+
+ vbl.request.type =
+ DRM_VBLANK_ABSOLUTE |
+ DRM_VBLANK_EVENT;
+ if (pipe > 0)
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
+
+ /*
+ * If divisor is zero, or current_msc is smaller than target_msc
+ * we just need to make sure target_msc passes before initiating
+ * the swap.
+ */
+ if (current_msc < *target_msc) {
+ DBG(("%s: waiting for swap: current=%d, target=%d, divisor=%d\n",
+ __FUNCTION__,
+ (int)current_msc,
+ (int)*target_msc,
+ (int)divisor));
+ vbl.request.sequence = *target_msc;
+ } else {
+ DBG(("%s: missed target, queueing event for next: current=%d, target=%d, divisor=%d\n",
+ __FUNCTION__,
+ (int)current_msc,
+ (int)*target_msc,
+ (int)divisor));
+
+ vbl.request.sequence = current_msc - current_msc % divisor + remainder;
+
+ /*
+ * If the calculated deadline vbl.request.sequence is smaller than
+ * or equal to current_msc, it means we've passed the last point
+ * when effective onset frame seq could satisfy
+ * seq % divisor == remainder, so we need to wait for the next time
+ * this will happen.
+ *
+ * This comparison takes the 1 frame swap delay in pageflipping mode
+ * into account.
+ */
+ if (vbl.request.sequence <= current_msc)
+ vbl.request.sequence += divisor;
+
+ /* Adjust returned value for 1 frame pageflip offset */
+ *target_msc = vbl.reply.sequence + 1;
+ }
+
+ /* Account for 1 frame extra pageflip delay */
+ vbl.request.sequence -= 1;
+ vbl.request.signal = (unsigned long)info;
+ if (drmWaitVBlank(sna->kgem.fd, &vbl)) {
+ free(info);
+ return FALSE;
+ }
+
+ info->frame = *target_msc;
+ }
+
+ return TRUE;
+}
+
/*
* ScheduleSwap is responsible for requesting a DRM vblank event for the
* appropriate frame.
@@ -1196,7 +1313,7 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct sna *sna = to_sna(scrn);
drmVBlank vbl;
- int pipe, flip;
+ int pipe;
struct sna_dri_frame_event *info = NULL;
enum frame_event_type swap_type = DRI2_SWAP;
CARD64 current_msc;
@@ -1207,31 +1324,21 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
(long long)divisor,
(long long)remainder));
- flip = 0;
if (can_flip(sna, draw, front, back)) {
- DBG(("%s: can flip\n", __FUNCTION__));
- swap_type = DRI2_FLIP;
- flip = 1;
+ DBG(("%s: try flip\n", __FUNCTION__));
+ if (!sna_dri_schedule_flip(client, draw, front, back,
+ target_msc, divisor, remainder,
+ func, data))
+ goto blit_fallback;
+
+ return TRUE;
}
/* Drawable not displayed... just complete the swap */
pipe = sna_dri_get_pipe(draw);
if (pipe == -1) {
- struct sna_dri_private *back_priv = back->driverPrivate;
- PixmapPtr pixmap;
-
DBG(("%s: off-screen, immediate update\n", __FUNCTION__));
-
- if (!flip)
- goto blit_fallback;
-
- pixmap = sna_set_screen_pixmap(sna, back_priv->pixmap);
- assert(pixmap->refcnt > 1);
- pixmap->refcnt--;
- sna_dri_exchange_buffers(front, back);
- DRI2SwapComplete(client, draw, 0, 0, 0,
- DRI2_EXCHANGE_COMPLETE, func, data);
- return TRUE;
+ goto blit_fallback;
}
/* Truncate to match kernel interfaces; means occasional overflow
@@ -1265,10 +1372,6 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
info->type = swap_type;
if (divisor == 0) {
- DBG(("%s: performing immediate swap\n", __FUNCTION__));
- if (flip && sna_dri_flip(sna, draw, info))
- return TRUE;
-
DBG(("%s: emitting immediate vsync'ed blit, throttling client\n",
__FUNCTION__));
@@ -1287,7 +1390,10 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data);
}
- sna_dri_copy(sna, draw, NULL, front, back, true);
+ sna_dri_copy(sna, draw, NULL,
+ get_private(front)->bo,
+ get_private(back)->bo,
+ true);
return TRUE;
}
@@ -1297,9 +1403,6 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
vbl.request.type |= DRM_VBLANK_SECONDARY;
vbl.request.sequence = 0;
if (drmWaitVBlank(sna->kgem.fd, &vbl)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "first get vblank counter failed: %s\n",
- strerror(errno));
goto blit_fallback;
}
@@ -1318,14 +1421,14 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
(int)divisor));
info->frame = *target_msc;
- info->type = flip ? DRI2_FLIP : DRI2_SWAP;
+ info->type = DRI2_SWAP;
vbl.request.type =
DRM_VBLANK_ABSOLUTE |
DRM_VBLANK_EVENT;
if (pipe > 0)
vbl.request.type |= DRM_VBLANK_SECONDARY;
- vbl.request.sequence = *target_msc - flip;
+ vbl.request.sequence = *target_msc;
vbl.request.signal = (unsigned long)info;
if (drmWaitVBlank(sna->kgem.fd, &vbl))
goto blit_fallback;
@@ -1345,8 +1448,7 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
(int)divisor));
vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
- if (flip == 0)
- vbl.request.type |= DRM_VBLANK_NEXTONMISS;
+ vbl.request.type |= DRM_VBLANK_NEXTONMISS;
if (pipe > 0)
vbl.request.type |= DRM_VBLANK_SECONDARY;
@@ -1366,25 +1468,21 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
if (vbl.request.sequence <= current_msc)
vbl.request.sequence += divisor;
- /* Account for 1 frame extra pageflip delay if flip > 0 */
- vbl.request.sequence -= flip;
-
vbl.request.signal = (unsigned long)info;
if (drmWaitVBlank(sna->kgem.fd, &vbl)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "final get vblank counter failed: %s\n",
- strerror(errno));
goto blit_fallback;
}
- /* Adjust returned value for 1 fame pageflip offset of flip > 0 */
- *target_msc = vbl.reply.sequence + flip;
+ *target_msc = vbl.reply.sequence;
info->frame = *target_msc;
return TRUE;
blit_fallback:
DBG(("%s -- blit\n", __FUNCTION__));
- sna_dri_copy(sna, draw, NULL, front, back, true);
+ sna_dri_copy(sna, draw, NULL,
+ get_private(front)->bo,
+ get_private(back)->bo,
+ true);
if (info)
sna_dri_frame_event_info_free(info);
DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data);
@@ -1392,38 +1490,46 @@ blit_fallback:
return TRUE;
}
-#if DRI2INFOREC_VERSION >= 6
+#if DRI2INFOREC_VERSION >= 7
static void
sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
DRI2BufferPtr front, DRI2BufferPtr back,
DRI2SwapEventPtr func, void *data)
{
- ScreenPtr screen = draw->pScreen;
- struct sna *sna = to_sna_from_screen(screen);
- int type = DRI2_EXCHANGE_COMPLETE;
- struct sna_dri_private *back_priv = back->driverPrivate;
- struct sna_dri_private *front_priv = front->driverPrivate;
+ struct sna *sna = to_sna_from_drawable(draw);
struct sna_dri_frame_event *info;
- PixmapPtr pixmap;
- int pipe;
+ struct kgem_bo *bo;
+ int name, pipe;
DBG(("%s()\n", __FUNCTION__));
+ pipe = sna_dri_get_pipe(draw);
+ if (pipe == -1) {
+ PixmapPtr pixmap = get_drawable_pixmap(draw);
+
+ set_bo(pixmap, get_private(back)->bo);
+ sna_dri_exchange_attachment(front, back);
+ get_private(back)->pixmap = pixmap;
+ get_private(front)->pixmap = NULL;
+
+ DRI2SwapComplete(client, draw, 0, 0, 0,
+ DRI2_EXCHANGE_COMPLETE, func, data);
+ return;
+ }
+
if (!can_flip(sna, draw, front, back)) {
blit:
- sna_dri_copy(sna, draw, NULL, front, back, false);
+ sna_dri_copy(sna, draw, NULL,
+ get_private(front)->bo,
+ get_private(back)->bo,
+ false);
DRI2SwapComplete(client, draw, 0, 0, 0,
DRI2_BLIT_COMPLETE, func, data);
return;
}
- assert(front_priv->pixmap == sna->front);
-
- pipe = sna_dri_get_pipe(draw);
- if (pipe == -1) {
- /* Drawable not displayed... just complete the swap */
- goto exchange;
- }
+ bo = NULL;
+ name = 0;
info = sna->dri.flip_pending[pipe];
if (info == NULL) {
@@ -1432,71 +1538,68 @@ blit:
info = calloc(1, sizeof(struct sna_dri_frame_event));
if (!info)
- goto exchange;
+ goto blit;
info->sna = sna;
+ info->client = client;
info->type = DRI2_ASYNC_FLIP;
info->pipe = pipe;
- info->client = client;
+ info->front = front;
+ info->back = back;
if (!sna_dri_add_frame_event(info)) {
DBG(("%s: failed to hook up frame event\n", __FUNCTION__));
free(info);
info = NULL;
- goto exchange;
+ goto blit;
}
- info->count = sna_do_pageflip(sna, back_priv->pixmap,
- info, pipe,
- &info->old_fb);
-
- if (info->count == 0) {
- DBG(("%s: pageflip failed\n", __FUNCTION__));
+ if (!sna_dri_page_flip(sna, info)) {
free(info);
- goto exchange;
+ goto blit;
}
- info->old_front = sna->front;
- info->old_front->refcnt++;
+ info->next_front.name = info->front->name;
+ info->next_front.bo = get_private(info->front)->bo;
+ info->off_delay = 5;
- info->next_front = back_priv->pixmap;
- info->next_front->refcnt++;
+ sna_dri_reference_buffer(front);
+ sna_dri_reference_buffer(back);
- type = DRI2_FLIP_COMPLETE;
- sna->dri.flip_pending[pipe] = info;
-
- if ((pixmap = screen->CreatePixmap(screen,
- draw->width,
- draw->height,
- draw->depth,
- SNA_CREATE_FB))) {
- DBG(("%s: new back buffer\n", __FUNCTION__));
- set_pixmap(sna, front, pixmap);
- }
} else if (info->type != DRI2_ASYNC_FLIP) {
/* A normal vsync'ed client is finishing, wait for it
- * to unpin the old framebuffer before taking* pver.
+ * to unpin the old framebuffer before taking over.
*/
goto blit;
+ } else {
+ if (info->next_front.name == info->front->name) {
+ name = info->cache.name;
+ bo = info->cache.bo;
+ } else {
+ name = info->front->name;
+ bo = get_private(info->front)->bo;
+ }
+ info->front->name = info->back->name;
+ get_private(info->front)->bo = get_private(info->back)->bo;
}
- if (front_priv->pixmap == info->next_front &&
- (pixmap = screen->CreatePixmap(screen,
- draw->width,
- draw->height,
- draw->depth,
- SNA_CREATE_FB))) {
- DBG(("%s: new back buffer\n", __FUNCTION__));
- set_pixmap(sna, front, pixmap);
- }
+ if (bo == NULL)
+ bo = kgem_create_2d(&sna->kgem,
+ draw->width,
+ draw->height,
+ draw->bitsPerPixel,
+ I915_TILING_X, CREATE_EXACT);
+ get_private(info->back)->bo = bo;
-exchange:
- damage_all(back_priv->pixmap);
- pixmap = sna_set_screen_pixmap(sna, back_priv->pixmap);
- screen->DestroyPixmap(pixmap);
+ if (name == 0)
+ name = kgem_bo_flink(&sna->kgem, bo);
+ info->back->name = name;
+
+ set_bo(sna->front, get_private(info->front)->bo);
+ sna->dri.flip_pending[info->pipe] = info;
- sna_dri_exchange_buffers(front, back);
- DRI2SwapComplete(client, draw, 0, 0, 0, type, func, data);
+ DRI2SwapComplete(client, draw, 0, 0, 0,
+ DRI2_EXCHANGE_COMPLETE, func, data);
}
#endif
@@ -1698,8 +1801,7 @@ static unsigned int dri2_server_generation;
Bool sna_dri_open(struct sna *sna, ScreenPtr screen)
{
DRI2InfoRec info;
- int dri2_major = 1;
- int dri2_minor = 0;
+ int major = 1, minor = 0;
#if DRI2INFOREC_VERSION >= 4
const char *driverNames[1];
#endif
@@ -1713,9 +1815,9 @@ Bool sna_dri_open(struct sna *sna, ScreenPtr screen)
}
if (xf86LoaderCheckSymbol("DRI2Version"))
- DRI2Version(&dri2_major, &dri2_minor);
+ DRI2Version(&major, &minor);
- if (dri2_minor < 1) {
+ if (minor < 1) {
xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
"DRI2 requires DRI2 module version 1.1.0 or later\n");
return FALSE;
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index d834c0a..693febc 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -613,12 +613,12 @@ sna_wakeup_handler(int i, pointer data, unsigned long result, pointer read_mask)
if ((int)result < 0)
return;
- if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask))
- sna_dri_wakeup(sna);
-
sna->WakeupHandler(i, sna->WakeupData, result, read_mask);
sna_accel_wakeup_handler(sna);
+
+ if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask))
+ sna_dri_wakeup(sna);
}
#if HAVE_UDEV
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index cc37901..04366be 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -432,7 +432,6 @@ struct kgem_bo *sna_replace(struct sna *sna,
DBG(("%s(handle=%d, %dx%d, bpp=%d, tiling=%d)\n",
__FUNCTION__, bo->handle, width, height, bpp, bo->tiling));
- assert(bo->reusable);
if (kgem_bo_is_busy(bo)) {
struct kgem_bo *new_bo;
commit aac022cbb3342e7027301a3f8c9add8929edbad6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 14 19:49:29 2011 +0000
sna: Optimise single pixel transfers
Surprisingly frequent.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/blt.c b/src/sna/blt.c
index ca15453..1b56cc7 100644
--- a/src/sna/blt.c
+++ b/src/sna/blt.c
@@ -64,9 +64,45 @@ memcpy_blt(const void *src, void *dst, int bpp,
return;
}
- do {
- memcpy(dst_bytes, src_bytes, byte_width);
- src_bytes += src_stride;
- dst_bytes += dst_stride;
- } while (--height);
+ switch (byte_width) {
+ case 1:
+ do {
+ *dst_bytes = *src_bytes;
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+ } while (--height);
+ break;
+
+ case 2:
+ do {
+ *(uint16_t *)dst_bytes = *(uint16_t *)src_bytes;
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+ } while (--height);
+ break;
+
+ case 4:
+ do {
+ *(uint32_t *)dst_bytes = *(uint32_t *)src_bytes;
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+ } while (--height);
+ break;
+
+ case 8:
+ do {
+ *(uint64_t *)dst_bytes = *(uint64_t *)src_bytes;
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+ } while (--height);
+ break;
+
+ default:
+ do {
+ memcpy(dst_bytes, src_bytes, byte_width);
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+ } while (--height);
+ break;
+ }
}
More information about the xorg-commit
mailing list