[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-vmware: Changes to 'upstream-ubuntu'



 configure.ac                |    6 
 src/vmware_bootstrap.c      |   20 ++
 src/vmware_bootstrap.h      |    2 
 src/vmwarevideo.c           |    4 
 vmwgfx/Makefile.am          |    5 
 vmwgfx/vmwgfx_dri2.c        |   37 +++++
 vmwgfx/vmwgfx_driver.c      |  309 ++++++++++++++++++++++++++------------------
 vmwgfx/vmwgfx_driver.h      |    4 
 vmwgfx/vmwgfx_drmi.c        |  142 ++++++++++++++++++++
 vmwgfx/vmwgfx_drmi.h        |   13 +
 vmwgfx/vmwgfx_hosted.c      |   71 ++++++++++
 vmwgfx/vmwgfx_hosted.h      |  258 ++++++++++++++++++++++++++++++++++++
 vmwgfx/vmwgfx_hosted_priv.h |   40 +++++
 vmwgfx/vmwgfx_overlay.c     |    8 -
 vmwgfx/vmwgfx_saa.c         |  263 ++++++++++++++++++++++++++++++++-----
 vmwgfx/vmwgfx_saa.h         |    7 
 vmwgfx/vmwgfx_saa_priv.h    |    2 
 vmwgfx/vmwgfx_tex_video.c   |    2 
 vmwgfx/vmwgfx_xa_surface.c  |    2 
 vmwgfx/vmwgfx_xmir.c        |  178 +++++++++++++++++++++++++
 vmwgfx/vmwgfx_xwayland.c    |  186 ++++++++++++++++++++++++++
 21 files changed, 1393 insertions(+), 166 deletions(-)

New commits:
commit 8da981712f62050076cff53e1b40ed1e307fcca8
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date:   Wed Jan 15 11:04:05 2014 +0100

    vmware/vmwgfx: Always allocate shared hardware surfaces.
    
    Hardware surfaces are all likely to be shared at some point, and we *really*
    don't want to change a hardware surface that is bound as a drm framebuffer.
    
    Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
    Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>

diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 8c97618..b56b05f 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -811,7 +811,7 @@ vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
 	return TRUE;
 
     new_flags = (vpix->xa_flags & ~vpix->staging_remove_flags) |
-	vpix->staging_add_flags;
+	vpix->staging_add_flags | XA_FLAG_SHARED;
 
     hw = xa_surface_create(vsaa->xat,
 			   pixmap->drawable.width,
diff --git a/vmwgfx/vmwgfx_xa_surface.c b/vmwgfx/vmwgfx_xa_surface.c
index 2f23c57..189bfdc 100644
--- a/vmwgfx/vmwgfx_xa_surface.c
+++ b/vmwgfx/vmwgfx_xa_surface.c
@@ -318,7 +318,7 @@ vmwgfx_hw_commit(PixmapPtr pixmap)
 	uint32_t new_flags;
 
 	new_flags = (vpix->xa_flags & ~vpix->staging_remove_flags) |
-	    vpix->staging_add_flags;
+	    vpix->staging_add_flags | XA_FLAG_SHARED;
 
 	if (vpix->staging_format != xa_surface_format(vpix->hw))
 	    LogMessage(X_INFO, "Changing hardware format.\n");

commit 31bff9f7f3d9a68fd1449532e8ab50065de63857
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date:   Thu Jan 9 13:53:59 2014 +0100

    vmware: Require libdrm 2.4.38 to build XMir.
    
    Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
    Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>

diff --git a/configure.ac b/configure.ac
index 123356c..3e8d541 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,6 +127,12 @@ if test x$BUILD_VMWGFX = xyes; then
 	                  [AC_DEFINE([HAVE_XA_2], 1,
                		  [Has version 2 of XA])])],
 			  [],[BUILD_VMWGFX=no])
+#
+# Check for prime.
+#
+	PKG_CHECK_EXISTS([libdrm >= 2.4.38],
+			 [AC_DEFINE([HAVE_LIBDRM_2_4_38], 1,
+			 [Has version 2.4.38 or greater of libdrm])])
 fi
 
 DRIVER_NAME=vmware
diff --git a/vmwgfx/vmwgfx_drmi.c b/vmwgfx/vmwgfx_drmi.c
index d926019..b6fb56d 100644
--- a/vmwgfx/vmwgfx_drmi.c
+++ b/vmwgfx/vmwgfx_drmi.c
@@ -501,6 +501,7 @@ vmwgfx_max_fb_size(int drm_fd, size_t *size)
     return 0;
 }
 
