xserver-xorg-video-vmware: Changes to 'upstream-ubuntu'
configure.ac | 6
src/vmware_bootstrap.c | 20 ++
src/vmware_bootstrap.h | 2
src/vmwarevideo.c | 4
vmwgfx/Makefile.am | 5
vmwgfx/vmwgfx_dri2.c | 37 +++++
vmwgfx/vmwgfx_driver.c | 309 ++++++++++++++++++++++++++------------------
vmwgfx/vmwgfx_driver.h | 4
vmwgfx/vmwgfx_drmi.c | 142 ++++++++++++++++++++
vmwgfx/vmwgfx_drmi.h | 13 +
vmwgfx/vmwgfx_hosted.c | 71 ++++++++++
vmwgfx/vmwgfx_hosted.h | 258 ++++++++++++++++++++++++++++++++++++
vmwgfx/vmwgfx_hosted_priv.h | 40 +++++
vmwgfx/vmwgfx_overlay.c | 8 -
vmwgfx/vmwgfx_saa.c | 263 ++++++++++++++++++++++++++++++++-----
vmwgfx/vmwgfx_saa.h | 7
vmwgfx/vmwgfx_saa_priv.h | 2
vmwgfx/vmwgfx_tex_video.c | 2
vmwgfx/vmwgfx_xa_surface.c | 2
vmwgfx/vmwgfx_xmir.c | 178 +++++++++++++++++++++++++
vmwgfx/vmwgfx_xwayland.c | 186 ++++++++++++++++++++++++++
21 files changed, 1393 insertions(+), 166 deletions(-)
New commits:
commit 8da981712f62050076cff53e1b40ed1e307fcca8
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date: Wed Jan 15 11:04:05 2014 +0100
vmware/vmwgfx: Always allocate shared hardware surfaces.
Hardware surfaces are all likely to be shared at some point, and we *really*
don't want to change a hardware surface that is bound as a drm framebuffer.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 8c97618..b56b05f 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -811,7 +811,7 @@ vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
return TRUE;
new_flags = (vpix->xa_flags & ~vpix->staging_remove_flags) |
- vpix->staging_add_flags;
+ vpix->staging_add_flags | XA_FLAG_SHARED;
hw = xa_surface_create(vsaa->xat,
pixmap->drawable.width,
diff --git a/vmwgfx/vmwgfx_xa_surface.c b/vmwgfx/vmwgfx_xa_surface.c
index 2f23c57..189bfdc 100644
--- a/vmwgfx/vmwgfx_xa_surface.c
+++ b/vmwgfx/vmwgfx_xa_surface.c
@@ -318,7 +318,7 @@ vmwgfx_hw_commit(PixmapPtr pixmap)
uint32_t new_flags;
new_flags = (vpix->xa_flags & ~vpix->staging_remove_flags) |
- vpix->staging_add_flags;
+ vpix->staging_add_flags | XA_FLAG_SHARED;
if (vpix->staging_format != xa_surface_format(vpix->hw))
LogMessage(X_INFO, "Changing hardware format.\n");
commit 31bff9f7f3d9a68fd1449532e8ab50065de63857
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date: Thu Jan 9 13:53:59 2014 +0100
vmware: Require libdrm 2.4.38 to build XMir.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
diff --git a/configure.ac b/configure.ac
index 123356c..3e8d541 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,6 +127,12 @@ if test x$BUILD_VMWGFX = xyes; then
[AC_DEFINE([HAVE_XA_2], 1,
[Has version 2 of XA])])],
[],[BUILD_VMWGFX=no])
+#
+# Check for prime.
+#
+ PKG_CHECK_EXISTS([libdrm >= 2.4.38],
+ [AC_DEFINE([HAVE_LIBDRM_2_4_38], 1,
+ [Has version 2.4.38 or greater of libdrm])])
fi
DRIVER_NAME=vmware
diff --git a/vmwgfx/vmwgfx_drmi.c b/vmwgfx/vmwgfx_drmi.c
index d926019..b6fb56d 100644
--- a/vmwgfx/vmwgfx_drmi.c
+++ b/vmwgfx/vmwgfx_drmi.c
@@ -501,6 +501,7 @@ vmwgfx_max_fb_size(int drm_fd, size_t *size)
return 0;
}
+#ifdef HAVE_LIBDRM_2_4_38
/**
* vmwgfx_prime_fd_to_handle - Return a TTM handle to a prime object
*
@@ -537,3 +538,4 @@ vmwgfx_prime_release_handle(int drm_fd, uint32_t handle)
(void) drmCommandWrite(drm_fd, DRM_VMW_UNREF_SURFACE, &s_arg,
sizeof(s_arg));
}
+#endif /* HAVE_LIBDRM_2_4_38 */
diff --git a/vmwgfx/vmwgfx_drmi.h b/vmwgfx/vmwgfx_drmi.h
index 1494485..3168088 100644
--- a/vmwgfx/vmwgfx_drmi.h
+++ b/vmwgfx/vmwgfx_drmi.h
@@ -85,9 +85,11 @@ vmwgfx_update_gui_layout(int drm_fd, unsigned int num_rects,
int
vmwgfx_get_param(int drm_fd, uint32_t param, uint64_t *out);
+#ifdef HAVE_LIBDRM_2_4_38
int
vmwgfx_prime_fd_to_handle(int drm_fd, int prime_fd, uint32_t *handle);
void
vmwgfx_prime_release_handle(int drm_fd, uint32_t handle);
+#endif /* HAVE_LIBDRM_2_4_38 */
#endif
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index cb55849..8c97618 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1618,7 +1618,7 @@ vmwgfx_saa_drop_master(ScreenPtr pScreen)
* Helpers for hosted.
*/
-#if (XA_TRACKER_VERSION_MAJOR >= 2)
+#if (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38)
/**
* vmwgfx_saa_copy_to_surface - Copy Drawable contents to an external surface.
diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h
index 55f0ded..921fabd 100644
--- a/vmwgfx/vmwgfx_saa.h
+++ b/vmwgfx/vmwgfx_saa.h
@@ -116,9 +116,11 @@ vmwgfx_saa_set_master(ScreenPtr pScreen);
void
vmwgfx_saa_drop_master(ScreenPtr pScreen);
+#if (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38)
Bool
vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
const BoxRec *dst_box, RegionPtr region);
+#endif /* (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38) */
#if (XA_TRACKER_VERSION_MAJOR <= 1) && !defined(HAVE_XA_2)
diff --git a/vmwgfx/vmwgfx_xmir.c b/vmwgfx/vmwgfx_xmir.c
index e0ff6a4..ede6753 100644
--- a/vmwgfx/vmwgfx_xmir.c
+++ b/vmwgfx/vmwgfx_xmir.c
@@ -32,7 +32,7 @@
#include "vmwgfx_hosted_priv.h"
#include <xa_tracker.h>
-#if XMIR && (XA_TRACKER_VERSION_MAJOR >= 2)
+#if XMIR && (XA_TRACKER_VERSION_MAJOR >= 2) && defined(HAVE_LIBDRM_2_4_38)
#include "vmwgfx_hosted.h"
#include "vmwgfx_saa.h"
commit d6b179a5addef6456325adf241eb8dcaf8e4c3d6
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date: Thu Jan 9 13:28:22 2014 +0100
vmware: Fix build errors and warnings
A previous commit and the hosted merge unfortunately brought in some build
errors / warnings on early X servers.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
diff --git a/src/vmware_bootstrap.c b/src/vmware_bootstrap.c
index 57f8ae9..ed6c740 100644
--- a/src/vmware_bootstrap.c
+++ b/src/vmware_bootstrap.c
@@ -34,6 +34,7 @@
#include "xf86Pci.h" /* pci */
#include "vm_device_version.h"
#include "vmware_bootstrap.h"
+#include <stdint.h>
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
#include "xf86Resources.h"
diff --git a/src/vmwarevideo.c b/src/vmwarevideo.c
index 8d7d171..745c71f 100644
--- a/src/vmwarevideo.c
+++ b/src/vmwarevideo.c
@@ -82,7 +82,7 @@
#define VMWARE_VID_MAX_HEIGHT 2048
#define VMWARE_VID_NUM_ENCODINGS 1
-static const XF86VideoEncodingRec vmwareVideoEncodings[] =
+static XF86VideoEncodingRec vmwareVideoEncodings[] =
{
{
0,
@@ -108,7 +108,7 @@ static XF86ImageRec vmwareVideoImages[] =
};
#define VMWARE_VID_NUM_ATTRIBUTES 2
-static const XF86AttributeRec vmwareVideoAttributes[] =
+static XF86AttributeRec vmwareVideoAttributes[] =
{
{
XvGettable | XvSettable,
diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index dc05b86..2d38d2a 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -130,7 +130,7 @@ vmwgfx_hookup(ScrnInfoPtr pScrn)
}
void
-vmwgfx_modify_flags(CARD32 *flags)
+vmwgfx_modify_flags(uint32_t *flags)
{
*flags &= ~(HW_IO);
vmwgfx_hosted_modify_flags(flags);
diff --git a/vmwgfx/vmwgfx_overlay.c b/vmwgfx/vmwgfx_overlay.c
index c8c6bb9..2c0d7fa 100644
--- a/vmwgfx/vmwgfx_overlay.c
+++ b/vmwgfx/vmwgfx_overlay.c
@@ -85,7 +85,7 @@ typedef uint8_t uint8;
#define VMWARE_VID_MAX_HEIGHT 2048
#define VMWARE_VID_NUM_ENCODINGS 1
-static const XF86VideoEncodingRec vmwareVideoEncodings[] =
+static XF86VideoEncodingRec vmwareVideoEncodings[] =
{
{
0,
@@ -111,7 +111,7 @@ static XF86ImageRec vmwareVideoImages[] =
};
#define VMWARE_VID_NUM_ATTRIBUTES 2
-static const XF86AttributeRec vmwareVideoAttributes[] =
+static XF86AttributeRec vmwareVideoAttributes[] =
{
{
XvGettable | XvSettable,
diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index 9fd8f22..0803a99 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -82,7 +82,7 @@ static XF86VideoFormatRec Formats[NUM_FORMATS] = {
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
};
-static const XF86VideoEncodingRec DummyEncoding[1] = {
+static XF86VideoEncodingRec DummyEncoding[1] = {
{
0,
"XV_IMAGE",
commit f37684e7169b9c0ab23ff748d5acacb65fad82f7
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date: Tue Jan 7 17:55:49 2014 +0100
vmwgfx: Block DMA to prime surfaces for now
Since there is currently no _good_ way to get the surface format of a
prime surface, we block DMA to these surfaces; we don't know if our
software data is compatible with the surface format.
This patch also makes sure that there is a hardware surface backing the
drawable we copy from.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index c323c5f..cb55849 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1428,6 +1428,7 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
vsaa->only_hw_presents = only_hw_presents;
vsaa->rendercheck = rendercheck;
vsaa->is_master = TRUE;
+ vsaa->known_prime_format = FALSE;
WSBMINITLISTHEAD(&vsaa->sync_x_list);
WSBMINITLISTHEAD(&vsaa->pixmaps);
@@ -1688,23 +1689,24 @@ vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
/*
* Determine the intersection between software contents and region to copy.
- * XXX: First check that the software contents is compatible with the
- * external surface format, before applying this optimization.
*/
- REGION_NULL(pScreen, &intersection);
- if (!vpix->hw)
- REGION_COPY(pScreen, &intersection, region);
- else if (spix->damage && REGION_NOTEMPTY(pScreen, &spix->dirty_shadow))
- REGION_INTERSECT(pScreen, &intersection, region, &spix->dirty_shadow);
- /*
- * DMA software contents directly into the destination. Then subtract
- * the region we've DMA'd from the region to copy.
- */
- if (REGION_NOTEMPTY(pScreen, &intersection)) {
- if (vmwgfx_saa_dma(vsaa, src, &intersection, TRUE, dx, dy, dst)) {
- REGION_SUBTRACT(pScreen, &intersection, region, &intersection);
- copy_region = &intersection;
+ if (vsaa->known_prime_format) {
+ REGION_NULL(pScreen, &intersection);
+ if (!vpix->hw)
+ REGION_COPY(pScreen, &intersection, region);
+ else if (spix->damage && REGION_NOTEMPTY(pScreen, &spix->dirty_shadow))
+ REGION_INTERSECT(pScreen, &intersection, region, &spix->dirty_shadow);
+
+ /*
+ * DMA software contents directly into the destination. Then subtract
+ * the region we've DMA'd from the region to copy.
+ */
+ if (REGION_NOTEMPTY(pScreen, &intersection)) {
+ if (vmwgfx_saa_dma(vsaa, src, &intersection, TRUE, dx, dy, dst)) {
+ REGION_SUBTRACT(pScreen, &intersection, region, &intersection);
+ copy_region = &intersection;
+ }
}
}
@@ -1717,6 +1719,11 @@ vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
box = REGION_RECTS(copy_region);
n = REGION_NUM_RECTS(copy_region);
+ if (!vmwgfx_hw_accel_validate(src, 0, 0, 0, copy_region)) {
+ ret = FALSE;
+ goto out_no_copy;
+ }
+
if (xa_copy_prepare(vsaa->xa_ctx, dst, vpix->hw) != XA_ERR_NONE) {
ret = FALSE;
goto out_no_copy;
@@ -1732,7 +1739,8 @@ vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
xa_context_flush(vsaa->xa_ctx);
out_no_copy:
- REGION_UNINIT(pScreen, &intersection);
+ if (vsaa->known_prime_format)
+ REGION_UNINIT(pScreen, &intersection);
if (sx || sy)
REGION_TRANSLATE(pScreen, region, -sx, -sy);
xa_surface_unref(dst);
diff --git a/vmwgfx/vmwgfx_saa_priv.h b/vmwgfx/vmwgfx_saa_priv.h
index 16583b0..c84827b 100644
--- a/vmwgfx/vmwgfx_saa_priv.h
+++ b/vmwgfx/vmwgfx_saa_priv.h
@@ -55,6 +55,7 @@ struct vmwgfx_saa {
Bool only_hw_presents;
Bool rendercheck;
Bool is_master;
+ Bool known_prime_format;
void (*present_flush) (ScreenPtr pScreen);
struct _WsbmListHead sync_x_list;
struct _WsbmListHead pixmaps;
commit 97ce302ddd6e86397ea56ea9089b9549af73c3ac
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date: Mon Jan 6 12:37:36 2014 +0100
vmwgfx: Enable direct dmas
Enable direct dmas instead of using the xa-provided dma functionality.
This saves a bounce-buffer software copy of all dma'd contents.
This also implies that all drawables with mixed software / hardware contents
will use a kernel buffer for software rendering.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index c8b4df1..c323c5f 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1423,7 +1423,7 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
vsaa->xa_ctx = xa_context_default(xat);
vsaa->drm_fd = drm_fd;
vsaa->present_flush = present_flush;
- vsaa->can_optimize_dma = FALSE;
+ vsaa->can_optimize_dma = TRUE;
vsaa->use_present_opt = direct_presents;
vsaa->only_hw_presents = only_hw_presents;
vsaa->rendercheck = rendercheck;
commit fd636e39a3f32a6dcd107c370513d8cb9aae26c2
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date: Mon Dec 16 06:21:09 2013 -0800
vmwgfx: Add support for XWayland
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
diff --git a/vmwgfx/Makefile.am b/vmwgfx/Makefile.am
index 41833a1..81b9e08 100644
--- a/vmwgfx/Makefile.am
+++ b/vmwgfx/Makefile.am
@@ -29,5 +29,6 @@ libvmwgfx_la_SOURCES = \
vmwgfx_hosted.h \
vmwgfx_hosted_priv.h \
vmwgfx_xmir.c \
+ vmwgfx_xwayland.c \
wsbm_util.h
endif
diff --git a/vmwgfx/vmwgfx_hosted.c b/vmwgfx/vmwgfx_hosted.c
index 018b88b..9b41f3e 100644
--- a/vmwgfx/vmwgfx_hosted.c
+++ b/vmwgfx/vmwgfx_hosted.c
@@ -48,6 +48,9 @@ vmwgfx_hosted_detect(void)
{
const struct vmwgfx_hosted_driver *tmp = vmwgfx_xmir_detect();
+ if (!tmp)
+ tmp = vmwgfx_xwl_detect();
+
return tmp;
}
@@ -64,4 +67,5 @@ void
vmwgfx_hosted_modify_flags(uint32_t *flags)
{
vmwgfx_xmir_modify_flags(flags);
+ vmwgfx_xwl_modify_flags(flags);
}
diff --git a/vmwgfx/vmwgfx_hosted_priv.h b/vmwgfx/vmwgfx_hosted_priv.h
index c81f5ee..2668e55 100644
--- a/vmwgfx/vmwgfx_hosted_priv.h
+++ b/vmwgfx/vmwgfx_hosted_priv.h
@@ -34,4 +34,7 @@
extern const struct vmwgfx_hosted_driver *vmwgfx_xmir_detect(void);
extern void vmwgfx_xmir_modify_flags(uint32_t *flags);
+extern const struct vmwgfx_hosted_driver *vmwgfx_xwl_detect(void);
+extern void vmwgfx_xwl_modify_flags(uint32_t *flags);
+
#endif
diff --git a/vmwgfx/vmwgfx_xwayland.c b/vmwgfx/vmwgfx_xwayland.c
new file mode 100644
index 0000000..a16a7c4
--- /dev/null
+++ b/vmwgfx/vmwgfx_xwayland.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 VMWare, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ * Author: Jakob Bornecrantz <jakob@vmware.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmwgfx_hosted_priv.h"
+
+#ifdef XORG_WAYLAND
+
+#include "vmwgfx_hosted.h"
+#include "vmwgfx_saa.h"
+#include <xf86Priv.h>
+#include <xwayland.h>
+
+struct vmwgfx_hosted {
+ struct xwl_screen *xwl;
+ ScrnInfoPtr pScrn;
+ ScreenPtr pScreen;
+};
+
+static int
+vmwgfx_create_window_buffer(struct xwl_window *xwl_window,
+ PixmapPtr pixmap)
+{
+ struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
+ uint32_t name, pitch;
+
+ if (!vmwgfx_hw_dri2_validate(pixmap, 0))
+ return BadDrawable;
+
+ /*
+ * Pixmaps with hw_is_hosted == TRUE are put on a flush list when
+ * they've seen software rendering. When vmwgfx_flush_dri2 is called
+ * on these pixmaps, software contents are flushed to the hardware
+ * surface.
+ */
+ vpix->hw_is_hosted = TRUE;
+ if (xa_surface_handle(vpix->hw, &name, &pitch) != XA_ERR_NONE)
+ return BadDrawable;
+
+ return xwl_create_window_buffer_drm(xwl_window, pixmap, name);
+}
+
+static struct xwl_driver vmwgfx_xwl_driver = {
+ .version = 2,
+ .use_drm = 1,
+ .create_window_buffer = vmwgfx_create_window_buffer
+};
+
+static struct vmwgfx_hosted *
+vmwgfx_xwl_create(ScrnInfoPtr pScrn)
+{
+ struct vmwgfx_hosted *hosted;
+
+ hosted = calloc(1, sizeof(*hosted));
+ if (!hosted)
+ return NULL;
+
+ hosted->xwl = xwl_screen_create();
+ if (!hosted->xwl) {
+ free(hosted);
+ return NULL;
+ }
+
+ hosted->pScrn = pScrn;
+ return hosted;
+}
+
+static void
+vmwgfx_xwl_destroy(struct vmwgfx_hosted *hosted)
+{
+ xwl_screen_destroy(hosted->xwl);
+ free(hosted);
+}
+
+static Bool
+vmwgfx_xwl_pre_init(struct vmwgfx_hosted *hosted, int flags)
+{
+ return xwl_screen_pre_init(hosted->pScrn, hosted->xwl, 0,
+ &vmwgfx_xwl_driver);
+}
+
+static int
+vmwgfx_xwl_drm_fd(struct vmwgfx_hosted *hosted, const struct pci_device *pci)
+{
+ return xwl_screen_get_drm_fd(hosted->xwl);
+}
+
+static Bool
+vmwgfx_xwl_screen_init(struct vmwgfx_hosted *hosted, ScreenPtr pScreen)
+{
+ if (xwl_screen_init(hosted->xwl, pScreen))
+ return FALSE;
+
+ hosted->pScreen = pScreen;
+
+ return TRUE;
+}
+
+static void
+vmwgfx_xwl_screen_close(struct vmwgfx_hosted *hosted)
+{
+ if (hosted->pScreen)
+ xwl_screen_close(hosted->xwl);
+
+ hosted->pScreen = NULL;
+}
+
+static void
+vmwgfx_xwl_post_damage(struct vmwgfx_hosted *hosted)
+{
+ vmwgfx_flush_dri2(hosted->pScreen);
+ xwl_screen_post_damage(hosted->xwl);
+}
+
+static int
+vmwgfx_xwl_dri_auth(struct vmwgfx_hosted *hosted, ClientPtr client,
+ uint32_t magic)
+{
+ return xwl_drm_authenticate(client, hosted->xwl, magic);
+}
+
+static const struct vmwgfx_hosted_driver vmwgfx_hosted_xwl_driver = {
+ .create = vmwgfx_xwl_create,
+ .destroy = vmwgfx_xwl_destroy,
+ .drm_fd = vmwgfx_xwl_drm_fd,
+ .pre_init = vmwgfx_xwl_pre_init,
+ .screen_init = vmwgfx_xwl_screen_init,
+ .screen_close = vmwgfx_xwl_screen_close,
+ .post_damage = vmwgfx_xwl_post_damage,
+ .dri_auth = vmwgfx_xwl_dri_auth
+};
+
+const struct vmwgfx_hosted_driver *
+vmwgfx_xwl_detect(void)
+{
+ return (xorgWayland) ? &vmwgfx_hosted_xwl_driver : NULL;
+}
+
+void
+vmwgfx_xwl_modify_flags(uint32_t *flags)
+{
+ if (xorgWayland)
+ *flags |= HW_SKIP_CONSOLE | HW_WAYLAND;
+}
+
+#else
+
+const struct vmwgfx_hosted_driver *
+vmwgfx_xwl_detect(void)
+{
+ return NULL;
+}
+
+void
+vmwgfx_xwl_modify_flags(uint32_t *flags)
+{
+}
+#endif
commit c020923597d3bc30dffa89ba0a47f3b9517dd5fb
Author: Thomas Hellstrom <thellstrom@vmware.com>
Date: Mon Dec 16 06:13:25 2013 -0800
vmwgfx: Add support for XMir v2.
Use the hosted infrastructure to add support for XMir.
Helpers go in vmwgfx_saa.c.
v2: Added comments for the helpers, and added a
vmwgfx_flush_dri2 to be executed when coming back from vt switch.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
diff --git a/vmwgfx/Makefile.am b/vmwgfx/Makefile.am
index 2b0380b..41833a1 100644
--- a/vmwgfx/Makefile.am
+++ b/vmwgfx/Makefile.am
@@ -28,5 +28,6 @@ libvmwgfx_la_SOURCES = \
vmwgfx_hosted.c \
vmwgfx_hosted.h \
vmwgfx_hosted_priv.h \
+ vmwgfx_xmir.c \
wsbm_util.h
endif
diff --git a/vmwgfx/vmwgfx_drmi.c b/vmwgfx/vmwgfx_drmi.c
index 496a16b..d926019 100644
--- a/vmwgfx/vmwgfx_drmi.c
+++ b/vmwgfx/vmwgfx_drmi.c
@@ -284,7 +284,7 @@ vmwgfx_dmabuf_destroy(struct vmwgfx_dmabuf *buf)
}
int
-vmwgfx_dma(unsigned int host_x, unsigned int host_y,
+vmwgfx_dma(int host_x, int host_y,
RegionPtr region, struct vmwgfx_dmabuf *buf,
uint32_t buf_pitch, uint32_t surface_handle, int to_surface)
{
@@ -500,3 +500,40 @@ vmwgfx_max_fb_size(int drm_fd, size_t *size)
return 0;
}
+
+/**
+ * vmwgfx_prime_fd_to_handle - Return a TTM handle to a prime object
+ *
+ * @drm_fd: File descriptor for the drm connection.
+ * @prime_fd: File descriptor identifying the prime object.
+ * @handle: Pointer to returned TTM handle.
+ *
+ * Takes a reference on the underlying object and returns a TTM handle to it.
+ */
+int
+vmwgfx_prime_fd_to_handle(int drm_fd, int prime_fd, uint32_t *handle)
+{
+ *handle = 0;
+
+ return drmPrimeFDToHandle(drm_fd, prime_fd, handle);
+}
+
+/**
+ * vmwgfx_prime_release_handle - Release a reference on a TTM object
+ *
+ * @drm_fd: File descriptor for the drm connection.
+ * @handle: TTM handle as returned by vmwgfx_prime_fd_to_handle.
+ *
+ * Releases the reference obtained by vmwgfx_prime_fd_to_handle().
+ */
+void
+vmwgfx_prime_release_handle(int drm_fd, uint32_t handle)
+{
+ struct drm_vmw_surface_arg s_arg;
+
+ memset(&s_arg, 0, sizeof(s_arg));
+ s_arg.sid = handle;
+
+ (void) drmCommandWrite(drm_fd, DRM_VMW_UNREF_SURFACE, &s_arg,
+ sizeof(s_arg));
+}
diff --git a/vmwgfx/vmwgfx_drmi.h b/vmwgfx/vmwgfx_drmi.h
index 2435009..1494485 100644
--- a/vmwgfx/vmwgfx_drmi.h
+++ b/vmwgfx/vmwgfx_drmi.h
@@ -60,7 +60,7 @@ extern void
vmwgfx_dmabuf_unmap(struct vmwgfx_dmabuf *buf);
extern int
-vmwgfx_dma(unsigned int host_x, unsigned int host_y,
+vmwgfx_dma(int host_x, int host_y,
RegionPtr region, struct vmwgfx_dmabuf *buf,
uint32_t buf_pitch, uint32_t surface_handle, int to_surface);
@@ -84,4 +84,10 @@ vmwgfx_update_gui_layout(int drm_fd, unsigned int num_rects,
struct drm_vmw_rect *rects);
int
vmwgfx_get_param(int drm_fd, uint32_t param, uint64_t *out);
+
+int
+vmwgfx_prime_fd_to_handle(int drm_fd, int prime_fd, uint32_t *handle);
+
+void
+vmwgfx_prime_release_handle(int drm_fd, uint32_t handle);
#endif
diff --git a/vmwgfx/vmwgfx_hosted.c b/vmwgfx/vmwgfx_hosted.c
index b42d962..018b88b 100644
--- a/vmwgfx/vmwgfx_hosted.c
+++ b/vmwgfx/vmwgfx_hosted.c
@@ -46,7 +46,9 @@
const struct vmwgfx_hosted_driver *
vmwgfx_hosted_detect(void)
{
- return NULL;
+ const struct vmwgfx_hosted_driver *tmp = vmwgfx_xmir_detect();
+
+ return tmp;
}
/**
@@ -61,4 +63,5 @@ vmwgfx_hosted_detect(void)
void
vmwgfx_hosted_modify_flags(uint32_t *flags)
{
+ vmwgfx_xmir_modify_flags(flags);
}
diff --git a/vmwgfx/vmwgfx_hosted.h b/vmwgfx/vmwgfx_hosted.h
index 8f3b243..78dc7cd 100644
--- a/vmwgfx/vmwgfx_hosted.h
+++ b/vmwgfx/vmwgfx_hosted.h
@@ -23,6 +23,7 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Author: Thomas Hellstrom <thellstrom@vmware.com>
+ * Note: "Hosted" is a term stolen from the xf86-video-intel driver.
*/
#ifndef _VMWGFX_HOSTED_H
diff --git a/vmwgfx/vmwgfx_hosted_priv.h b/vmwgfx/vmwgfx_hosted_priv.h
index 05ded25..c81f5ee 100644
--- a/vmwgfx/vmwgfx_hosted_priv.h
+++ b/vmwgfx/vmwgfx_hosted_priv.h
@@ -31,4 +31,7 @@
#include <stdint.h>
#include "vmwgfx_hosted.h"
+extern const struct vmwgfx_hosted_driver *vmwgfx_xmir_detect(void);
+extern void vmwgfx_xmir_modify_flags(uint32_t *flags);
+
#endif
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index e76bd09..c8b4df1 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -282,32 +282,44 @@ static Bool
vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
PixmapPtr pixmap,
RegionPtr reg,
- Bool to_hw)
+ Bool to_hw,
+ int dx,
+ int dy,
+ struct xa_surface *srf)
{
struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
- if (!vpix->hw || (!vpix->gmr && !vpix->malloc))
+ if (!srf)
+ srf = vpix->hw;
+
+ if (!srf || (!vpix->gmr && !vpix->malloc))
return TRUE;
if (vpix->gmr && vsaa->can_optimize_dma) {
uint32_t handle, dummy;
- if (_xa_surface_handle(vpix->hw, &handle, &dummy) != 0)
+ if (_xa_surface_handle(srf, &handle, &dummy) != 0)
goto out_err;
- if (vmwgfx_dma(0, 0, reg, vpix->gmr, pixmap->devKind, handle,
+ if (vmwgfx_dma(dx, dy, reg, vpix->gmr, pixmap->devKind, handle,
to_hw) != 0)
goto out_err;
} else {
- void *data = vpix->malloc;
+ uint8_t *data = (uint8_t *) vpix->malloc;
int ret;
if (vpix->gmr) {
- data = vmwgfx_dmabuf_map(vpix->gmr);
+ data = (uint8_t *) vmwgfx_dmabuf_map(vpix->gmr);
if (!data)
goto out_err;
}
- ret = xa_surface_dma(vsaa->xa_ctx, vpix->hw, data, pixmap->devKind,
+ if (dx || dy) {
+ REGION_TRANSLATE(pScreen, reg, dx, dy);
+ data -= ((dx * pixmap->drawable.bitsPerPixel + 7)/8 +
+ dy * pixmap->devKind);
+ }
+
+ ret = xa_surface_dma(vsaa->xa_ctx, srf, data, pixmap->devKind,
(int) to_hw,
(struct xa_box *) REGION_RECTS(reg),
REGION_NUM_RECTS(reg));
@@ -315,6 +327,8 @@ vmwgfx_saa_dma(struct vmwgfx_saa *vsaa,
xa_context_flush(vsaa->xa_ctx);
if (vpix->gmr)
vmwgfx_dmabuf_unmap(vpix->gmr);
+ if (dx || dy)
+ REGION_TRANSLATE(pScreen, reg, -dx, -dy);
if (ret)
goto out_err;
}
@@ -353,7 +367,7 @@ vmwgfx_download_from_hw(struct saa_driver *driver, PixmapPtr pixmap,
if (!vmwgfx_pixmap_create_sw(vsaa, pixmap))
goto out_err;
- if (!vmwgfx_saa_dma(vsaa, pixmap, readback, FALSE))
+ if (!vmwgfx_saa_dma(vsaa, pixmap, readback, FALSE, 0, 0, NULL))
goto out_err;
REGION_SUBTRACT(vsaa->pScreen, &spix->dirty_hw, &spix->dirty_hw, readback);
REGION_UNINIT(vsaa->pScreen, &intersection);
@@ -368,7 +382,8 @@ static Bool
vmwgfx_upload_to_hw(struct saa_driver *driver, PixmapPtr pixmap,
RegionPtr upload)
{
- return vmwgfx_saa_dma(to_vmwgfx_saa(driver), pixmap, upload, TRUE);
+ return vmwgfx_saa_dma(to_vmwgfx_saa(driver), pixmap, upload, TRUE,
+ 0, 0, NULL);
}
static void
@@ -753,6 +768,33 @@ vmwgfx_check_hw_contents(struct vmwgfx_saa *vsaa,
REGION_UNINIT(vsaa->pScreen, &intersection);
}
+/**
+ * vmwgfx_prefer_gmr: Prefer a dma buffer over malloced memory for software
+ * rendered storage
+ *
+ * @vsaa: Pointer to a struct vmwgfx_saa accelerator.
+ * @pixmap: Pointer to pixmap whose storage preference we want to alter.
+ *
+ * If possible, alter the storage or future storage of the software contents
+ * of this pixmap to be in a DMA buffer rather than in malloced memory.
+ * This function should be called when it's likely that frequent DMA operations
+ * will occur between a surface and the memory holding the software
+ * contents.
+ */
+static void
+vmwgfx_prefer_gmr(struct vmwgfx_saa *vsaa, PixmapPtr pixmap)
+{
+ struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
+
+ if (vsaa->can_optimize_dma) {
+ if (vpix->malloc) {
+ (void) vmwgfx_pixmap_create_gmr(vsaa, pixmap);
+ } else if (vpix->backing & VMWGFX_PIX_MALLOC) {
+ vpix->backing |= VMWGFX_PIX_GMR;
+ vpix->backing &= ~VMWGFX_PIX_MALLOC;
+ }
+ }
+}
Bool
vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
@@ -786,15 +828,16 @@ vmwgfx_create_hw(struct vmwgfx_saa *vsaa,
if (!vmwgfx_pixmap_add_damage(pixmap))
goto out_no_damage;
- /*
- * Even if we don't have a GMR yet, indicate that when needed it
- * should be created.
- */
-
vpix->hw = hw;
vpix->backing |= VMWGFX_PIX_SURFACE;
vmwgfx_pixmap_free_storage(vpix);
+ /*
+ * If there is a HW surface, make sure that the shadow is
+ * (or will be) a GMR, provided we can do fast DMAs from / to it.
+ */
+ vmwgfx_prefer_gmr(vsaa, pixmap);
+
return TRUE;
out_no_damage:
@@ -1226,10 +1269,14 @@ vmwgfx_operation_complete(struct saa_driver *driver,
* executed at glxWaitX(). Currently glxWaitX() is broken, so
* we flush immediately, unless we're VT-switched away, in which
* case a flush would deadlock in the kernel.
+ *
+ * For pixmaps for which vpix->hw_is_hosted is true, we can explicitly
+ * inform the compositor when contents has changed, so for those pixmaps
+ * we defer the upload until the compositor is informed, by putting
+ * them on the sync_x_list. Note that hw_is_dri2_fronts take precedence.
*/
-
- if (vpix->hw && vpix->hw_is_dri2_fronts) {
- if (pScrn->vtSema &&
+ if (vpix->hw && (vpix->hw_is_dri2_fronts || vpix->hw_is_hosted)) {
+ if (pScrn->vtSema && vpix->hw_is_dri2_fronts &&
vmwgfx_upload_to_hw(driver, pixmap, &spix->dirty_shadow)) {
REGION_EMPTY(vsaa->pScreen, &spix->dirty_shadow);
@@ -1539,6 +1586,7 @@ vmwgfx_saa_set_master(ScreenPtr pScreen)
struct vmwgfx_saa *vsaa = to_vmwgfx_saa(saa_get_driver(pScreen));
vsaa->is_master = TRUE;
+ vmwgfx_flush_dri2(pScreen);
}
void
@@ -1563,3 +1611,134 @@ vmwgfx_saa_drop_master(ScreenPtr pScreen)
vsaa->is_master = FALSE;
}
+
+/*
+ * *************************************************************************
+ * Helpers for hosted.
+ */
+
+#if (XA_TRACKER_VERSION_MAJOR >= 2)
+
+/**
+ * vmwgfx_saa_copy_to_surface - Copy Drawable contents to an external surface.
+ *
+ * @pDraw: Pointer to source drawable.
+ * @surface_fd: Prime file descriptor of external surface to copy to.
+ * @dst_box: BoxRec describing the destination bounding box.
+ * @region: Region of drawable to copy. Note: The code assumes that the
+ * region is relative to the drawable origin, not the underlying pixmap
+ * origin.
+ *
+ * Copies the contents (both software- and accelerated contents) to an
+ * external surface.
+ */
+Bool
+vmwgfx_saa_copy_to_surface(DrawablePtr pDraw, uint32_t surface_fd,
+ const BoxRec *dst_box, RegionPtr region)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ struct vmwgfx_saa *vsaa = to_vmwgfx_saa(saa_get_driver(pScreen));
+ PixmapPtr src;
+ struct saa_pixmap *spix;
+ struct vmwgfx_saa_pixmap *vpix;
+ const BoxRec *box;
+ int n;
+ int sx, sy, dx, dy;
+ struct xa_surface *dst;
+ uint32_t handle;
+ Bool ret = TRUE;
+ RegionRec intersection;
+ RegionPtr copy_region = region;
+
+ if (vmwgfx_prime_fd_to_handle(vsaa->drm_fd, surface_fd, &handle) < 0)
+ return FALSE;
Reply to: