Mesa (mesa_7_7_branch): svga: Do a more propper creation of textures from handles

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Wed Jan 20 00:02:58 UTC 2010


Module: Mesa
Branch: mesa_7_7_branch
Commit: bea9ed4dc6abbcf2b95f5f55554800d4f41da47a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bea9ed4dc6abbcf2b95f5f55554800d4f41da47a

Author: Jakob Bornecrantz <jakob at vmware.com>
Date:   Tue Jan 19 22:26:01 2010 +0100

svga: Do a more propper creation of textures from handles

---

 src/gallium/drivers/svga/svga_screen_texture.c     |   68 +++++++++++++++++++-
 src/gallium/drivers/svga/svga_winsys.h             |    6 ++
 .../winsys/drm/vmware/core/vmw_screen_dri.c        |   68 ++++++--------------
 3 files changed, 90 insertions(+), 52 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index 1eb03db..9ad4eda 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -308,11 +308,19 @@ svga_texture_create(struct pipe_screen *screen,
       tex->key.numFaces = 1;
    }
 
+   tex->key.cachable = 1;
+
    if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
       tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
 
-   if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+   if(templat->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+      tex->key.cachable = 0;
+   }
+
+   if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
       tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
+      tex->key.cachable = 0;
+   }
    
    /* 
     * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
@@ -335,8 +343,6 @@ svga_texture_create(struct pipe_screen *screen,
    if(tex->key.format == SVGA3D_FORMAT_INVALID)
       goto error2;
 
-   tex->key.cachable = 1;
-   
    SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
    tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
    if (tex->handle)
@@ -418,6 +424,62 @@ svga_texture_blanket(struct pipe_screen * screen,
 }
 
 
+struct pipe_texture *
+svga_screen_texture_wrap_surface(struct pipe_screen *screen,
+				 struct pipe_texture *base,
+				 enum SVGA3dSurfaceFormat format,
+				 struct svga_winsys_surface *srf)
+{
+   struct svga_texture *tex;
+   assert(screen);
+
+   /* Only supports one type */
+   if (base->target != PIPE_TEXTURE_2D ||
+       base->last_level != 0 ||
+       base->depth[0] != 1) {
+      return NULL;
+   }
+
+   if (!srf)
+      return NULL;
+
+   if (svga_translate_format(base->format) != format) {
+      unsigned f1 = svga_translate_format(base->format);
+      unsigned f2 = format;
+
+      /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
+      if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
+              (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
+              (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
+         debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
+         return NULL;
+      }
+   }
+
+   tex = CALLOC_STRUCT(svga_texture);
+   if (!tex)
+      return NULL;
+
+   tex->base = *base;
+   
+
+   if (format == 1)
+      tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM;
+   else if (format == 2)
+      tex->base.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+   pipe_reference_init(&tex->base.reference, 1);
+   tex->base.screen = screen;
+
+   SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf);
+
+   tex->key.cachable = 0;
+   tex->handle = srf;
+
+   return &tex->base;
+}
+
+
 static void
 svga_texture_destroy(struct pipe_texture *pt)
 {
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index 59f299c..27b99fe 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -296,4 +296,10 @@ svga_screen_buffer_from_texture(struct pipe_texture *texture,
 				struct pipe_buffer **buffer,
 				unsigned *stride);
 
+struct pipe_texture *
+svga_screen_texture_wrap_surface(struct pipe_screen *screen,
+				 struct pipe_texture *base,
+				 enum SVGA3dSurfaceFormat format,
+				 struct svga_winsys_surface *srf);
+
 #endif /* SVGA_WINSYS_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
index dbbe170..60491cb 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
@@ -237,22 +237,19 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
    vmw_svga_winsys_surface_reference(&vsrf, NULL);
 }
 