+#ifdef HAVE_LIBDRM_2_4_38
 /**
  * vmwgfx_prime_fd_to_handle - Return a TTM handle to a prime object
  *
@@ -537,3 +538,4 @@ vmwgfx_prime_release_handle(int drm_fd, uint32_t handle)
     (void) drmCommandWrite(drm_fd, DRM_VMW_UNREF_SURFACE, &s_arg,
 			   sizeof(s_arg));
 }
+#endif /* HAVE_LIBDRM_2_4_38 */
diff --git a/vmwgfx/vmwgfx_drmi.h b/vmwgfx/vmwgfx_drmi.h
index 1494485..3168088 100644
--- a/vmwgfx/vmwgfx_drmi.h
+++ b/vmwgfx/vmwgfx_drmi.h
@@ -85,9 +85,11 @@ vmwgfx_update_gui_layout(int drm_fd, unsigned int num_rects,
 int
 vmwgfx_get_param(int drm_fd, uint32_t param, uint64_t *out);
 
+#ifdef HAVE_LIBDRM_2_4_38
 int
 vmwgfx_prime_fd_to_handle(int drm_fd, int prime_fd, uint32_t *handle);
 
 void
 vmwgfx_prime_release_handle(int drm_fd, uint32_t handle);
+#endif /* HAVE_LIBDRM_2_4_38 */
 #endif
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index cb55849..8c97618 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1618,7 +1618,7 @@ vmwgfx_saa_drop_master(ScreenPtr pScreen)
  * Helpers for hosted.
  */
 
-#if (XA_TRACKER_VERSION_MAJOR >= 2)
+#if (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38)
 
 /**
  * vmwgfx_saa_copy_to_surface - Copy Drawable contents to an external surface.
diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h
index 55f0ded..921fabd 100644
--- a/vmwgfx/vmwgfx_saa.h
+++ b/vmwgfx/vmwgfx_saa.h
@@ -116,9 +116,11 @@ vmwgfx_saa_set_master(ScreenPtr pScreen);
 void
 vmwgfx_saa_drop_master(ScreenPtr pScreen);
 
+#if (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38)
 Bool
 vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
 			   const BoxRec *dst_box, RegionPtr region);
+#endif /* (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38) */
 
 #if (XA_TRACKER_VERSION_MAJOR <= 1) && !defined(HAVE_XA_2)
 
diff --git a/vmwgfx/vmwgfx_xmir.c b/vmwgfx/vmwgfx_xmir.c
index e0ff6a4..ede6753 100644
--- a/vmwgfx/vmwgfx_xmir.c
+++ b/vmwgfx/vmwgfx_xmir.c
@@ -32,7 +32,7 @@
 #include "vmwgfx_hosted_priv.h"
 #include <xa_tracker.h>
 
-#if XMIR && (XA_TRACKER_VERSION_MAJOR >= 2)
+#if XMIR && (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38)
 
 #include "vmwgfx_hosted.h"
 #include "vmwgfx_saa.h"

commit d6b179a5addef6456325adf241eb8dcaf8e4c3d6
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date:   Thu Jan 9 13:28:22 2014 +0100

    vmware: Fix build errors and warnings
    
    A previous commit and the hosted merge unfortunately brought in some build
    errors / warnings on early X servers.
    
    Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
    Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>

diff --git a/src/vmware_bootstrap.c b/src/vmware_bootstrap.c
index 57f8ae9..ed6c740 100644
--- a/src/vmware_bootstrap.c
+++ b/src/vmware_bootstrap.c
@@ -34,6 +34,7 @@
 #include "xf86Pci.h"		/* pci */
 #include "vm_device_version.h"
 #include "vmware_bootstrap.h"
+#include <stdint.h>
 
 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
 #include "xf86Resources.h"
diff --git a/src/vmwarevideo.c b/src/vmwarevideo.c
index 8d7d171..745c71f 100644
--- a/src/vmwarevideo.c
+++ b/src/vmwarevideo.c
@@ -82,7 +82,7 @@
 #define VMWARE_VID_MAX_HEIGHT   2048
 
 #define VMWARE_VID_NUM_ENCODINGS 1
-static const XF86VideoEncodingRec vmwareVideoEncodings[] =
+static XF86VideoEncodingRec vmwareVideoEncodings[] =
 {
     {
        0,
@@ -108,7 +108,7 @@ static XF86ImageRec vmwareVideoImages[] =
 };
 
 #define VMWARE_VID_NUM_ATTRIBUTES 2
-static const XF86AttributeRec vmwareVideoAttributes[] =
+static XF86AttributeRec vmwareVideoAttributes[] =
 {
     {
         XvGettable | XvSettable,
diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index dc05b86..2d38d2a 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -130,7 +130,7 @@ vmwgfx_hookup(ScrnInfoPtr pScrn)
 }
 
 void
-vmwgfx_modify_flags(CARD32 *flags)
+vmwgfx_modify_flags(uint32_t *flags)
 {
     *flags &= ~(HW_IO);
     vmwgfx_hosted_modify_flags(flags);
diff --git a/vmwgfx/vmwgfx_overlay.c b/vmwgfx/vmwgfx_overlay.c
index c8c6bb9..2c0d7fa 100644
--- a/vmwgfx/vmwgfx_overlay.c
+++ b/vmwgfx/vmwgfx_overlay.c
@@ -85,7 +85,7 @@ typedef uint8_t uint8;
 #define VMWARE_VID_MAX_HEIGHT   2048
 
 #define VMWARE_VID_NUM_ENCODINGS 1
-static const XF86VideoEncodingRec vmwareVideoEncodings[] =
+static XF86VideoEncodingRec vmwareVideoEncodings[] =
 {
     {
        0,
@@ -111,7 +111,7 @@ static XF86ImageRec vmwareVideoImages[] =
 };
 
 #define VMWARE_VID_NUM_ATTRIBUTES 2
-static const XF86AttributeRec vmwareVideoAttributes[] =
+static XF86AttributeRec vmwareVideoAttributes[] =
 {
     {
         XvGettable | XvSettable,
diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index 9fd8f22..0803a99 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -82,7 +82,7 @@ static XF86VideoFormatRec Formats[NUM_FORMATS] = {
    {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 };
 
-static const XF86VideoEncodingRec DummyEncoding[1] = {
+static XF86VideoEncodingRec DummyEncoding[1] = {
    {
       0,
       "XV_IMAGE",

commit f37684e7169b9c0ab23ff748d5acacb65fad82f7
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date:   Tue Jan 7 17:55:49 2014 +0100

    vmwgfx: Block DMA to prime surfaces for now
    
    Since there is currently no _good_ way to get the surface format of a
    prime surface, we block DMA to these surfaces; we don't know if our
    software data is compatible with the surface format.
    
    This patch also makes sure that there is a hardware surface backing the
    drawable we copy from.
    
    Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
    Reviewed-by: Brian Paul <brianp@vmware.com>
    Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>

diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index c323c5f..cb55849 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1428,6 +1428,7 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
     vsaa->only_hw_presents = only_hw_presents;
     vsaa->rendercheck = rendercheck;
     vsaa->is_master = TRUE;
+    vsaa->known_prime_format = FALSE;
     WSBMINITLISTHEAD(&vsaa->sync_x_list);
     WSBMINITLISTHEAD(&vsaa->pixmaps);
 
@@ -1688,23 +1689,24 @@ vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
 
     /*
      * Determine the intersection between software contents and region to copy.
-     * XXX: First check that the software contents is compatible with the
-     * external surface format, before applying this optimization.
      */
-    REGION_NULL(pScreen, &intersection);
-    if (!vpix->hw)
-	REGION_COPY(pScreen, &intersection, region);
-    else if (spix->damage && REGION_NOTEMPTY(pScreen, &spix->dirty_shadow))
-	REGION_INTERSECT(pScreen, &intersection, region, &spix->dirty_shadow);
 
-    /*
-     * DMA software contents directly into the destination. Then subtract
-     * the region we've DMA'd from the region to copy.
-     */
-    if (REGION_NOTEMPTY(pScreen, &intersection)) {
-	if (vmwgfx_saa_dma(vsaa, src, &intersection, TRUE, dx, dy, dst)) {
-	    REGION_SUBTRACT(pScreen, &intersection, region, &intersection);
-	    copy_region = &intersection;
+    if (vsaa->known_prime_format) {
+	REGION_NULL(pScreen, &intersection);
+	if (!vpix->hw)
+	    REGION_COPY(pScreen, &intersection, region);
+	else if (spix->damage && REGION_NOTEMPTY(pScreen, &spix->dirty_shadow))
+	    REGION_INTERSECT(pScreen, &intersection, region, &spix->dirty_shadow);
+
+	/*
+	 * DMA software contents directly into the destination. Then subtract
+	 * the region we've DMA'd from the region to copy.
+	 */
+	if (REGION_NOTEMPTY(pScreen, &intersection)) {
+	    if (vmwgfx_saa_dma(vsaa, src, &intersection, TRUE, dx, dy, dst)) {
+		REGION_SUBTRACT(pScreen, &intersection, region, &intersection);
+		copy_region = &intersection;
+	    }
 	}
     }
 
@@ -1717,6 +1719,11 @@ vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
     box = REGION_RECTS(copy_region);
     n = REGION_NUM_RECTS(copy_region);
 
+    if (!vmwgfx_hw_accel_validate(src, 0, 0, 0, copy_region)) {
+	ret = FALSE;
+	goto out_no_copy;
+    }
+
     if (xa_copy_prepare(vsaa->xa_ctx, dst, vpix->hw) != XA_ERR_NONE) {
 	ret = FALSE;
 	goto out_no_copy;
@@ -1732,7 +1739,8 @@ vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
     xa_context_flush(vsaa->xa_ctx);
 
   out_no_copy:
-    REGION_UNINIT(pScreen, &intersection);
+    if (vsaa->known_prime_format)
+	REGION_UNINIT(pScreen, &intersection);
     if (sx || sy)
 	REGION_TRANSLATE(pScreen, region, -sx, -sy);
     xa_surface_unref(dst);
diff --git a/vmwgfx/vmwgfx_saa_priv.h b/vmwgfx/vmwgfx_saa_priv.h
index 16583b0..c84827b 100644
--- a/vmwgfx/vmwgfx_saa_priv.h
+++ b/vmwgfx/vmwgfx_saa_priv.h
@@ -55,6 +55,7 @@ struct vmwgfx_saa {
     Bool only_hw_presents;
     Bool rendercheck;
     Bool is_master;
+    Bool known_prime_format;
     void (*present_flush) (ScreenPtr pScreen);
     struct _WsbmListHead sync_x_list;
     struct _WsbmListHead pixmaps;

commit 97ce302ddd6e86397ea56ea9089b9549af73c3ac
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date:   Mon Jan 6 12:37:36 2014 +0100

    vmwgfx: Enable direct dmas
    
    Enable direct dmas instead of using the xa-provided dma functionality.
    This saves a bounce-buffer software copy of all dma'd contents.
    
    This also implies that all drawables with mixed software / hardware contents
    will use a kernel buffer for software rendering.
    
    Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
    Reviewed-by: Brian Paul <brianp@vmware.com>

diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index c8b4df1..c323c5f 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1423,7 +1423,7 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
 	vsaa->xa_ctx = xa_context_default(xat);
     vsaa->drm_fd = drm_fd;
     vsaa->present_flush = present_flush;
-    vsaa->can_optimize_dma = FALSE;
+    vsaa->can_optimize_dma = TRUE;
     vsaa->use_present_opt = direct_presents;
     vsaa->only_hw_presents = only_hw_presents;
     vsaa->rendercheck = rendercheck;

commit fd636e39a3f32a6dcd107c370513d8cb9aae26c2
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date:   Mon Dec 16 06:21:09 2013 -0800

    vmwgfx: Add support for XWayland
    
    Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
    Reviewed-by: Brian Paul <brianp@vmware.com>
    Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>

diff --git a/vmwgfx/Makefile.am b/vmwgfx/Makefile.am
index 41833a1..81b9e08 100644
--- a/vmwgfx/Makefile.am
+++ b/vmwgfx/Makefile.am
@@ -29,5 +29,6 @@ libvmwgfx_la_SOURCES = \
 	vmwgfx_hosted.h \
 	vmwgfx_hosted_priv.h \
 	vmwgfx_xmir.c \
+	vmwgfx_xwayland.c \
 	wsbm_util.h
 endif
diff --git a/vmwgfx/vmwgfx_hosted.c b/vmwgfx/vmwgfx_hosted.c
index 018b88b..9b41f3e 100644
--- a/vmwgfx/vmwgfx_hosted.c
+++ b/vmwgfx/vmwgfx_hosted.c
@@ -48,6 +48,9 @@ vmwgfx_hosted_detect(void)
 {
     const struct vmwgfx_hosted_driver *tmp = vmwgfx_xmir_detect();
 
+    if (!tmp)
+	tmp = vmwgfx_xwl_detect();
+
     return tmp;
 }
 
@@ -64,4 +67,5 @@ void
 vmwgfx_hosted_modify_flags(uint32_t *flags)
 {
     vmwgfx_xmir_modify_flags(flags);
+    vmwgfx_xwl_modify_flags(flags);
 }
diff --git a/vmwgfx/vmwgfx_hosted_priv.h b/vmwgfx/vmwgfx_hosted_priv.h
index c81f5ee..2668e55 100644
--- a/vmwgfx/vmwgfx_hosted_priv.h
+++ b/vmwgfx/vmwgfx_hosted_priv.h
@@ -34,4 +34,7 @@
 extern const struct vmwgfx_hosted_driver *vmwgfx_xmir_detect(void);
 extern void vmwgfx_xmir_modify_flags(uint32_t *flags);
 
+extern const struct vmwgfx_hosted_driver *vmwgfx_xwl_detect(void);
+extern void vmwgfx_xwl_modify_flags(uint32_t *flags);
+
 #endif
diff --git a/vmwgfx/vmwgfx_xwayland.c b/vmwgfx/vmwgfx_xwayland.c
new file mode 100644
index 0000000..a16a7c4
--- /dev/null
+++ b/vmwgfx/vmwgfx_xwayland.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 VMWare, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ * Author: Jakob Bornecrantz <jakob@vmware.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmwgfx_hosted_priv.h"
+
+#ifdef XORG_WAYLAND
+
+#include "vmwgfx_hosted.h"
+#include "vmwgfx_saa.h"
+#include <xf86Priv.h>
+#include <xwayland.h>
+
+struct vmwgfx_hosted {
+    struct xwl_screen *xwl;
+    ScrnInfoPtr pScrn;
+    ScreenPtr pScreen;
+};
+
+static int
+vmwgfx_create_window_buffer(struct xwl_window *xwl_window,
+			    PixmapPtr pixmap)
+{
+    struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
+    uint32_t name, pitch;
+
+    if (!vmwgfx_hw_dri2_validate(pixmap, 0))
+	return BadDrawable;
+
+    /*
+     * Pixmaps with hw_is_hosted == TRUE are put on a flush list when
+     * they've seen software rendering. When vmwgfx_flush_dri2 is called
+     * on these pixmaps, software contents are flushed to the hardware
+     * surface.
+     */
+    vpix->hw_is_hosted = TRUE;
+    if (xa_surface_handle(vpix->hw, &name, &pitch) != XA_ERR_NONE)
+	return BadDrawable;
+
+    return xwl_create_window_buffer_drm(xwl_window, pixmap, name);
+}
+
+static struct xwl_driver vmwgfx_xwl_driver = {
+    .version = 2,
+    .use_drm = 1,
+    .create_window_buffer = vmwgfx_create_window_buffer
+};
+
+static struct vmwgfx_hosted *
+vmwgfx_xwl_create(ScrnInfoPtr pScrn)
+{
+    struct vmwgfx_hosted *hosted;
+
+    hosted = calloc(1, sizeof(*hosted));
+    if (!hosted)
+	return NULL;
+
+    hosted->xwl = xwl_screen_create();
+    if (!hosted->xwl) {
+	free(hosted);
+	return NULL;
+    }
+
+    hosted->pScrn = pScrn;
+    return hosted;
+}
+
+static void
+vmwgfx_xwl_destroy(struct vmwgfx_hosted *hosted)
+{
+    xwl_screen_destroy(hosted->xwl);
+    free(hosted);
+}
+
+static Bool
+vmwgfx_xwl_pre_init(struct vmwgfx_hosted *hosted, int flags)
+{
+    return xwl_screen_pre_init(hosted->pScrn, hosted->xwl, 0,
+			       &vmwgfx_xwl_driver);
+}
+
+static int
+vmwgfx_xwl_drm_fd(struct vmwgfx_hosted *hosted, const struct pci_device *pci)
+{
+    return xwl_screen_get_drm_fd(hosted->xwl);
+}
+
+static Bool
+vmwgfx_xwl_screen_init(struct vmwgfx_hosted *hosted, ScreenPtr pScreen)
+{
+    if (xwl_screen_init(hosted->xwl, pScreen))
+	return FALSE;
+
+    hosted->pScreen = pScreen;
+
+    return TRUE;
+}
+
+static void
+vmwgfx_xwl_screen_close(struct vmwgfx_hosted *hosted)
+{
+    if (hosted->pScreen)
+	xwl_screen_close(hosted->xwl);
+
+    hosted->pScreen = NULL;
+}
+
+static void
+vmwgfx_xwl_post_damage(struct vmwgfx_hosted *hosted)
+{
+    vmwgfx_flush_dri2(hosted->pScreen);
+    xwl_screen_post_damage(hosted->xwl);
+}
+
+static int
+vmwgfx_xwl_dri_auth(struct vmwgfx_hosted *hosted, ClientPtr client,
+		    uint32_t magic)
+{
+    return xwl_drm_authenticate(client, hosted->xwl, magic);
+}
+
+static const struct vmwgfx_hosted_driver vmwgfx_hosted_xwl_driver = {
+    .create = vmwgfx_xwl_create,
+    .destroy = vmwgfx_xwl_destroy,
+    .drm_fd = vmwgfx_xwl_drm_fd,
+    .pre_init = vmwgfx_xwl_pre_init,
+    .screen_init = vmwgfx_xwl_screen_init,
+    .screen_close = vmwgfx_xwl_screen_close,
+    .post_damage = vmwgfx_xwl_post_damage,
+    .dri_auth = vmwgfx_xwl_dri_auth
+};
+
+const struct vmwgfx_hosted_driver *
+vmwgfx_xwl_detect(void)
+{
+    return (xorgWayland) ? &vmwgfx_hosted_xwl_driver : NULL;
+}
+
+void
+vmwgfx_xwl_modify_flags(uint32_t *flags)
+{
+    if (xorgWayland)
+	*flags |= HW_SKIP_CONSOLE | HW_WAYLAND;
+}
+
+#else
+
+const struct vmwgfx_hosted_driver *
+vmwgfx_xwl_detect(void)
+{
+    return NULL;
+}
+
+void
+vmwgfx_xwl_modify_flags(uint32_t *flags)
+{
+}
+#endif

commit c020923597d3bc30dffa89ba0a47f3b9517dd5fb
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date:   Mon Dec 16 06:13:25 2013 -0800

    vmwgfx: Add support for XMir v2.
    
    Use the hosted infrastructure to add support for XMir.
    Helpers go in vmwgfx_saa.c.
    
    v2: Added comments for the helpers, and added a
    vmwgfx_flush_dri2 to be executed when coming back from vt switch.
    
    Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
    Reviewed-by: Brian Paul <brianp@vmware.com>
    Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>

diff --git a/vmwgfx/Makefile.am b/vmwgfx/Makefile.am
index 2b0380b..41833a1 100644
--- a/vmwgfx/Makefile.am
+++ b/vmwgfx/Makefile.am
@@ -28,5 +28,6 @@ libvmwgfx_la_SOURCES = \
 	vmwgfx_hosted.c \
 	vmwgfx_hosted.h \
 	vmwgfx_hosted_priv.h \
+	vmwgfx_xmir.c \
 	wsbm_util.h
 endif
diff --git a/vmwgfx/vmwgfx_drmi.c b/vmwgfx/vmwgfx_drmi.c
index 496a16b..d926019 100644
--- a/vmwgfx/vmwgfx_drmi.c
+++ b/vmwgfx/vmwgfx_drmi.c
@@ -284,7 +284,7 @@ vmwgfx_dmabuf_destroy(struct vmwgfx_dmabuf *buf)
 }
 
 int
-vmwgfx_dma(unsigned int host_x, unsigned int host_y,
+vmwgfx_dma(int host_x, int host_y,
 	   RegionPtr region, struct vmwgfx_dmabuf *buf,
 	   uint32_t buf_pitch, uint32_t surface_handle, int to_surface)
 {
@@ -500,3 +500,40 @@ vmwgfx_max_fb_size(int drm_fd, size_t *size)
 
     return 0;
 }
+
+/**
+ * vmwgfx_prime_fd_to_handle - Return a TTM handle to a prime object
+ *
+ * @drm_fd: File descriptor for the drm connection.
+ * @prime_fd: File descriptor identifying the prime object.
+ * @handle: Pointer to returned TTM handle.
+ *
+ * Takes a reference on the underlying object and returns a TTM handle to it.
+ */
+int
+vmwgfx_prime_fd_to_handle(int drm_fd, int prime_fd, uint32_t *handle)
+{
+    *handle = 0;
+
+    return drmPrimeFDToHandle(drm_fd, prime_fd, handle);
+}
+
+/**
+ * vmwgfx_prime_release_handle - Release a reference on a TTM object
+ *
+ * @drm_fd: File descriptor for the drm connection.
+ * @handle: TTM handle as returned by vmwgfx_prime_fd_to_handle.
+ *
+ * Releases the reference obtained by vmwgfx_prime_fd_to_handle().
+ */
+void
+vmwgfx_prime_release_handle(int drm_fd, uint32_t handle)
+{
+    struct drm_vmw_surface_arg s_arg;
+
+    memset(&s_arg, 0, sizeof(s_arg));
+    s_arg.sid = handle;
+
+    (void) drmCommandWrite(drm_fd, DRM_VMW_UNREF_SURFACE, &s_arg,
+			   sizeof(s_arg));
+}
diff --git a/vmwgfx/vmwgfx_drmi.h b/vmwgfx/vmwgfx_drmi.h
index 2435009..1494485 100644
--- a/vmwgfx/vmwgfx_drmi.h
+++ b/vmwgfx/vmwgfx_drmi.h
@@ -60,7 +60,7 @@ extern void
 vmwgfx_dmabuf_unmap(struct vmwgfx_dmabuf *buf);
 
 extern int
-vmwgfx_dma(unsigned int host_x, unsigned int host_y,
+vmwgfx_dma(int host_x, int host_y,
 	   RegionPtr region, struct vmwgfx_dmabuf *buf,
 	   uint32_t buf_pitch, uint32_t surface_handle, int to_surface);
 
@@ -84,4 +84,10 @@ vmwgfx_update_gui_layout(int drm_fd, unsigned int num_rects,
 			 struct drm_vmw_rect *rects);
 int
 vmwgfx_get_param(int drm_fd, uint32_t param, uint64_t *out);
+
+int
+vmwgfx_prime_fd_to_handle(int drm_fd, int prime_fd, uint32_t *handle);
+
+void
+vmwgfx_prime_release_handle(int drm_fd, uint32_t handle);
 #endif
diff --git a/vmwgfx/vmwgfx_hosted.c b/vmwgfx/vmwgfx_hosted.c
index b42d962..018b88b 100644
--- a/vmwgfx/vmwgfx_hosted.c
+++ b/vmwgfx/vmwgfx_hosted.c
@@ -46,7 +46,9 @@
 const struct vmwgfx_hosted_driver *
 vmwgfx_hosted_detect(void)
 {
-    return NULL;
+    const struct vmwgfx_hosted_driver *tmp = vmwgfx_xmir_detect();
+
+    return tmp;
 }
 
 /**
@@ -61,4 +63,5 @@ vmwgfx_hosted_detect(void)
 void
 vmwgfx_hosted_modify_flags(uint32_t *flags)
 {
+    vmwgfx_xmir_modify_flags(flags);
 }
diff --git a/vmwgfx/vmwgfx_hosted.h b/vmwgfx/vmwgfx_hosted.h
index 8f3b243..78dc7cd 100644
--- a/vmwgfx/vmwgfx_hosted.h
+++ b/vmwgfx/vmwgfx_hosted.h
@@ -23,6 +23,7 @@
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ * Note: "Hosted" is a term stolen from the xf86-video-intel driver.
  */
 
 #ifndef _VMWGFX_HOSTED_H
diff --git a/vmwgfx/vmwgfx_hosted_priv.h b/vmwgfx/vmwgfx_hosted_priv.h
index 05ded25..c81f5ee 100644
--- a/vmwgfx/vmwgfx_hosted_priv.h
+++ b/vmwgfx/vmwgfx_hosted_priv.h
@@ -31,4 +31,7 @@
 #include <stdint.h>
 #include "vmwgfx_hosted.h"
 
+extern const struct vmwgfx_hosted_driver *vmwgfx_xmir_detect(void);
+extern void vmwgfx_xmir_modify_flags(uint32_t *flags);
+
 #endif
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index e76bd09..c8b4df1 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -282,32 +282,44 @@ static Bool
 vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
 	       PixmapPtr pixmap,
 	       RegionPtr reg,
-	       Bool to_hw)
+	       Bool to_hw,
+	       int dx,
+	       int dy,
+	       struct xa_surface *srf)
 {
     struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
 
-    if (!vpix->hw || (!vpix->gmr && !vpix->malloc))
+    if (!srf)
+	srf = vpix->hw;
+
+    if (!srf || (!vpix->gmr && !vpix->malloc))
 	return TRUE;
 
     if (vpix->gmr && vsaa->can_optimize_dma) {
 	uint32_t handle, dummy;
 
-	if (_xa_surface_handle(vpix->hw, &handle, &dummy) != 0)
+	if (_xa_surface_handle(srf, &handle, &dummy) != 0)
 	    goto out_err;
-	if (vmwgfx_dma(0, 0, reg, vpix->gmr, pixmap->devKind, handle,
+	if (vmwgfx_dma(dx, dy, reg, vpix->gmr, pixmap->devKind, handle,
 		       to_hw) != 0)
 	    goto out_err;
     } else {
-	void *data = vpix->malloc;
+	uint8_t *data = (uint8_t *) vpix->malloc;
 	int ret;
 
 	if (vpix->gmr) {
-	    data = vmwgfx_dmabuf_map(vpix->gmr);
+	    data = (uint8_t *) vmwgfx_dmabuf_map(vpix->gmr);
 	    if (!data)
 		goto out_err;
 	}
 
-	ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
+	if (dx || dy) {
+	    REGION_TRANSLATE(pScreen, reg, dx, dy);
+	    data -= ((dx * pixmap->drawable.bitsPerPixel + 7)/8 +
+		     dy * pixmap->devKind);
+	}
+
+	ret = xa_surface_dma(vsaa->xa_ctx, srf, data, pixmap->devKind,
 			     (int) to_hw,
 			     (struct xa_box *) REGION_RECTS(reg),
 			     REGION_NUM_RECTS(reg));
@@ -315,6 +327,8 @@ vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
 	    xa_context_flush(vsaa->xa_ctx);
 	if (vpix->gmr)
 	    vmwgfx_dmabuf_unmap(vpix->gmr);
+	if (dx || dy)
+	    REGION_TRANSLATE(pScreen, reg, -dx, -dy);
 	if (ret)
 	    goto out_err;
     }
@@ -353,7 +367,7 @@ vmwgfx_download_from_hw(struct saa_driver *driver, PixmapPtr pixmap,
     if (!vmwgfx_pixmap_create_sw(vsaa, pixmap))
 	goto out_err;
 
-    if (!vmwgfx_saa_dma(vsaa, pixmap, readback, FALSE))
+    if (!vmwgfx_saa_dma(vsaa, pixmap, readback, FALSE, 0, 0, NULL))
 	goto out_err;
     REGION_SUBTRACT(vsaa->pScreen, &spix->dirty_hw, &spix->dirty_hw, readback);
     REGION_UNINIT(vsaa->pScreen, &intersection);
@@ -368,7 +382,8 @@ static Bool
 vmwgfx_upload_to_hw(struct saa_driver *driver, PixmapPtr pixmap,
 		    RegionPtr upload)
 {
-    return vmwgfx_saa_dma(to_vmwgfx_saa(driver), pixmap, upload, TRUE);
+    return vmwgfx_saa_dma(to_vmwgfx_saa(driver), pixmap, upload, TRUE,
+			  0, 0, NULL);
 }
 
 static void
@@ -753,6 +768,33 @@ vmwgfx_check_hw_contents(struct vmwgfx_saa *vsaa,
     REGION_UNINIT(vsaa->pScreen, &intersection);
 }
 
+/**
+ * vmwgfx_prefer_gmr: Prefer a dma buffer over malloced memory for software
+ * rendered storage
+ *
+ * @vsaa: Pointer to a struct vmwgfx_saa accelerator.
+ * @pixmap: Pointer to pixmap whose storage preference we want to alter.
+ *
+ * If possible, alter the storage or future storage of the software contents
+ * of this pixmap to be in a DMA buffer rather than in malloced memory.
+ * This function should be called when it's likely that frequent DMA operations
+ * will occur between a surface and the memory holding the software
+ * contents.
+ */
+static void
+vmwgfx_prefer_gmr(struct vmwgfx_saa *vsaa, PixmapPtr pixmap)
+{
+    struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
+
+    if (vsaa->can_optimize_dma) {
+	if (vpix->malloc) {
+	    (void) vmwgfx_pixmap_create_gmr(vsaa, pixmap);
+	} else if (vpix->backing & VMWGFX_PIX_MALLOC) {
+	    vpix->backing |= VMWGFX_PIX_GMR;
+	    vpix->backing &= ~VMWGFX_PIX_MALLOC;
+	}
+    }
+}
 
 Bool
 vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
@@ -786,15 +828,16 @@ vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
     if (!vmwgfx_pixmap_add_damage(pixmap))
 	goto out_no_damage;
 
-    /*
-     * Even if we don't have a GMR yet, indicate that when needed it
-     * should be created.
-     */
-
     vpix->hw = hw;
     vpix->backing |= VMWGFX_PIX_SURFACE;
     vmwgfx_pixmap_free_storage(vpix);
 
+    /*
+     * If there is a HW surface, make sure that the shadow is
+     * (or will be) a GMR, provided we can do fast DMAs from / to it.
+     */
+    vmwgfx_prefer_gmr(vsaa, pixmap);
+
     return TRUE;
 
 out_no_damage:
@@ -1226,10 +1269,14 @@ vmwgfx_operation_complete(struct saa_driver *driver,
      * executed at glxWaitX(). Currently glxWaitX() is broken, so
      * we flush immediately, unless we're VT-switched away, in which
      * case a flush would deadlock in the kernel.
+     *
+     * For pixmaps for which vpix->hw_is_hosted is true, we can explicitly
+     * inform the compositor when contents has changed, so for those pixmaps
+     * we defer the upload until the compositor is informed, by putting
+     * them on the sync_x_list. Note that hw_is_dri2_fronts take precedence.
      */
-
-    if (vpix->hw && vpix->hw_is_dri2_fronts) {
-	if (pScrn->vtSema &&
+    if (vpix->hw && (vpix->hw_is_dri2_fronts || vpix->hw_is_hosted)) {
+	if (pScrn->vtSema && vpix->hw_is_dri2_fronts &&
 	    vmwgfx_upload_to_hw(driver, pixmap, &spix->dirty_shadow)) {
 
 	    REGION_EMPTY(vsaa->pScreen, &spix->dirty_shadow);
@@ -1539,6 +1586,7 @@ vmwgfx_saa_set_master(ScreenPtr pScreen)
     struct vmwgfx_saa *vsaa = to_vmwgfx_saa(saa_get_driver(pScreen));
 
     vsaa->is_master = TRUE;
+    vmwgfx_flush_dri2(pScreen);
 }
 
 void
@@ -1563,3 +1611,134 @@ vmwgfx_saa_drop_master(ScreenPtr pScreen)
 
     vsaa->is_master = FALSE;
 }
+
+/*
+ * *************************************************************************
+ * Helpers for hosted.
+ */
+
+#if (XA_TRACKER_VERSION_MAJOR >= 2)
+
+/**
+ * vmwgfx_saa_copy_to_surface - Copy Drawable contents to an external surface.
+ *
+ * @pDraw: Pointer to source drawable.
+ * @surface_fd: Prime file descriptor of external surface to copy to.
+ * @dst_box: BoxRec describing the destination bounding box.
+ * @region: Region of drawable to copy. Note: The code assumes that the
+ * region is relative to the drawable origin, not the underlying pixmap
+ * origin.
+ *
+ * Copies the contents (both software- and accelerated contents) to an
+ * external surface.
+ */
+Bool
+vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
+			   const BoxRec *dst_box, RegionPtr region)
+{
+    ScreenPtr pScreen = pDraw->pScreen;
+    struct vmwgfx_saa *vsaa = to_vmwgfx_saa(saa_get_driver(pScreen));
+    PixmapPtr src;
+    struct saa_pixmap *spix;
+    struct vmwgfx_saa_pixmap *vpix;
+    const BoxRec *box;
+    int n;
+    int sx, sy, dx, dy;
+    struct xa_surface *dst;
+    uint32_t handle;
+    Bool ret = TRUE;
+    RegionRec intersection;
+    RegionPtr copy_region = region;
+
+    if (vmwgfx_prime_fd_to_handle(vsaa->drm_fd, surface_fd, &handle) < 0)
+	return FALSE;


Reply to: