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 <thellst...@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 <thellst...@vmware.com> Reviewed-by: Jakob Bornecrantz <ja...@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 <thellst...@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 <thellst...@vmware.com> Reviewed-by: Jakob Bornecrantz <ja...@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 <thellst...@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 <thellst...@vmware.com> Reviewed-by: Jakob Bornecrantz <ja...@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 <thellst...@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 <thellst...@vmware.com> Reviewed-by: Brian Paul <bri...@vmware.com> Reviewed-by: Jakob Bornecrantz <ja...@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 <thellst...@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 <thellst...@vmware.com> Reviewed-by: Brian Paul <bri...@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 <thellst...@vmware.com> Date: Mon Dec 16 06:21:09 2013 -0800 vmwgfx: Add support for XWayland Signed-off-by: Thomas Hellstrom <thellst...@vmware.com> Reviewed-by: Brian Paul <bri...@vmware.com> Reviewed-by: Jakob Bornecrantz <ja...@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 <thellst...@vmware.com> + * Author: Jakob Bornecrantz <ja...@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 <thellst...@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 <thellst...@vmware.com> Reviewed-by: Brian Paul <bri...@vmware.com> Reviewed-by: Jakob Bornecrantz <ja...@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 <thellst...@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; -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/e1wxxj0-0000gg...@moszumanska.debian.org