From 0945bea5fc32eacb7bf42639efbd45dcd43e7ab5 Mon Sep 17 00:00:00 2001
From: Rob Clark <robdclark@gmail.com>
Date: Mon, 10 Jun 2013 13:31:31 -0400
Subject: [PATCH 01/11] vmwgfx: update for XA API changes

Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
Tested-by: Jakob Bornecrantz <jakob@vmware.com>
---
 configure.ac              |  2 +-
 vmwgfx/vmwgfx_dri2.c      |  5 +++--
 vmwgfx/vmwgfx_driver.c    |  3 ++-
 vmwgfx/vmwgfx_saa.c       | 20 ++++++++++++++------
 vmwgfx/vmwgfx_tex_video.c |  5 +++--
 5 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index 0631bcc..dccfb27 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,7 +118,7 @@ if test x$BUILD_VMWGFX = xyes; then
 	PKG_CHECK_MODULES([LIBDRM], [libdrm],[],[BUILD_VMWGFX=no])
 fi
 if test x$BUILD_VMWGFX = xyes; then
-	PKG_CHECK_MODULES([XATRACKER], [xatracker >= 0.4.0],[],[BUILD_VMWGFX=no])
+	PKG_CHECK_MODULES([XATRACKER], [xatracker >= 2.0.0],[],[BUILD_VMWGFX=no])
 fi
 
 DRIVER_NAME=vmware
diff --git a/vmwgfx/vmwgfx_dri2.c b/vmwgfx/vmwgfx_dri2.c
index 7de0772..2f007f0 100644
--- a/vmwgfx/vmwgfx_dri2.c
+++ b/vmwgfx/vmwgfx_dri2.c
@@ -201,7 +201,8 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer, unsigned int for
     }
 
     private->srf = srf;
-    if (xa_surface_handle(srf, &buffer->name, &buffer->pitch) != 0)
+    if (xa_surface_handle(srf, xa_handle_type_shared,
+	    &buffer->name, &buffer->pitch) != 0)
 	return FALSE;
 
     buffer->cpp = xa_format_depth(xa_surface_format(srf)) / 8;
@@ -222,7 +223,7 @@ dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
     struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(private->pPixmap);
 
     if (--private->refcount == 0 && srf) {
-	xa_surface_destroy(srf);
+	xa_surface_unref(srf);
     }
 
     /*
diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index 7863ba2..3002285 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -617,7 +617,8 @@ vmwgfx_scanout_present(ScreenPtr pScreen, int drm_fd,
 	return FALSE;
     }
 
-    if (xa_surface_handle(vpix->hw, &handle, &dummy) != 0) {
+    if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
+	    &handle, &dummy) != 0) {
 	LogMessage(X_ERROR, "Could not get present surface handle.\n");
 	return FALSE;
     }
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 63df3a1..ed3c1ee 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -140,7 +140,7 @@ vmwgfx_pixmap_free_storage(struct vmwgfx_saa_pixmap *vpix)
 	vpix->malloc = NULL;
     }
     if (!(vpix->backing & VMWGFX_PIX_SURFACE) && vpix->hw) {
-	xa_surface_destroy(vpix->hw);
+	xa_surface_unref(vpix->hw);
 	vpix->hw = NULL;
     }
     if (!(vpix->backing & VMWGFX_PIX_GMR) && vpix->gmr) {
@@ -286,7 +286,8 @@ vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
     if (vpix->gmr && vsaa->can_optimize_dma) {
 	uint32_t handle, dummy;
 
-	if (xa_surface_handle(vpix->hw, &handle, &dummy) != 0)
+	if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
+		 &handle, &dummy) != 0)
 	    goto out_err;
 	if (vmwgfx_dma(0, 0, reg, vpix->gmr, pixmap->devKind, handle,
 		       to_hw) != 0)
@@ -305,6 +306,8 @@ vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
 			     (int) to_hw,
 			     (struct xa_box *) REGION_RECTS(reg),
 			     REGION_NUM_RECTS(reg));
+	if (to_hw)
+	    xa_context_flush(vsaa->xa_ctx);
 	if (vpix->gmr)
 	    vmwgfx_dmabuf_unmap(vpix->gmr);
 	if (ret)
@@ -441,7 +444,7 @@ vmwgfx_hw_kill(struct vmwgfx_saa *vsaa,
 				 &spix->dirty_hw))
 	return FALSE;
 
-    xa_surface_destroy(vpix->hw);
+    xa_surface_unref(vpix->hw);
     vpix->hw = NULL;
 
     /*
@@ -683,7 +686,8 @@ vmwgfx_present_prepare(struct vmwgfx_saa *vsaa,
 
     (void) pScreen;
     if (src_vpix == dst_vpix || !src_vpix->hw ||
-	xa_surface_handle(src_vpix->hw, &vsaa->src_handle, &dummy) != 0)
+	xa_surface_handle(src_vpix->hw, xa_handle_type_shared,
+		&vsaa->src_handle, &dummy) != 0)
 	return FALSE;
 
     REGION_NULL(pScreen, &vsaa->present_region);
@@ -784,7 +788,7 @@ vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
     return TRUE;
 
 out_no_damage:
-    xa_surface_destroy(hw);
+    xa_surface_unref(hw);
     return FALSE;
 }
 
@@ -929,6 +933,7 @@ vmwgfx_copy_prepare(struct saa_driver *driver,
 
 	if (!vmwgfx_hw_validate(src_pixmap, src_reg)) {
 	    xa_copy_done(vsaa->xa_ctx);
+	    xa_context_flush(vsaa->xa_ctx);
 	    return FALSE;
 	}
 
@@ -1029,6 +1034,7 @@ vmwgfx_copy_done(struct saa_driver *driver)
 	return;
     }
     xa_copy_done(vsaa->xa_ctx);
+    xa_context_flush(vsaa->xa_ctx);
 }
 
 static Bool
@@ -1175,6 +1181,7 @@ vmwgfx_composite_done(struct saa_driver *driver)
    struct vmwgfx_saa *vsaa = to_vmwgfx_saa(driver);
 
    xa_composite_done(vsaa->xa_ctx);
+   xa_context_flush(vsaa->xa_ctx);
 }
 
 static void
@@ -1436,7 +1443,8 @@ vmwgfx_scanout_ref(struct vmwgfx_screen_entry  *entry)
 	     */
 	    if (!vmwgfx_hw_accel_validate(pixmap, 0, XA_FLAG_SCANOUT, 0, NULL))
 		goto out_err;
-	    if (xa_surface_handle(vpix->hw, &handle, &dummy) != 0)
+	    if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
+			 &handle, &dummy) != 0)
 		goto out_err;
 	    depth = xa_format_depth(xa_surface_format(vpix->hw));
 
diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index 449266b..2971ed7 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -199,7 +199,7 @@ stop_video(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 
        for (i=0; i<3; ++i) {
 	   if (priv->yuv[i]) {
-	       xa_surface_destroy(priv->yuv[i]);
+	       xa_surface_unref(priv->yuv[i]);
 	       priv->yuv[i] = NULL;
 	   }
 	   for (j=0; j<2; ++j) {
@@ -539,7 +539,8 @@ copy_packed_data(ScrnInfoPtr pScrn,
 	       REGION_RESET(pScrn->pScreen, &reg, &box);
 	   }
 
-	   if (xa_surface_handle(srf, &handle, &stride) != 0) {
+	   if (xa_surface_handle(srf, xa_handle_type_shared,
+			&handle, &stride) != 0) {
 	       ret = BadAlloc;
 	       break;
 	   }
-- 
1.8.5.1


From 835ce4698f916ba080f4132988fd4caf898e0b1e Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Thu, 26 Sep 2013 01:25:33 -0700
Subject: [PATCH 02/11] vmwgfx: Avoid HW operations when not master

Note that for DRI2, a dri2_copy_region becomes a NOP when not master.
Additionally, all dri2 operations that lead to a potential kernel
access will return FALSE.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
---
 vmwgfx/vmwgfx_dri2.c       | 13 +++++++++++++
 vmwgfx/vmwgfx_driver.c     |  3 +++
 vmwgfx/vmwgfx_saa.c        | 44 +++++++++++++++++++++++++++++++++++++++++++-
 vmwgfx/vmwgfx_saa.h        |  8 ++++++++
 vmwgfx/vmwgfx_saa_priv.h   |  2 ++
 vmwgfx/vmwgfx_xa_surface.c |  6 ++++++
 6 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/vmwgfx/vmwgfx_dri2.c b/vmwgfx/vmwgfx_dri2.c
index 2f007f0..57f2d9d 100644
--- a/vmwgfx/vmwgfx_dri2.c
+++ b/vmwgfx/vmwgfx_dri2.c
@@ -138,6 +138,8 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer, unsigned int for
       return TRUE;
     case DRI2BufferStencil:
     case DRI2BufferDepthStencil:
+	if (!pScrn->vtSema)
+	    return FALSE;
 
 	depth = (format) ? vmwgfx_zs_format_to_depth(format) : 32;
 
@@ -155,6 +157,9 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer, unsigned int for
 
        break;
     case DRI2BufferDepth:
+	if (!pScrn->vtSema)
+	    return FALSE;
+
 	depth = (format) ? vmwgfx_z_format_to_depth(format) :
 	    pDraw->bitsPerPixel;
 
@@ -291,6 +296,14 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
     DrawablePtr dst_draw;
     RegionPtr myClip;
     GCPtr gc;
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+
+    /*
+     * This is a fragile protection against HW operations when not master.
+     * Needs to be blocked higher up in the dri2 code.
+     */
+    if (!pScrn->vtSema)
+	return;
 
     /*
      * In driCreateBuffers we dewrap windows into the
diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index 3002285..eeaea4b 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -1116,6 +1116,7 @@ drv_leave_vt(VT_FUNC_ARGS_DECL)
 
     vmwgfx_cursor_bypass(ms->fd, 0, 0);
     vmwgfx_disable_scanout(pScrn);
+    vmwgfx_saa_drop_master(pScrn->pScreen);
 
     if (drmDropMaster(ms->fd))
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1136,6 +1137,8 @@ drv_enter_vt(VT_FUNC_ARGS_DECL)
     if (!drv_set_master(pScrn))
 	return FALSE;
 
+    vmwgfx_saa_set_master(pScrn->pScreen);
+
     if (!xf86SetDesiredModes(pScrn))
 	return FALSE;
 
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index ed3c1ee..5534ca3 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -423,6 +423,7 @@ vmwgfx_create_pixmap(struct saa_driver *driver, struct saa_pixmap *spix,
 
     WSBMINITLISTHEAD(&vpix->sync_x_head);
     WSBMINITLISTHEAD(&vpix->scanout_list);
+    WSBMINITLISTHEAD(&vpix->pixmap_list);
 
     return TRUE;
 }
@@ -499,6 +500,7 @@ vmwgfx_destroy_pixmap(struct saa_driver *driver, PixmapPtr pixmap)
      */
 
     vmwgfx_pixmap_remove_present(vpix);
+    WSBMLISTDELINIT(&vpix->pixmap_list);
     WSBMLISTDELINIT(&vpix->sync_x_head);
 
     if (vpix->hw_is_dri2_fronts)
@@ -627,6 +629,8 @@ vmwgfx_modify_pixmap_header (PixmapPtr pixmap, int w, int h, int depth,
 			     int bpp, int devkind, void *pixdata)
 {
     struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
+    ScreenPtr pScreen = pixmap->drawable.pScreen;
+    struct vmwgfx_saa *vsaa = to_vmwgfx_saa(saa_get_driver(pScreen));
     unsigned int old_height;
     unsigned int old_width;
     unsigned int old_pitch;
@@ -670,6 +674,8 @@ vmwgfx_modify_pixmap_header (PixmapPtr pixmap, int w, int h, int depth,
 
     vmwgfx_pix_resize(pixmap, old_pitch, old_height, old_width);
     vmwgfx_pixmap_free_storage(vpix);
+    WSBMLISTADDTAIL(&vpix->pixmap_list, &vsaa->pixmaps);
+
     return TRUE;
 
   out_no_modify:
@@ -860,7 +866,7 @@ vmwgfx_copy_prepare(struct saa_driver *driver,
     Bool has_valid_hw;
 
     if (!vsaa->xat || !SAA_PM_IS_SOLID(&dst_pixmap->drawable, plane_mask) ||
-	alu != GXcopy)
+	alu != GXcopy || !vsaa->is_master)
 	return FALSE;
 
     src_vpix = vmwgfx_saa_pixmap(src_pixmap);
@@ -1057,6 +1063,9 @@ vmwgfx_composite_prepare(struct saa_driver *driver, CARD8 op,
     RegionRec empty;
     struct xa_composite *xa_comp;
 
+    if (!vsaa->is_master)
+	return FALSE;
+
     REGION_NULL(pScreen, &empty);
 
     /*
@@ -1367,7 +1376,9 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
     vsaa->use_present_opt = direct_presents;
     vsaa->only_hw_presents = only_hw_presents;
     vsaa->rendercheck = rendercheck;
+    vsaa->is_master = TRUE;
     WSBMINITLISTHEAD(&vsaa->sync_x_list);
+    WSBMINITLISTHEAD(&vsaa->pixmaps);
 
     vsaa->driver = vmwgfx_saa_driver;
     vsaa->vcomp = vmwgfx_alloc_composite();
@@ -1518,3 +1529,34 @@ vmwgfx_scanout_unref(struct vmwgfx_screen_entry *entry)
     entry->pixmap = NULL;
     pixmap->drawable.pScreen->DestroyPixmap(pixmap);
 }
+
+void
+vmwgfx_saa_set_master(ScreenPtr pScreen)
+{
+    struct vmwgfx_saa *vsaa = to_vmwgfx_saa(saa_get_driver(pScreen));
+
+    vsaa->is_master = TRUE;
+}
+
+void
+vmwgfx_saa_drop_master(ScreenPtr pScreen)
+{
+    struct vmwgfx_saa *vsaa = to_vmwgfx_saa(saa_get_driver(pScreen));
+    struct _WsbmListHead *list;
+    struct vmwgfx_saa_pixmap *vpix;
+    struct saa_pixmap *spix;
+
+    WSBMLISTFOREACH(list, &vsaa->pixmaps) {
+	vpix = WSBMLISTENTRY(list, struct vmwgfx_saa_pixmap, pixmap_list);
+	spix = &vpix->base;
+
+	if (!vpix->hw)
+	    continue;
+
+	(void) vmwgfx_download_from_hw(&vsaa->driver, spix->pixmap,
+				       &spix->dirty_hw);
+	REGION_EMPTY(draw->pScreen, &spix->dirty_hw);
+    }
+
+    vsaa->is_master = FALSE;
+}
diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h
index bb8ec96..d8aa3d3 100644
--- a/vmwgfx/vmwgfx_saa.h
+++ b/vmwgfx/vmwgfx_saa.h
@@ -54,6 +54,7 @@ struct vmwgfx_saa_pixmap {
     int hw_is_dri2_fronts;
     struct _WsbmListHead sync_x_head;
     struct _WsbmListHead scanout_list;
+    struct _WsbmListHead pixmap_list;
 
     uint32_t xa_flags;
     uint32_t staging_add_flags;
@@ -107,4 +108,11 @@ Bool
 vmwgfx_hw_accel_validate(PixmapPtr pixmap, unsigned int depth,
 			 uint32_t add_flags, uint32_t remove_flags,
 			 RegionPtr region);
+
+void
+vmwgfx_saa_set_master(ScreenPtr pScreen);
+
+void
+vmwgfx_saa_drop_master(ScreenPtr pScreen);
+
 #endif
diff --git a/vmwgfx/vmwgfx_saa_priv.h b/vmwgfx/vmwgfx_saa_priv.h
index 5f46dee..16583b0 100644
--- a/vmwgfx/vmwgfx_saa_priv.h
+++ b/vmwgfx/vmwgfx_saa_priv.h
@@ -54,8 +54,10 @@ struct vmwgfx_saa {
     Bool use_present_opt;
     Bool only_hw_presents;
     Bool rendercheck;
+    Bool is_master;
     void (*present_flush) (ScreenPtr pScreen);
     struct _WsbmListHead sync_x_list;
+    struct _WsbmListHead pixmaps;
     struct vmwgfx_composite *vcomp;
 };
 
diff --git a/vmwgfx/vmwgfx_xa_surface.c b/vmwgfx/vmwgfx_xa_surface.c
index 8b30e45..2f23c57 100644
--- a/vmwgfx/vmwgfx_xa_surface.c
+++ b/vmwgfx/vmwgfx_xa_surface.c
@@ -362,6 +362,12 @@ vmwgfx_hw_accel_validate(PixmapPtr pixmap, unsigned int depth,
 Bool
 vmwgfx_hw_dri2_validate(PixmapPtr pixmap, unsigned int depth)
 {
+    struct vmwgfx_saa *vsaa =
+	to_vmwgfx_saa(saa_get_driver(pixmap->drawable.pScreen));
+
+    if (!vsaa->is_master)
+	    return FALSE;
+
     return (vmwgfx_hw_dri2_stage(pixmap, depth) &&
 	    vmwgfx_hw_commit(pixmap) &&
 	    vmwgfx_hw_validate(pixmap, NULL));
-- 
1.8.5.1


From 7192acf9f0bf8e7176ab0b803b861a858623f709 Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Wed, 19 Sep 2012 20:36:57 +0200
Subject: [PATCH 03/11] vmwgfx: Implement textured video completely on top of
 XA.

Remove device-specific hacks. This may increase resource usage a little
on old hardware revisions, but we don't need separate code paths on
different hardware revisions.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Zack Rusin <zackr@vmware.com>
---
 vmwgfx/vmwgfx_tex_video.c | 109 ++++++----------------------------------------
 1 file changed, 14 insertions(+), 95 deletions(-)

diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index 2971ed7..a0a4f4a 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -111,8 +111,7 @@ struct xorg_xv_port_priv {
     int hue;
 
     int current_set;
-    struct vmwgfx_dmabuf *bounce[2][3];
-    struct xa_surface *yuv[3];
+    struct xa_surface *yuv[2][3];
 
     int drm_fd;
 
@@ -198,14 +197,10 @@ stop_video(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
        priv->fence = NULL;
 
        for (i=0; i<3; ++i) {
-	   if (priv->yuv[i]) {
-	       xa_surface_unref(priv->yuv[i]);
-	       priv->yuv[i] = NULL;
-	   }
 	   for (j=0; j<2; ++j) {
-	       if (priv->bounce[j][i]) {
-		   vmwgfx_dmabuf_destroy(priv->bounce[j][i]);
-		   priv->bounce[0][i] = NULL;
+	       if (priv->yuv[i]) {
+		   xa_surface_unref(priv->yuv[j][i]);
+		   priv->yuv[j][i] = NULL;
 	       }
 	   }
        }
@@ -297,11 +292,9 @@ static int
 check_yuv_surfaces(struct xorg_xv_port_priv *priv,  int id,
 		   int width, int height)
 {
-    struct xa_surface **yuv = priv->yuv;
-    struct vmwgfx_dmabuf **bounce = priv->bounce[priv->current_set];
+    struct xa_surface **yuv = priv->yuv[priv->current_set];
     int ret = 0;
     int i;
-    size_t size;
 
     for (i=0; i<3; ++i) {
 
@@ -334,19 +327,6 @@ check_yuv_surfaces(struct xorg_xv_port_priv *priv,  int id,
 	if (ret || !yuv[i])
 	    return BadAlloc;
 
-	size = width * height;
-
-	if (bounce[i] && (bounce[i]->size < size ||
-			  bounce[i]->size > 2*size)) {
-	    vmwgfx_dmabuf_destroy(bounce[i]);
-	    bounce[i] = NULL;
-	}
-
-	if (!bounce[i]) {
-	    bounce[i] = vmwgfx_dmabuf_alloc(priv->drm_fd, size);
-	    if (!bounce[i])
-		return BadAlloc;
-	}
     }
     return Success;
 }
@@ -413,28 +393,20 @@ copy_packed_data(ScrnInfoPtr pScrn,
                  unsigned short w, unsigned short h)
 {
     int i;
-   struct vmwgfx_dmabuf **bounce = port->bounce[port->current_set];
+   struct xa_surface **yuv = port->yuv[port->current_set];
    char *ymap, *vmap, *umap;
    unsigned char y1, y2, u, v;
    int yidx, uidx, vidx;
    int y_array_size = w * h;
    int ret = BadAlloc;
 
-   /*
-    * Here, we could use xa_surface_[map|unmap], but given the size of
-    * the yuv textures, that could stress the xa tracker dma buffer pool,
-    * particularaly with multiple videos rendering simultaneously.
-    *
-    * Instead, cheat and allocate vmwgfx dma buffers directly.
-    */
-
-   ymap = (char *)vmwgfx_dmabuf_map(bounce[0]);
+   ymap = xa_surface_map(port->r, yuv[0], XA_MAP_WRITE);
    if (!ymap)
        return BadAlloc;
-   umap = (char *)vmwgfx_dmabuf_map(bounce[1]);
+   umap = xa_surface_map(port->r, yuv[1], XA_MAP_WRITE);
    if (!umap)
        goto out_no_umap;
-   vmap = (char *)vmwgfx_dmabuf_map(bounce[2]);
+   vmap = xa_surface_map(port->r, yuv[2], XA_MAP_WRITE);
    if (!vmap)
        goto out_no_vmap;
 
@@ -493,65 +465,11 @@ copy_packed_data(ScrnInfoPtr pScrn,
    }
 
    ret = Success;
-   vmwgfx_dmabuf_unmap(bounce[2]);
+   xa_surface_unmap(yuv[2]);
   out_no_vmap:
-   vmwgfx_dmabuf_unmap(bounce[1]);
+   xa_surface_unmap(yuv[1]);
   out_no_umap:
-   vmwgfx_dmabuf_unmap(bounce[0]);
-
-   if (ret == Success) {
-       struct xa_surface *srf;
-       struct vmwgfx_dmabuf *buf;
-       uint32_t handle;
-       unsigned int stride;
-       BoxRec box;
-       RegionRec reg;
-
-       box.x1 = 0;
-       box.x2 = w;
-       box.y1 = 0;
-       box.y2 = h;
-
-       REGION_INIT(pScrn->pScreen, &reg, &box, 1);
-
-       for (i=0; i<3; ++i) {
-	   srf = port->yuv[i];
-	   buf = bounce[i];
-
-	   if (i == 1) {
-	       switch(id) {
-	       case FOURCC_YV12:
-		   h /= 2;
-		   /* Fall through */
-	       case FOURCC_YUY2:
-	       case FOURCC_UYVY:
-		   w /= 2;
-		   break;
-	       default:
-		   break;
-	       }
-
-	       box.x1 = 0;
-	       box.x2 = w;
-	       box.y1 = 0;
-	       box.y2 = h;
-
-	       REGION_RESET(pScrn->pScreen, &reg, &box);
-	   }
-
-	   if (xa_surface_handle(srf, xa_handle_type_shared,
-			&handle, &stride) != 0) {
-	       ret = BadAlloc;
-	       break;
-	   }
-
-	   if (vmwgfx_dma(0, 0, &reg, buf, w, handle, 1) != 0) {
-	       ret = BadAlloc;
-	       break;
-	   }
-       }
-       REGION_UNINIT(pScrn->pScreen, &reg);
-   }
+   xa_surface_unmap(yuv[0]);
 
    return ret;
 }
@@ -610,7 +528,8 @@ display_video(ScreenPtr pScreen, struct xorg_xv_port_priv *pPriv, int id,
 				 (struct xa_box *)REGION_RECTS(dstRegion),
 				 REGION_NUM_RECTS(dstRegion),
 				 pPriv->cm,
-				 vpix->hw, pPriv->yuv);
+				 vpix->hw,
+				 pPriv->yuv[pPriv->current_set ]);
 
    saa_pixmap_dirty(pPixmap, TRUE, dstRegion);
    DamageRegionProcessPending(&pPixmap->drawable);
-- 
1.8.5.1


From 45b2457516a9db4bd1d60fbb24a1efbe2d9dd932 Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Wed, 19 Sep 2012 21:50:40 +0200
Subject: [PATCH 04/11] vmwgfx: Get rid of device-specific DMA code

It's rarely used and things seem to work well enough on top of XA.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Zack Rusin <zackr@vmware.com>
---
 vmwgfx/vmwgfx_drmi.c     | 103 -----------------------------------------------
 vmwgfx/vmwgfx_drmi.h     |   5 ---
 vmwgfx/vmwgfx_saa.c      |  53 ++++++++++++------------
 vmwgfx/vmwgfx_saa_priv.h |   1 -
 4 files changed, 26 insertions(+), 136 deletions(-)

diff --git a/vmwgfx/vmwgfx_drmi.c b/vmwgfx/vmwgfx_drmi.c
index 496a16b..1e23f4a 100644
--- a/vmwgfx/vmwgfx_drmi.c
+++ b/vmwgfx/vmwgfx_drmi.c
@@ -284,109 +284,6 @@ vmwgfx_dmabuf_destroy(struct vmwgfx_dmabuf *buf)
 }
 
 int
-vmwgfx_dma(unsigned int host_x, unsigned int host_y,
-	   RegionPtr region, struct vmwgfx_dmabuf *buf,
-	   uint32_t buf_pitch, uint32_t surface_handle, int to_surface)
-{
-    BoxPtr clips = REGION_RECTS(region);
-    unsigned int num_clips = REGION_NUM_RECTS(region);
-    struct drm_vmw_execbuf_arg arg;
-    struct drm_vmw_fence_rep rep;
-    int ret;
-    unsigned int size;
-    unsigned i;
-    SVGA3dCopyBox *cb;
-    SVGA3dCmdSurfaceDMASuffix *suffix;
-    SVGA3dCmdSurfaceDMA *body;
-    struct vmwgfx_int_dmabuf *ibuf = vmwgfx_int_dmabuf(buf);
-
-    struct {
-	SVGA3dCmdHeader header;
-	SVGA3dCmdSurfaceDMA body;
-	SVGA3dCopyBox cb;
-    } *cmd;
-
-    if (num_clips == 0)
-	return 0;
-
-    size = sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cb) +
-	sizeof(*suffix);
-    cmd = malloc(size);
-    if (!cmd)
-	return -1;
-
-    cmd->header.id = SVGA_3D_CMD_SURFACE_DMA;
-    cmd->header.size = sizeof(cmd->body) + num_clips * sizeof(cmd->cb) +
-	sizeof(*suffix);
-    cb = &cmd->cb;
-
-    suffix = (SVGA3dCmdSurfaceDMASuffix *) &cb[num_clips];
-    suffix->suffixSize = sizeof(*suffix);
-    suffix->maximumOffset = (uint32_t) -1;
-    suffix->flags.discard = 0;
-    suffix->flags.unsynchronized = 0;
-    suffix->flags.reserved = 0;
-
-    body = &cmd->body;
-    body->guest.ptr.gmrId = buf->gmr_id;
-    body->guest.ptr.offset = buf->gmr_offset;
-    body->guest.pitch = buf_pitch;
-    body->host.sid = surface_handle;
-    body->host.face = 0;
-    body->host.mipmap = 0;
-
-    body->transfer =  (to_surface ? SVGA3D_WRITE_HOST_VRAM :
-		       SVGA3D_READ_HOST_VRAM);
-
-
-    for (i=0; i < num_clips; i++, cb++, clips++) {
-	cb->x = (uint16_t) clips->x1 + host_x;
-	cb->y = (uint16_t) clips->y1 + host_y;
-	cb->z = 0;
-	cb->srcx = (uint16_t) clips->x1;
-	cb->srcy = (uint16_t) clips->y1;
-	cb->srcz = 0;
-	cb->w = (uint16_t) (clips->x2 - clips->x1);
-	cb->h = (uint16_t) (clips->y2 - clips->y1);
-	cb->d = 1;
-#if 0
-	LogMessage(X_INFO, "DMA! x: %u y: %u srcx: %u srcy: %u w: %u h: %u %s\n",
-		   cb->x, cb->y, cb->srcx, cb->srcy, cb->w, cb->h,
-		   to_surface ? "to" : "from");
-#endif
-
-    }
-
-    memset(&arg, 0, sizeof(arg));
-    memset(&rep, 0, sizeof(rep));
-
-    rep.error = -EFAULT;
-    arg.fence_rep = ((to_surface) ? 0UL : (unsigned long)&rep);
-    arg.commands = (unsigned long)cmd;
-    arg.command_size = size;
-    arg.throttle_us = 0;
-    arg.version = DRM_VMW_EXECBUF_VERSION;
-
-    ret = drmCommandWrite(ibuf->drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
-    if (ret) {
-	LogMessage(X_ERROR, "DMA error %s.\n", strerror(-ret));
-    }
-
-    free(cmd);
-
-    if (rep.error == 0) {
-	ret = vmwgfx_fence_wait(ibuf->drm_fd, rep.handle, TRUE);
-	if (ret) {
-	    LogMessage(X_ERROR, "DMA from host fence wait error %s.\n",
-		       strerror(-ret));
-	    vmwgfx_fence_unref(ibuf->drm_fd, rep.handle);
-	}
-    }
-
-    return 0;
-}
-
-int
 vmwgfx_get_param(int drm_fd, uint32_t param, uint64_t *out)
 {
     struct drm_vmw_getparam_arg gp_arg;
diff --git a/vmwgfx/vmwgfx_drmi.h b/vmwgfx/vmwgfx_drmi.h
index 2435009..fff728a 100644
--- a/vmwgfx/vmwgfx_drmi.h
+++ b/vmwgfx/vmwgfx_drmi.h
@@ -60,11 +60,6 @@ extern void
 vmwgfx_dmabuf_unmap(struct vmwgfx_dmabuf *buf);
 
 extern int
-vmwgfx_dma(unsigned int host_x, unsigned int host_y,
-	   RegionPtr region, struct vmwgfx_dmabuf *buf,
-	   uint32_t buf_pitch, uint32_t surface_handle, int to_surface);
-
-extern int
 vmwgfx_num_streams(int drm_fd, uint32_t *ntot, uint32_t *nfree);
 
 extern int
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 5534ca3..fd80682 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -279,40 +279,40 @@ vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
 	       Bool to_hw)
 {
     struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
+    void *data = vpix->malloc;
+    int ret;
 
     if (!vpix->hw || (!vpix->gmr && !vpix->malloc))
 	return TRUE;
 
-    if (vpix->gmr && vsaa->can_optimize_dma) {
-	uint32_t handle, dummy;
 
-	if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
-		 &handle, &dummy) != 0)
-	    goto out_err;
-	if (vmwgfx_dma(0, 0, reg, vpix->gmr, pixmap->devKind, handle,
-		       to_hw) != 0)
+    if (vpix->gmr) {
+	data = vmwgfx_dmabuf_map(vpix->gmr);
+	if (!data)
 	    goto out_err;
-    } else {
-	void *data = vpix->malloc;
-	int ret;
+    }
 
-	if (vpix->gmr) {
-	    data = vmwgfx_dmabuf_map(vpix->gmr);
-	    if (!data)
-		goto out_err;
-	}
+    ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
+			 (int) to_hw,
+			 (struct xa_box *) REGION_RECTS(reg),
+			 REGION_NUM_RECTS(reg));
+    if (vpix->gmr)
+	vmwgfx_dmabuf_unmap(vpix->gmr);
+
+    if (ret)
+	goto out_err;
+
+    ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
+			 (int) to_hw,
+			 (struct xa_box *) REGION_RECTS(reg),
+			 REGION_NUM_RECTS(reg));
+    if (to_hw)
+	xa_context_flush(vsaa->xa_ctx);
+    if (vpix->gmr)
+	vmwgfx_dmabuf_unmap(vpix->gmr);
+    if (ret)
+	goto out_err;
 
-	ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
-			     (int) to_hw,
-			     (struct xa_box *) REGION_RECTS(reg),
-			     REGION_NUM_RECTS(reg));
-	if (to_hw)
-	    xa_context_flush(vsaa->xa_ctx);
-	if (vpix->gmr)
-	    vmwgfx_dmabuf_unmap(vpix->gmr);
-	if (ret)
-	    goto out_err;
-    }
     return TRUE;
   out_err:
     LogMessage(X_ERROR, "DMA %s surface failed.\n",
@@ -1372,7 +1372,6 @@ 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->use_present_opt = direct_presents;
     vsaa->only_hw_presents = only_hw_presents;
     vsaa->rendercheck = rendercheck;
diff --git a/vmwgfx/vmwgfx_saa_priv.h b/vmwgfx/vmwgfx_saa_priv.h
index 16583b0..f5f45ba 100644
--- a/vmwgfx/vmwgfx_saa_priv.h
+++ b/vmwgfx/vmwgfx_saa_priv.h
@@ -50,7 +50,6 @@ struct vmwgfx_saa {
     int ydiff;
     RegionRec present_region;
     uint32_t src_handle;
-    Bool can_optimize_dma;
     Bool use_present_opt;
     Bool only_hw_presents;
     Bool rendercheck;
-- 
1.8.5.1


From e26dec8f5278df74a102493bf6d2d8444dab5d6d Mon Sep 17 00:00:00 2001
From: Gaetan Nadon <memsize@videotron.ca>
Date: Mon, 28 Oct 2013 18:21:29 -0400
Subject: [PATCH 05/11] vmwgfx: handle changes of DamageUnregister API in
 1.14.99.2

Fix is inspired from the intel driver.

Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
---
 vmwgfx/vmwgfx_saa.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index fd80682..346e7f4 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -26,6 +26,7 @@
  */
 
 #include <xorg-server.h>
+#include <xorgVersion.h>
 #include <mi.h>
 #include <fb.h>
 #include <xf86drmMode.h>
@@ -76,7 +77,12 @@ vmwgfx_pixmap_remove_damage(PixmapPtr pixmap)
     if (!spix->damage || vpix->hw || vpix->gmr || vpix->malloc)
 	return;
 
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0)
+    DamageUnregister(spix->damage);
+#else
     DamageUnregister(&pixmap->drawable, spix->damage);
+#endif
+
     DamageDestroy(spix->damage);
     spix->damage = NULL;
 }