-/**
- * FIXME: We'd probably want to cache these buffers in the
- * screen, based on handle.
- */
-
-static struct pipe_buffer *
-vmw_drm_buffer_from_handle(struct drm_api *drm_api,
-                           struct pipe_screen *screen,
-			   const char *name,
-			   unsigned handle)
+static struct pipe_texture *
+vmw_drm_texture_from_handle(struct drm_api *drm_api,
+			    struct pipe_screen *screen,
+			    struct pipe_texture *templat,
+			    const char *name,
+			    unsigned stride,
+			    unsigned handle)
 {
     struct vmw_svga_winsys_surface *vsrf;
     struct svga_winsys_surface *ssrf;
     struct vmw_winsys_screen *vws =
 	vmw_winsys_screen(svga_winsys_screen(screen));
-    struct pipe_buffer *buf;
+    struct pipe_texture *tex;
     union drm_vmw_surface_reference_arg arg;
     struct drm_vmw_surface_arg *req = &arg.req;
     struct drm_vmw_surface_create_req *rep = &arg.rep;
@@ -299,43 +296,28 @@ vmw_drm_buffer_from_handle(struct drm_api *drm_api,
 
     pipe_reference_init(&vsrf->refcnt, 1);
     p_atomic_set(&vsrf->validated, 0);
+    vsrf->screen = vws;
     vsrf->sid = handle;
     ssrf = svga_winsys_surface(vsrf);
-    buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf);
-    if (!buf)
+    tex = svga_screen_texture_wrap_surface(screen, templat, rep->format, ssrf);
+    if (!tex)
 	vmw_svga_winsys_surface_reference(&vsrf, NULL);
 
-    return buf;
+    return tex;
   out_mip:
     vmw_ioctl_surface_destroy(vws, handle);
     return NULL;
 }
 
-static struct pipe_texture *
-vmw_drm_texture_from_handle(struct drm_api *drm_api,
-			    struct pipe_screen *screen,
-			    struct pipe_texture *templat,
-			    const char *name,
-			    unsigned stride,
-			    unsigned handle)
-{
-    struct pipe_buffer *buffer;
-    buffer = vmw_drm_buffer_from_handle(drm_api, screen, name, handle);
-
-    if (!buffer)
-	return NULL;
-
-    return screen->texture_blanket(screen, templat, &stride, buffer);
-}
-
 static boolean
-vmw_drm_handle_from_buffer(struct drm_api *drm_api,
+vmw_drm_handle_from_texture(struct drm_api *drm_api,
                            struct pipe_screen *screen,
-			   struct pipe_buffer *buffer,
+			   struct pipe_texture *texture,
+			   unsigned *stride,
 			   unsigned *handle)
 {
     struct svga_winsys_surface *surface =
-	svga_screen_buffer_get_winsys_surface(buffer);
+	svga_screen_texture_get_winsys_surface(texture);
     struct vmw_svga_winsys_surface *vsrf;
 
     if (!surface)
@@ -343,25 +325,13 @@ vmw_drm_handle_from_buffer(struct drm_api *drm_api,
 
     vsrf = vmw_svga_winsys_surface(surface);
     *handle = vsrf->sid;
+    *stride = pf_get_nblocksx(&texture->block, texture->width[0]) *
+	texture->block.size;
+
     vmw_svga_winsys_surface_reference(&vsrf, NULL);
     return TRUE;
 }
 
-static boolean
-vmw_drm_handle_from_texture(struct drm_api *drm_api,
-			    struct pipe_screen *screen,
-			    struct pipe_texture *texture,
-			    unsigned *stride,
-			    unsigned *handle)
-{
-    struct pipe_buffer *buffer;
-
-    if (!svga_screen_buffer_from_texture(texture, &buffer, stride))
-	return FALSE;
-
-    return vmw_drm_handle_from_buffer(drm_api, screen, buffer, handle);
-}
-
 static struct pipe_context*
 vmw_drm_create_context(struct drm_api *drm_api,
                        struct pipe_screen *screen)




More information about the mesa-commit mailing list