[Mesa-dev] [PATCH 19/19] svga/winsys: Propagate surface shared information to the winsys

Brian Paul brianp at vmware.com
Thu Feb 13 17:21:11 PST 2014


From: Thomas Hellstrom <thellstrom at vmware.com>

The linux winsys needs to know whether a surface is shared.
For guest-backed surfaces we need this information to avoid allocating a
mob out of the mob cache for shared surfaces, but instead allocate a shared
mob, that is never put in the mob cache, from the kernel.

Also previously, all surfaces were given the "shareable" attribute when
allocated from the kernel. This is too permissive for client-local surfaces.
Now that we have the needed info, only set the "shareable" attribute if the
client indicates that it needs to share the surface.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob at vmware.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
Cc: "10.1" <mesa-stable at lists.freedesktop.org>
---
 src/gallium/drivers/svga/svga_screen_cache.c   |    2 ++
 src/gallium/drivers/svga/svga_winsys.h         |   15 ++++++++++++--
 src/gallium/winsys/svga/drm/vmw_screen.h       |   12 ++++++-----
 src/gallium/winsys/svga/drm/vmw_screen_ioctl.c |   15 ++++++++------
 src/gallium/winsys/svga/drm/vmw_screen_svga.c  |   26 ++++++++++++------------
 5 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_screen_cache.c b/src/gallium/drivers/svga/svga_screen_cache.c
