svga: Do a more propper creation of textures from handles
authorJakob Bornecrantz <jakob@vmware.com>
Tue, 19 Jan 2010 21:26:01 +0000 (22:26 +0100)
committerJakob Bornecrantz <jakob@vmware.com>
Tue, 19 Jan 2010 22:30:31 +0000 (23:30 +0100)
src/gallium/drivers/svga/svga_screen_texture.c
src/gallium/drivers/svga/svga_winsys.h
src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c

index 1eb03db2806b182ce1c8f3e4b2a9819f931f3546..9ad4edafef20c9c2604d77021ceddd7ecea00c80 100644 (file)
@@ -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)
 {
index 59f299c185865fc21fd25e3a8d8ca5aaf6ecaa95..27b99fe4c102f715e0f88e8bf03dbcd9d7d2b229 100644 (file)
@@ -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_ */
index dbbe1701f190152af3a4fafbc90c8f154df890c6..60491cb519f03aeef0b16668b66fb5bc3160defe 100644 (file)
@@ -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)