-- 
1.8.5.1


From 7ac45326eccbf3bea9a4a8f95b9662a36ab58eb0 Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Thu, 28 Nov 2013 02:02:20 -0800
Subject: [PATCH 06/11] vmwgfx: Fix some compilation warnings and indentations

Most of the compilation warnings we're seeing are due to bad xorg headers,
but fix the ones we can fix in the driver. Some indentation fixes as well.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
---
 src/vmware_bootstrap.c    |  2 --
 src/vmwarevideo.c         |  4 ++--
 vmwgfx/vmwgfx_driver.c    |  1 -
 vmwgfx/vmwgfx_output.c    |  2 +-
 vmwgfx/vmwgfx_overlay.c   |  4 ++--
 vmwgfx/vmwgfx_tex_video.c | 26 +++++++++++++-------------
 6 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/src/vmware_bootstrap.c b/src/vmware_bootstrap.c
index ea5be19..bb58325 100644
--- a/src/vmware_bootstrap.c
+++ b/src/vmware_bootstrap.c
@@ -256,7 +256,6 @@ VMwarePciProbe (DriverPtr           drv,
                 intptr_t            match_data)
 {
     ScrnInfoPtr     scrn = NULL;
-    EntityInfoPtr   entity;
 
     scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets,
                                NULL, NULL, NULL, NULL, NULL);