index 71dc72e..307af1b 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.c
+++ b/src/gallium/drivers/svga/svga_screen_cache.c
@@ -449,6 +449,8 @@ svga_screen_surface_create(struct svga_screen *svgascreen,
       handle = sws->surface_create(sws,
                                    key->flags,
                                    key->format,
+                                   key->cachable ?
+                                   0 : SVGA_SURFACE_USAGE_SHARED,
                                    key->size,
                                    key->numFaces,
                                    key->numMipLevels);
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index f1f9237..879321f 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -79,6 +79,7 @@ struct winsys_handle;
 #define SVGA_FENCE_FLAG_EXEC      (1 << 0)
 #define SVGA_FENCE_FLAG_QUERY     (1 << 1)
 
+#define SVGA_SURFACE_USAGE_SHARED (1 << 0)
 
 /** Opaque surface handle */
 struct svga_winsys_surface;
@@ -252,8 +253,17 @@ struct svga_winsys_screen
    
    
    /**
-    * This creates a "surface" object in the SVGA3D device,
-    * and returns the surface ID (sid). Surfaces are generic
+    * This creates a "surface" object in the SVGA3D device.
+    *
+    * \param sws Pointer to an svga_winsys_context
+    * \param flags Device surface create flags
+    * \param format Format Device surface format
+    * \param usage Winsys usage: bitmask of SVGA_SURFACE_USAGE_x flags
+    * \param size Surface size given in device format
+    * \param numFaces Number of faces of the surface (1 or 6)
+    * \param numMipLevels Number of mipmap levels for each face
+    *
+    * Returns the surface ID (sid). Surfaces are generic
     * containers for host VRAM objects like textures, vertex
     * buffers, and depth/stencil buffers.
     *
@@ -284,6 +294,7 @@ struct svga_winsys_screen
    (*surface_create)(struct svga_winsys_screen *sws,
                      SVGA3dSurfaceFlags flags,
                      SVGA3dSurfaceFormat format,
+                     unsigned usage,
                      SVGA3dSize size,
                      uint32 numFaces,
                      uint32 numMipLevels);
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index f9da369..b68bf43 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -119,15 +119,17 @@ vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws,
 
 uint32
 vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
-                              SVGA3dSurfaceFlags flags,
-                              SVGA3dSurfaceFormat format,
-                              SVGA3dSize size,
-                              uint32 numFaces,
-                              uint32 numMipLevels);
+                         SVGA3dSurfaceFlags flags,
+                         SVGA3dSurfaceFormat format,
+                         unsigned usage,
+                         SVGA3dSize size,
+                         uint32 numFaces,
+                         uint32 numMipLevels);
 uint32
 vmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
 			    SVGA3dSurfaceFlags flags,
 			    SVGA3dSurfaceFormat format,
+                            unsigned usage,
 			    SVGA3dSize size,
 			    uint32 numFaces,
 			    uint32 numMipLevels,
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 501c047..b7bedb1 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -109,10 +109,11 @@ vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
 
 uint32
 vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
-			      SVGA3dSurfaceFlags flags,
-			      SVGA3dSurfaceFormat format,
-			      SVGA3dSize size,
-			      uint32_t numFaces, uint32_t numMipLevels)
+                         SVGA3dSurfaceFlags flags,
+                         SVGA3dSurfaceFormat format,
+                         unsigned usage,
+                         SVGA3dSize size,
+                         uint32_t numFaces, uint32_t numMipLevels)
 {
    union drm_vmw_surface_create_arg s_arg;
    struct drm_vmw_surface_create_req *req = &s_arg.req;
@@ -139,7 +140,7 @@ vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
       req->scanout = false;
    }
    req->format = (uint32_t) format;
-   req->shareable = 1;
+   req->shareable = !!(usage & SVGA_SURFACE_USAGE_SHARED);
 
    assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
 	  DRM_VMW_MAX_MIP_LEVELS);
@@ -180,6 +181,7 @@ uint32
 vmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
 			    SVGA3dSurfaceFlags flags,
 			    SVGA3dSurfaceFormat format,
+                            unsigned usage,
 			    SVGA3dSize size,
 			    uint32_t numFaces,
 			    uint32_t numMipLevels,
@@ -208,7 +210,8 @@ vmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
       req->svga3d_flags = (uint32_t) flags;
    }
    req->format = (uint32_t) format;
-   req->drm_surface_flags |= drm_vmw_surface_flag_shareable; 
+   if (usage & SVGA_SURFACE_USAGE_SHARED)
+      req->drm_surface_flags |= drm_vmw_surface_flag_shareable;
    req->drm_surface_flags |= drm_vmw_surface_flag_create_buffer; 
 
    assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
index bfba203..6d592f2 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
@@ -135,6 +135,7 @@ static struct svga_winsys_surface *
 vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
                                SVGA3dSurfaceFlags flags,
                                SVGA3dSurfaceFormat format,
+                               unsigned usage,
                                SVGA3dSize size,
                                uint32 numFaces,
                                uint32 numMipLevels)
@@ -142,7 +143,7 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
    struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
    struct vmw_svga_winsys_surface *surface;
    struct vmw_buffer_desc desc;
-   struct pb_manager *provider = vws->pools.mob_fenced;
+   struct pb_manager *provider;
    uint32_t buffer_size;
 
 
@@ -155,6 +156,8 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
    p_atomic_set(&surface->validated, 0);
    surface->screen = vws;
    pipe_mutex_init(surface->mutex);
+   surface->shared = !!(usage & SVGA_SURFACE_USAGE_SHARED);
+   provider = (surface->shared) ? vws->pools.gmr : vws->pools.mob_fenced;
 
    /*
     * Used for the backing buffer GB surfaces, and to approximate
@@ -169,7 +172,7 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
        * buffer out of the buffer cache. Otherwise, let the kernel allocate
        * a suitable buffer for us.
        */
-      if (buffer_size < VMW_TRY_CACHED_SIZE) {
+      if (buffer_size < VMW_TRY_CACHED_SIZE && !surface->shared) {
          struct pb_buffer *pb_buf;
 
          surface->size = buffer_size;
@@ -181,10 +184,9 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
             assert(0);
       }
 
-      surface->sid = vmw_ioctl_gb_surface_create(vws,
-						 flags, format, size,
-						 numFaces, numMipLevels,
-                                                 ptr.gmrId,
+      surface->sid = vmw_ioctl_gb_surface_create(vws, flags, format, usage,
+                                                 size, numFaces,
+                                                 numMipLevels, ptr.gmrId,
                                                  surface->buf ? NULL :
 						 &desc.region);
 
@@ -198,10 +200,9 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
           */
          vmw_svga_winsys_buffer_destroy(sws, surface->buf);
          surface->buf = NULL;
-         surface->sid = vmw_ioctl_gb_surface_create(vws,
-                                                    flags, format, size,
-                                                    numFaces, numMipLevels,
-                                                    0,
+         surface->sid = vmw_ioctl_gb_surface_create(vws, flags, format, usage,
+                                                    size, numFaces,
+                                                    numMipLevels, 0,
                                                     &desc.region);
          if (surface->sid == SVGA3D_INVALID_ID)
             goto no_sid;
@@ -227,9 +228,8 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
          }
       }
    } else {
-      surface->sid = vmw_ioctl_surface_create(vws,
-                                              flags, format, size,
-                                              numFaces, numMipLevels);
+      surface->sid = vmw_ioctl_surface_create(vws, flags, format, usage,
+                                              size, numFaces, numMipLevels);
       if(surface->sid == SVGA3D_INVALID_ID)
          goto no_sid;
 
-- 
1.7.10.4



More information about the mesa-dev mailing list