diff options
Diffstat (limited to 'main/xf86-video-vmware')
-rw-r--r-- | main/xf86-video-vmware/APKBUILD | 18 | ||||
-rw-r--r-- | main/xf86-video-vmware/xatracker-v2-fixes.patch | 1549 |
2 files changed, 1561 insertions, 6 deletions
diff --git a/main/xf86-video-vmware/APKBUILD b/main/xf86-video-vmware/APKBUILD index 4254f0f4d2..934f5fbf8c 100644 --- a/main/xf86-video-vmware/APKBUILD +++ b/main/xf86-video-vmware/APKBUILD @@ -1,7 +1,7 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=xf86-video-vmware pkgver=13.0.1 -pkgrel=0 +pkgrel=1 pkgdesc="X.org VMWare video driver" url="http://xorg.freedesktop.org/" arch="all" @@ -11,8 +11,11 @@ depends= makedepends="pkgconfig xorg-server-dev videoproto renderproto xproto libdrm-dev fontsproto xf86dgaproto xineramaproto randrproto xextproto libxi-dev" -source="http://xorg.freedesktop.org/releases/individual/driver/$pkgname-$pkgver.tar.bz2" +source="http://xorg.freedesktop.org/releases/individual/driver/$pkgname-$pkgver.tar.bz2 + xatracker-v2-fixes.patch + " +_builddir="$srcdir"/xf86-video-vmware-$pkgver prepare() { cd "$_builddir" update_config_sub || return 1 @@ -24,7 +27,7 @@ prepare() { } build() { - cd "$srcdir"/$pkgname-$pkgver + cd "$_builddir" export LDFLAGS="$LDFLAGS -Wl,-z,lazy" ./configure \ @@ -41,6 +44,9 @@ package() { rm "$pkgdir"/usr/lib/xorg/modules/*/*.la || return 1 install -Dm644 COPYING "$pkgdir"/usr/share/licenses/$pkgname/COPYING } -md5sums="b08e0195ebf3f88a82129322cb93da08 xf86-video-vmware-13.0.1.tar.bz2" -sha256sums="802dda415c22412edad6c3df44fe18a06e91d0f8456d9a58bac0d340fdf8fe3d xf86-video-vmware-13.0.1.tar.bz2" -sha512sums="2faf5fd524dffd2cd89a8b5a06b5470acbc51c3ee4f48bafc425b8e9c7c76d294201651cfb8c1d104c313885108e22abb6da736de1f3dbcf134a0926158ed147 xf86-video-vmware-13.0.1.tar.bz2" +md5sums="b08e0195ebf3f88a82129322cb93da08 xf86-video-vmware-13.0.1.tar.bz2 +bb2a64202644238815b9b223759a8515 xatracker-v2-fixes.patch" +sha256sums="802dda415c22412edad6c3df44fe18a06e91d0f8456d9a58bac0d340fdf8fe3d xf86-video-vmware-13.0.1.tar.bz2 +d943e66f1735edb2231fe8396065c1c4702cb9cba96cd9ff3a6afba75782bfd3 xatracker-v2-fixes.patch" +sha512sums="2faf5fd524dffd2cd89a8b5a06b5470acbc51c3ee4f48bafc425b8e9c7c76d294201651cfb8c1d104c313885108e22abb6da736de1f3dbcf134a0926158ed147 xf86-video-vmware-13.0.1.tar.bz2 +d87398febf7e900881ee7cdf137492c3759ffca5c90d2c5b8b0d2872cc7971fc8b37b42b5b298f08350b449fc91e4158b69af8275ea99f7a8a60e7c42cf9b45e xatracker-v2-fixes.patch" diff --git a/main/xf86-video-vmware/xatracker-v2-fixes.patch b/main/xf86-video-vmware/xatracker-v2-fixes.patch new file mode 100644 index 0000000000..c379dbb61f --- /dev/null +++ b/main/xf86-video-vmware/xatracker-v2-fixes.patch @@ -0,0 +1,1549 @@ +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/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, ®, &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, ®, &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, ®, &box); +- } +- +- if (xa_surface_handle(srf, xa_handle_type_shared, +- &handle, &stride) != 0) { +- ret = BadAlloc; +- break; +- } +- +- if (vmwgfx_dma(0, 0, ®, buf, w, handle, 1) != 0) { +- ret = BadAlloc; +- break; +- } +- } +- REGION_UNINIT(pScrn->pScreen, ®); +- } ++ 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/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 + |