@@ -267,7 +266,6 @@ VMwarePciProbe (DriverPtr           drv,
         scrn->Probe = NULL;
     }
 
-    entity = xf86GetEntityInfo(entity_num);
     switch (DEVICE_ID(device)) {
     case PCI_DEVICE_ID_VMWARE_SVGA2:
     case PCI_DEVICE_ID_VMWARE_SVGA:
diff --git a/src/vmwarevideo.c b/src/vmwarevideo.c
index 745c71f..8d7d171 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 XF86VideoEncodingRec vmwareVideoEncodings[] =
+static const XF86VideoEncodingRec vmwareVideoEncodings[] =
 {
     {
        0,
@@ -108,7 +108,7 @@ static XF86ImageRec vmwareVideoImages[] =
 };
 
 #define VMWARE_VID_NUM_ATTRIBUTES 2
-static XF86AttributeRec vmwareVideoAttributes[] =
+static const XF86AttributeRec vmwareVideoAttributes[] =
 {
     {
         XvGettable | XvSettable,
diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index eeaea4b..bfc07f8 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -658,7 +658,6 @@ void xorg_flush(ScreenPtr pScreen)
 	if (crtc->enabled) {
 	    pixmap = crtc_get_scanout(crtc);
 	    if (pixmap) {
-		unsigned int j;
 
 		/*
 		 * Remove duplicates.
diff --git a/vmwgfx/vmwgfx_output.c b/vmwgfx/vmwgfx_output.c
index 4f52f1d..f9e4263 100644
--- a/vmwgfx/vmwgfx_output.c
+++ b/vmwgfx/vmwgfx_output.c
@@ -60,7 +60,7 @@ struct output_private
     Bool is_implicit;
 };
 
-static char *output_enum_list[] = {
+static const char *output_enum_list[] = {
     "Unknown",
     "VGA",
     "DVI",
diff --git a/vmwgfx/vmwgfx_overlay.c b/vmwgfx/vmwgfx_overlay.c
index 6624a10..986dd06 100644
--- a/vmwgfx/vmwgfx_overlay.c
+++ b/vmwgfx/vmwgfx_overlay.c
@@ -84,7 +84,7 @@ typedef uint8_t uint8;
 #define VMWARE_VID_MAX_HEIGHT   2048
 
 #define VMWARE_VID_NUM_ENCODINGS 1
-static XF86VideoEncodingRec vmwareVideoEncodings[] =
+static const XF86VideoEncodingRec vmwareVideoEncodings[] =
 {
     {
        0,
@@ -110,7 +110,7 @@ static XF86ImageRec vmwareVideoImages[] =
 };
 
 #define VMWARE_VID_NUM_ATTRIBUTES 2
-static XF86AttributeRec vmwareVideoAttributes[] =
+static const XF86AttributeRec vmwareVideoAttributes[] =
 {
     {
         XvGettable | XvSettable,
diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index a0a4f4a..3ba40ef 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -70,11 +70,11 @@ static const float bt_709[] = {
 static Atom xvBrightness, xvContrast, xvSaturation, xvHue;
 
 #define NUM_TEXTURED_ATTRIBUTES 4
-static XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = {
-   {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
-   {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
-   {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
-   {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}
+static const XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = {
+    {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
+    {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
+    {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
+    {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}
 };
 
 #define NUM_FORMATS 3
@@ -82,7 +82,7 @@ static XF86VideoFormatRec Formats[NUM_FORMATS] = {
    {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 };
 
-static XF86VideoEncodingRec DummyEncoding[1] = {
+static const XF86VideoEncodingRec DummyEncoding[1] = {
    {
       0,
       "XV_IMAGE",
@@ -416,16 +416,16 @@ copy_packed_data(ScrnInfoPtr pScrn,
    switch (id) {
    case FOURCC_YV12: {
       int pitches[3], offsets[3];
-      unsigned char *y, *u, *v;
+      unsigned char *yp, *up, *vp;
       query_image_attributes(pScrn, FOURCC_YV12,
                              &w, &h, pitches, offsets);
 
-      y = buf + offsets[0];
-      v = buf + offsets[1];
-      u = buf + offsets[2];
-      memcpy(ymap, y, w*h);
-      memcpy(vmap, v, w*h/4);
-      memcpy(umap, u, w*h/4);
+      yp = buf + offsets[0];
+      vp = buf + offsets[1];
+      up = buf + offsets[2];
+      memcpy(ymap, yp, w*h);
+      memcpy(vmap, vp, w*h/4);
+      memcpy(umap, up, w*h/4);
       break;
    }
    case FOURCC_UYVY:
-- 
1.8.5.1


From a40cbd7b4fa19219849b4b0a48f07538772c3e22 Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Thu, 5 Dec 2013 02:58:47 -0800
Subject: [PATCH 07/11] vmwgfx: Support also XA version 1 v2

We need to support also XA version 1, since we want to be backwards
compatible with older mesa releases.
Unfortunately, the intended way of detecting XA major version at
compile-time was broken on mesa 10 so we need a workaround that tests
for XA version 2 at config time.

v2: Update the test for XA version 2.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
---
 configure.ac              | 10 +++++++++-
 vmwgfx/vmwgfx_dri2.c      |  5 ++---
 vmwgfx/vmwgfx_driver.c    |  3 +--
 vmwgfx/vmwgfx_saa.c       | 12 +++++-------
 vmwgfx/vmwgfx_saa.h       | 12 ++++++++++++
 vmwgfx/vmwgfx_tex_video.c |  2 +-
 6 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/configure.ac b/configure.ac
index dccfb27..123356c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,7 +118,15 @@ if test x$BUILD_VMWGFX = xyes; then
 	PKG_CHECK_MODULES([LIBDRM], [libdrm],[],[BUILD_VMWGFX=no])
 fi
 if test x$BUILD_VMWGFX = xyes; then
-	PKG_CHECK_MODULES([XATRACKER], [xatracker >= 2.0.0],[],[BUILD_VMWGFX=no])
+#
+# Early versions of mesa 10 forgot to bump the XA major version number in
+# the xa_tracker.h header
+#
+	PKG_CHECK_MODULES([XATRACKER], [xatracker >= 0.4.0],
+			  [PKG_CHECK_EXISTS([xatracker = 2.0.0],
+	                  [AC_DEFINE([HAVE_XA_2], 1,
+               		  [Has version 2 of XA])])],
+			  [],[BUILD_VMWGFX=no])
 fi
 
 DRIVER_NAME=vmware
diff --git a/vmwgfx/vmwgfx_dri2.c b/vmwgfx/vmwgfx_dri2.c
index 57f2d9d..4c74a6b 100644
--- a/vmwgfx/vmwgfx_dri2.c
+++ b/vmwgfx/vmwgfx_dri2.c
@@ -206,8 +206,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer, unsigned int for
     }
 
     private->srf = srf;
-    if (xa_surface_handle(srf, xa_handle_type_shared,
-	    &buffer->name, &buffer->pitch) != 0)
+    if (_xa_surface_handle(srf, &buffer->name, &buffer->pitch) != 0)
 	return FALSE;
 
     buffer->cpp = xa_format_depth(xa_surface_format(srf)) / 8;
@@ -228,7 +227,7 @@ dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
     struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(private->pPixmap);
 
     if (--private->refcount == 0 && srf) {
-	xa_surface_unref(srf);
+	xa_surface_destroy(srf);
     }
 
     /*
diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index bfc07f8..6301c29 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -617,8 +617,7 @@ vmwgfx_scanout_present(ScreenPtr pScreen, int drm_fd,
 	return FALSE;
     }
 
-    if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
-	    &handle, &dummy) != 0) {
+    if (_xa_surface_handle(vpix->hw, &handle, &dummy) != 0) {
 	LogMessage(X_ERROR, "Could not get present surface handle.\n");
 	return FALSE;
     }
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 346e7f4..1459933 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -146,7 +146,7 @@ vmwgfx_pixmap_free_storage(struct vmwgfx_saa_pixmap *vpix)
 	vpix->malloc = NULL;
     }
     if (!(vpix->backing & VMWGFX_PIX_SURFACE) && vpix->hw) {
-	xa_surface_unref(vpix->hw);
+	xa_surface_destroy(vpix->hw);
 	vpix->hw = NULL;
     }
     if (!(vpix->backing & VMWGFX_PIX_GMR) && vpix->gmr) {
@@ -451,7 +451,7 @@ vmwgfx_hw_kill(struct vmwgfx_saa *vsaa,
 				 &spix->dirty_hw))
 	return FALSE;
 
-    xa_surface_unref(vpix->hw);
+    xa_surface_destroy(vpix->hw);
     vpix->hw = NULL;
 
     /*
@@ -698,8 +698,7 @@ vmwgfx_present_prepare(struct vmwgfx_saa *vsaa,
 
     (void) pScreen;
     if (src_vpix == dst_vpix || !src_vpix->hw ||
-	xa_surface_handle(src_vpix->hw, xa_handle_type_shared,
-		&vsaa->src_handle, &dummy) != 0)
+	_xa_surface_handle(src_vpix->hw, &vsaa->src_handle, &dummy) != 0)
 	return FALSE;
 
     REGION_NULL(pScreen, &vsaa->present_region);
@@ -800,7 +799,7 @@ vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
     return TRUE;
 
 out_no_damage:
-    xa_surface_unref(hw);
+    xa_surface_destroy(hw);
     return FALSE;
 }
 
@@ -1459,8 +1458,7 @@ vmwgfx_scanout_ref(struct vmwgfx_screen_entry  *entry)
 	     */
 	    if (!vmwgfx_hw_accel_validate(pixmap, 0, XA_FLAG_SCANOUT, 0, NULL))
 		goto out_err;
-	    if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
-			 &handle, &dummy) != 0)
+	    if (_xa_surface_handle(vpix->hw, &handle, &dummy) != 0)
 		goto out_err;
 	    depth = xa_format_depth(xa_surface_format(vpix->hw));
 
diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h
index d8aa3d3..5e1f40c 100644
--- a/vmwgfx/vmwgfx_saa.h
+++ b/vmwgfx/vmwgfx_saa.h
@@ -115,4 +115,16 @@ vmwgfx_saa_set_master(ScreenPtr pScreen);
 void
 vmwgfx_saa_drop_master(ScreenPtr pScreen);
 
+#if (XA_TRACKER_VERSION_MAJOR <= 1) && !defined(HAVE_XA_2)
+
+#define _xa_surface_handle(_a, _b, _c) xa_surface_handle(_a, _b, _c)
+#define xa_context_flush(_a)
+
+#else
+
+#define xa_surface_destroy(_a) xa_surface_unref(_a)
+#define _xa_surface_handle(_a, _b, _c)		\
+    xa_surface_handle(_a, xa_handle_type_shared, _b, _c)
+
+#endif /*  (XA_TRACKER_VERSION_MAJOR <= 1) */
 #endif
diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index 3ba40ef..9fd8f22 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -199,7 +199,7 @@ stop_video(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
        for (i=0; i<3; ++i) {
 	   for (j=0; j<2; ++j) {
 	       if (priv->yuv[i]) {
-		   xa_surface_unref(priv->yuv[j][i]);
+		   xa_surface_destroy(priv->yuv[j][i]);
 		   priv->yuv[j][i] = NULL;
 	       }
 	   }
-- 
1.8.5.1


From c36cbcefb8526944141eb431e1e736dc4485a36e Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Mon, 9 Dec 2013 00:19:55 -0800
Subject: [PATCH 08/11] vmwgfx: Remove stray 1

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
---
 vmwgfx/vmwgfx_saa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 1459933..28819c1 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1230,7 +1230,7 @@ vmwgfx_operation_complete(struct saa_driver *driver,
      */
 
     if (vpix->hw && vpix->hw_is_dri2_fronts) {
-	if (1 && pScrn->vtSema &&
+	if (pScrn->vtSema &&
 	    vmwgfx_upload_to_hw(driver, pixmap, &spix->dirty_shadow)) {
 
 	    REGION_EMPTY(vsaa->pScreen, &spix->dirty_shadow);
-- 
1.8.5.1


From 4af6062ce281a7f4aaa50985fe757e9569208ee1 Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Wed, 11 Dec 2013 04:59:49 -0800
Subject: [PATCH 09/11] Revert "vmwgfx: Get rid of device-specific DMA code"

This reverts commit 45b2457516a9db4bd1d60fbb24a1efbe2d9dd932.

Reverting this because using direct DMA for shared pixmaps should
boost performance. It should be usable both in a composited environment
and when running hosted. Need to retest the DMA flaws I saw before disabling
this code.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
---
 vmwgfx/vmwgfx_drmi.c     | 103 +++++++++++++++++++++++++++++++++++++++++++++++
 vmwgfx/vmwgfx_drmi.h     |   5 +++
 vmwgfx/vmwgfx_saa.c      |  53 ++++++++++++------------
 vmwgfx/vmwgfx_saa_priv.h |   1 +
 4 files changed, 136 insertions(+), 26 deletions(-)

diff --git a/vmwgfx/vmwgfx_drmi.c b/vmwgfx/vmwgfx_drmi.c
index 1e23f4a..496a16b 100644
--- a/vmwgfx/vmwgfx_drmi.c
+++ b/vmwgfx/vmwgfx_drmi.c
@@ -284,6 +284,109 @@ vmwgfx_dmabuf_destroy(struct vmwgfx_dmabuf *buf)
 }
 
 int
+vmwgfx_dma(unsigned int host_x, unsigned int host_y,
+	   RegionPtr region, struct vmwgfx_dmabuf *buf,
+	   uint32_t buf_pitch, uint32_t surface_handle, int to_surface)
+{
+    BoxPtr clips = REGION_RECTS(region);
+    unsigned int num_clips = REGION_NUM_RECTS(region);
+    struct drm_vmw_execbuf_arg arg;
+    struct drm_vmw_fence_rep rep;
+    int ret;
+    unsigned int size;
+    unsigned i;
+    SVGA3dCopyBox *cb;
+    SVGA3dCmdSurfaceDMASuffix *suffix;
+    SVGA3dCmdSurfaceDMA *body;
+    struct vmwgfx_int_dmabuf *ibuf = vmwgfx_int_dmabuf(buf);
+
+    struct {
+	SVGA3dCmdHeader header;
+	SVGA3dCmdSurfaceDMA body;
+	SVGA3dCopyBox cb;
+    } *cmd;
+
+    if (num_clips == 0)
+	return 0;
+
+    size = sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cb) +
+	sizeof(*suffix);
+    cmd = malloc(size);
+    if (!cmd)
+	return -1;
+
+    cmd->header.id = SVGA_3D_CMD_SURFACE_DMA;
+    cmd->header.size = sizeof(cmd->body) + num_clips * sizeof(cmd->cb) +
+	sizeof(*suffix);
+    cb = &cmd->cb;
+
+    suffix = (SVGA3dCmdSurfaceDMASuffix *) &cb[num_clips];
+    suffix->suffixSize = sizeof(*suffix);
+    suffix->maximumOffset = (uint32_t) -1;
+    suffix->flags.discard = 0;
+    suffix->flags.unsynchronized = 0;
+    suffix->flags.reserved = 0;
+
+    body = &cmd->body;
+    body->guest.ptr.gmrId = buf->gmr_id;
+    body->guest.ptr.offset = buf->gmr_offset;
+    body->guest.pitch = buf_pitch;
+    body->host.sid = surface_handle;
+    body->host.face = 0;
+    body->host.mipmap = 0;
+
+    body->transfer =  (to_surface ? SVGA3D_WRITE_HOST_VRAM :
+		       SVGA3D_READ_HOST_VRAM);
+
+
+    for (i=0; i < num_clips; i++, cb++, clips++) {
+	cb->x = (uint16_t) clips->x1 + host_x;
+	cb->y = (uint16_t) clips->y1 + host_y;
+	cb->z = 0;
+	cb->srcx = (uint16_t) clips->x1;
+	cb->srcy = (uint16_t) clips->y1;
+	cb->srcz = 0;
+	cb->w = (uint16_t) (clips->x2 - clips->x1);
+	cb->h = (uint16_t) (clips->y2 - clips->y1);
+	cb->d = 1;
+#if 0
+	LogMessage(X_INFO, "DMA! x: %u y: %u srcx: %u srcy: %u w: %u h: %u %s\n",
+		   cb->x, cb->y, cb->srcx, cb->srcy, cb->w, cb->h,
+		   to_surface ? "to" : "from");
+#endif
+
+    }
+
+    memset(&arg, 0, sizeof(arg));
+    memset(&rep, 0, sizeof(rep));
+
+    rep.error = -EFAULT;
+    arg.fence_rep = ((to_surface) ? 0UL : (unsigned long)&rep);
+    arg.commands = (unsigned long)cmd;
+    arg.command_size = size;
+    arg.throttle_us = 0;
+    arg.version = DRM_VMW_EXECBUF_VERSION;
+
+    ret = drmCommandWrite(ibuf->drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
+    if (ret) {
+	LogMessage(X_ERROR, "DMA error %s.\n", strerror(-ret));
+    }
+
+    free(cmd);
+
+    if (rep.error == 0) {
+	ret = vmwgfx_fence_wait(ibuf->drm_fd, rep.handle, TRUE);
+	if (ret) {
+	    LogMessage(X_ERROR, "DMA from host fence wait error %s.\n",
+		       strerror(-ret));
+	    vmwgfx_fence_unref(ibuf->drm_fd, rep.handle);
+	}
+    }
+
+    return 0;
+}
+
+int
 vmwgfx_get_param(int drm_fd, uint32_t param, uint64_t *out)
 {
     struct drm_vmw_getparam_arg gp_arg;
diff --git a/vmwgfx/vmwgfx_drmi.h b/vmwgfx/vmwgfx_drmi.h
index fff728a..2435009 100644
--- a/vmwgfx/vmwgfx_drmi.h
+++ b/vmwgfx/vmwgfx_drmi.h
@@ -60,6 +60,11 @@ extern void
 vmwgfx_dmabuf_unmap(struct vmwgfx_dmabuf *buf);
 
 extern int
+vmwgfx_dma(unsigned int host_x, unsigned int host_y,
+	   RegionPtr region, struct vmwgfx_dmabuf *buf,
+	   uint32_t buf_pitch, uint32_t surface_handle, int to_surface);
+
+extern int
 vmwgfx_num_streams(int drm_fd, uint32_t *ntot, uint32_t *nfree);
 
 extern int
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 28819c1..96275a5 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -285,40 +285,40 @@ vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
 	       Bool to_hw)
 {
     struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
-    void *data = vpix->malloc;
-    int ret;
 
     if (!vpix->hw || (!vpix->gmr && !vpix->malloc))
 	return TRUE;
 
+    if (vpix->gmr && vsaa->can_optimize_dma) {
+	uint32_t handle, dummy;
 
-    if (vpix->gmr) {
-	data = vmwgfx_dmabuf_map(vpix->gmr);
-	if (!data)
+	if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
+		 &handle, &dummy) != 0)
 	    goto out_err;
-    }
-
-    ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
-			 (int) to_hw,
-			 (struct xa_box *) REGION_RECTS(reg),
-			 REGION_NUM_RECTS(reg));
-    if (vpix->gmr)
-	vmwgfx_dmabuf_unmap(vpix->gmr);
-
-    if (ret)
-	goto out_err;
+	if (vmwgfx_dma(0, 0, reg, vpix->gmr, pixmap->devKind, handle,
+		       to_hw) != 0)
+	    goto out_err;
+    } else {
+	void *data = vpix->malloc;
+	int ret;
 
-    ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
-			 (int) to_hw,
-			 (struct xa_box *) REGION_RECTS(reg),
-			 REGION_NUM_RECTS(reg));
-    if (to_hw)
-	xa_context_flush(vsaa->xa_ctx);
-    if (vpix->gmr)
-	vmwgfx_dmabuf_unmap(vpix->gmr);
-    if (ret)
-	goto out_err;
+	if (vpix->gmr) {
+	    data = vmwgfx_dmabuf_map(vpix->gmr);
+	    if (!data)
+		goto out_err;
+	}
 
+	ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
+			     (int) to_hw,
+			     (struct xa_box *) REGION_RECTS(reg),
+			     REGION_NUM_RECTS(reg));
+	if (to_hw)
+	    xa_context_flush(vsaa->xa_ctx);
+	if (vpix->gmr)
+	    vmwgfx_dmabuf_unmap(vpix->gmr);
+	if (ret)
+	    goto out_err;
+    }
     return TRUE;
   out_err:
     LogMessage(X_ERROR, "DMA %s surface failed.\n",
@@ -1377,6 +1377,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->use_present_opt = direct_presents;
     vsaa->only_hw_presents = only_hw_presents;
     vsaa->rendercheck = rendercheck;
diff --git a/vmwgfx/vmwgfx_saa_priv.h b/vmwgfx/vmwgfx_saa_priv.h
index f5f45ba..16583b0 100644
--- a/vmwgfx/vmwgfx_saa_priv.h
+++ b/vmwgfx/vmwgfx_saa_priv.h
@@ -50,6 +50,7 @@ struct vmwgfx_saa {
     int ydiff;
     RegionRec present_region;
     uint32_t src_handle;
+    Bool can_optimize_dma;
     Bool use_present_opt;
     Bool only_hw_presents;
     Bool rendercheck;
-- 
1.8.5.1


From 93228f3dd3355a25583d22dbb96791678b93be3e Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Wed, 11 Dec 2013 06:54:02 -0800
Subject: [PATCH 10/11] vmwgfx: Really allow XA version 2.

When XA starts to correctly advertise version 2, we didn't allow it.
Fix this.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
---
 vmwgfx/vmwgfx_driver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index 6301c29..4e28097 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -79,7 +79,7 @@ typedef uint8_t uint8;
 
 #define XA_VERSION_MINOR_REQUIRED 0
 #define XA_VERSION_MAJOR_REQUIRED 1
-#define XA_VERSION_MAJOR_COMPAT 1
+#define XA_VERSION_MAJOR_COMPAT 2
 
 #define DRM_VERSION_MAJOR_REQUIRED 2
 #define DRM_VERSION_MINOR_REQUIRED 3
-- 
1.8.5.1


From f45a551e9b70ccec8f92df02747d4e2af299cf8c Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom@vmware.com>
Date: Mon, 16 Dec 2013 10:38:21 +0100
Subject: [PATCH 11/11] vmwgfx: Fix compile breakage on XA version 1.

A recent revert brought back code that assumed XA version 2.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: trivial
---
 vmwgfx/vmwgfx_saa.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 96275a5..e76bd09 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -292,8 +292,7 @@ vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
     if (vpix->gmr && vsaa->can_optimize_dma) {
 	uint32_t handle, dummy;
 
-	if (xa_surface_handle(vpix->hw, xa_handle_type_shared,
-		 &handle, &dummy) != 0)
+	if (_xa_surface_handle(vpix->hw, &handle, &dummy) != 0)
 	    goto out_err;
 	if (vmwgfx_dma(0, 0, reg, vpix->gmr, pixmap->devKind, handle,
 		       to_hw) != 0)
-- 
1.8.5.1

