svga: Keep tight control of texture handle ownership.
authorJosé Fonseca <jfonseca@vmware.com>
Fri, 11 Dec 2009 12:29:02 +0000 (12:29 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 11 Dec 2009 12:29:02 +0000 (12:29 +0000)
The texture owns the surface handle. All derivatives need to keep
a reference to texture.

This fixes several assertions failures starting up Jedi Knight 2.

Should cause no change for DRM surface sharing -- reference count still
done as before there.

src/gallium/drivers/svga/svga_screen_texture.c
src/gallium/drivers/svga/svga_screen_texture.h

index ed83ba48f09e7c587bd7dc0fa806fc6c132d193f..1eb03db2806b182ce1c8f3e4b2a9819f931f3546 100644 (file)
@@ -657,13 +657,11 @@ svga_get_tex_surface(struct pipe_screen *screen,
       s->real_level = 0;
       s->real_zslice = 0;
    } else {
-      struct svga_winsys_screen *sws = svga_winsys_screen(screen);
-
       SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
                pt, level, face, zslice, s);
 
       memset(&s->key, 0, sizeof s->key);
-      sws->surface_reference(sws, &s->handle, tex->handle);
+      s->handle = tex->handle;
       s->real_face = face;
       s->real_level = level;
       s->real_zslice = zslice;
@@ -677,11 +675,14 @@ static void
 svga_tex_surface_destroy(struct pipe_surface *surf)
 {
    struct svga_surface *s = svga_surface(surf);
+   struct svga_texture *t = svga_texture(surf->texture);
    struct svga_screen *ss = svga_screen(surf->texture->screen);
 
-   SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
-   assert(s->key.cachable == 0);
-   svga_screen_surface_destroy(ss, &s->key, &s->handle);
+   if(s->handle != t->handle) {
+      SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
+      svga_screen_surface_destroy(ss, &s->key, &s->handle);
+   }
+
    pipe_texture_reference(&surf->texture, NULL);
    FREE(surf);
 }
@@ -910,7 +911,6 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
                           unsigned min_lod, unsigned max_lod)
 {
    struct svga_screen *ss = svga_screen(pt->screen);
-   struct svga_winsys_screen *sws = ss->sws;
    struct svga_texture *tex = svga_texture(pt); 
    struct svga_sampler_view *sv = NULL;
    SVGA3dSurfaceFormat format = svga_translate_format(pt->format);
@@ -961,7 +961,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
 
    sv = CALLOC_STRUCT(svga_sampler_view);
    pipe_reference_init(&sv->reference, 1);
-   sv->texture = tex;
+   pipe_texture_reference(&sv->texture, pt);
    sv->min_lod = min_lod;
    sv->max_lod = max_lod;
 
@@ -976,7 +976,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
                pt->depth[0],
                pt->last_level);
       sv->key.cachable = 0;
-      sws->surface_reference(sws, &sv->handle, tex->handle);
+      sv->handle = tex->handle;
       return sv;
    }
 
@@ -999,7 +999,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
    if (!sv->handle) {
       assert(0);
       sv->key.cachable = 0;
-      sws->surface_reference(sws, &sv->handle, tex->handle);
+      sv->handle = tex->handle;
       return sv;
    }
 
@@ -1013,14 +1013,14 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
 void
 svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v)
 {
-   struct svga_texture *tex = v->texture;
+   struct svga_texture *tex = svga_texture(v->texture);
    unsigned numFaces;
    unsigned age = 0;
    int i, k;
 
    assert(svga);
 
-   if (v->handle == v->texture->handle)
+   if (v->handle == tex->handle)
       return;
 
    age = tex->age;
@@ -1048,11 +1048,14 @@ svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *
 void
 svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
 {
-   struct svga_screen *ss = svga_screen(v->texture->base.screen);
-
-   SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
-   svga_screen_surface_destroy(ss, &v->key, &v->handle);
+   struct svga_texture *tex = svga_texture(v->texture);
 
+   if(v->handle != tex->handle) {
+      struct svga_screen *ss = svga_screen(v->texture->screen);
+      SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
+      svga_screen_surface_destroy(ss, &v->key, &v->handle);
+   }
+   pipe_texture_reference(&v->texture, NULL);
    FREE(v);
 }
 
index 1cc4063e6536d31c98d1ab2a1a13cde58da4e492..8cfdfea6937da2ce0db2d7d1c9aa5cf205fe471b 100644 (file)
@@ -61,7 +61,7 @@ struct svga_sampler_view
 {
    struct pipe_reference reference;
 
-   struct svga_texture *texture;
+   struct pipe_texture *texture;
 
    int min_lod;
    int max_lod;
@@ -94,6 +94,13 @@ struct svga_texture
     * operation.
     */
    struct svga_host_surface_cache_key key;
+
+   /**
+    * Handle for the host side surface.
+    *
+    * This handle is owned by this texture. Views should hold on to a reference
+    * to this texture and never destroy this handle directly.
+    */
    struct svga_winsys_surface *handle;
 };