softpipe: reformatting, clean-ups, comments
[mesa.git] / src / gallium / drivers / softpipe / sp_texture.c
index 142ce230fc0e4555681570b15eb9a9139d9b916c..9a3f8f3d53b0d6d0fbad4f0fe4ac3d491f522cbe 100644 (file)
 #include "sp_texture.h"
 #include "sp_tile_cache.h"
 #include "sp_screen.h"
+#include "sp_winsys.h"
 
 
 /* Simple, maximally packed layout.
  */
 
-static unsigned minify( unsigned d )
-{
-   return MAX2(1, d>>1);
-}
 
-
-/* Conventional allocation path for non-display textures:
+/**
+ * Conventional allocation path for non-display textures:
  */
 static boolean
 softpipe_texture_layout(struct pipe_screen *screen,
                         struct softpipe_texture * spt)
 {
-   struct pipe_winsys *ws = screen->winsys;
    struct pipe_texture *pt = &spt->base;
    unsigned level;
    unsigned width = pt->width[0];
@@ -87,38 +83,40 @@ softpipe_texture_layout(struct pipe_screen *screen,
       depth = minify(depth);
    }
 
-   spt->buffer = ws->buffer_create(ws, 32,
-                                   PIPE_BUFFER_USAGE_PIXEL,
-                                   buffer_size);
+   spt->buffer = screen->buffer_create(screen, 32,
+                                       PIPE_BUFFER_USAGE_PIXEL,
+                                       buffer_size);
 
    return spt->buffer != NULL;
 }
 
+
+/**
+ * Texture layout for simple color buffers.
+ */
 static boolean
 softpipe_displaytarget_layout(struct pipe_screen *screen,
                               struct softpipe_texture * spt)
 {
-   struct pipe_winsys *ws = screen->winsys;
    unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
                      PIPE_BUFFER_USAGE_GPU_READ_WRITE);
+   unsigned tex_usage = spt->base.tex_usage;
 
    spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);  
    spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);  
 
-   spt->buffer = ws->surface_buffer_create( ws, 
-                                            spt->base.width[0], 
-                                            spt->base.height[0],
-                                            spt->base.format,
-                                            usage,
-                                            &spt->stride[0]);
+   spt->buffer = screen->surface_buffer_create( screen, 
+                                                spt->base.width[0], 
+                                                spt->base.height[0],
+                                                spt->base.format,
+                                                usage,
+                                                tex_usage,
+                                                &spt->stride[0]);
 
    return spt->buffer != NULL;
 }
 
 
-
-
-
 static struct pipe_texture *
 softpipe_texture_create(struct pipe_screen *screen,
                         const struct pipe_texture *templat)
@@ -128,10 +126,11 @@ softpipe_texture_create(struct pipe_screen *screen,
       return NULL;
 
    spt->base = *templat;
-   spt->base.refcount = 1;
+   pipe_reference_init(&spt->base.reference, 1);
    spt->base.screen = screen;
 
-   if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+   if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+                              PIPE_TEXTURE_USAGE_PRIMARY)) {
       if (!softpipe_displaytarget_layout(screen, spt))
          goto fail;
    }
@@ -140,7 +139,6 @@ softpipe_texture_create(struct pipe_screen *screen,
          goto fail;
    }
     
-   assert(spt->base.refcount == 1);
    return &spt->base;
 
  fail:
@@ -170,32 +168,25 @@ softpipe_texture_blanket(struct pipe_screen * screen,
       return NULL;
 
    spt->base = *base;
-   spt->base.refcount = 1;
+   pipe_reference_init(&spt->base.reference, 1);
    spt->base.screen = screen;
    spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);  
    spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);  
    spt->stride[0] = stride[0];
 
-   pipe_buffer_reference(screen, &spt->buffer, buffer);
+   pipe_buffer_reference(&spt->buffer, buffer);
 
    return &spt->base;
 }
 
 
 static void
-softpipe_texture_release(struct pipe_screen *screen,
-                         struct pipe_texture **pt)
+softpipe_texture_destroy(struct pipe_texture *pt)
 {
-   if (!*pt)
-      return;
-
-   if (--(*pt)->refcount <= 0) {
-      struct softpipe_texture *spt = softpipe_texture(*pt);
+   struct softpipe_texture *spt = softpipe_texture(pt);
 
-      pipe_buffer_reference(screen, &spt->buffer, NULL);
-      FREE(spt);
-   }
-   *pt = NULL;
+   pipe_buffer_reference(&spt->buffer, NULL);
+   FREE(spt);
 }
 
 
@@ -212,7 +203,7 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
 
    ps = CALLOC_STRUCT(pipe_surface);
    if (ps) {
-      ps->refcount = 1;
+      pipe_reference_init(&ps->reference, 1);
       pipe_texture_reference(&ps->texture, pt);
       ps->format = pt->format;
       ps->width = pt->width[level];
@@ -233,12 +224,6 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
       if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
          ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
 
-      if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
-                       PIPE_BUFFER_USAGE_GPU_WRITE)) {
-         /* Mark the surface as dirty.  The tile cache will look for this. */
-         spt->modified = TRUE;
-      }
-
       ps->face = face;
       ps->level = level;
       ps->zslice = zslice;
@@ -259,20 +244,15 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
 
 
 static void 
-softpipe_tex_surface_release(struct pipe_screen *screen, 
-                             struct pipe_surface **s)
+softpipe_tex_surface_destroy(struct pipe_surface *surf)
 {
-   struct pipe_surface *surf = *s;
    /* Effectively do the texture_update work here - if texture images
     * needed post-processing to put them into hardware layout, this is
     * where it would happen.  For softpipe, nothing to do.
     */
    assert(surf->texture);
-   if (--surf->refcount == 0) {
-      pipe_texture_reference(&surf->texture, NULL);
-      FREE(surf);
-   }
-   *s = NULL;
+   pipe_texture_reference(&surf->texture, NULL);
+   FREE(surf);
 }
 
 
@@ -292,7 +272,6 @@ softpipe_get_tex_transfer(struct pipe_screen *screen,
    spt = CALLOC_STRUCT(softpipe_transfer);
    if (spt) {
       struct pipe_transfer *pt = &spt->base;
-      pt->refcount = 1;
       pipe_texture_reference(&pt->texture, texture);
       pt->format = texture->format;
       pt->block = texture->block;
@@ -327,20 +306,15 @@ softpipe_get_tex_transfer(struct pipe_screen *screen,
 
 
 static void 
-softpipe_tex_transfer_release(struct pipe_screen *screen, 
-                              struct pipe_transfer **t)
+softpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
 {
-   struct softpipe_transfer *transfer = softpipe_transfer(*t);
    /* Effectively do the texture_update work here - if texture images
     * needed post-processing to put them into hardware layout, this is
     * where it would happen.  For softpipe, nothing to do.
     */
-   assert (transfer->base.texture);
-   if (--transfer->base.refcount == 0) {
-      pipe_texture_reference(&transfer->base.texture, NULL);
-      FREE(transfer);
-   }
-   *t = NULL;
+   assert (transfer->texture);
+   pipe_texture_reference(&transfer->texture, NULL);
+   FREE(transfer);
 }
 
 
@@ -348,7 +322,7 @@ static void *
 softpipe_transfer_map( struct pipe_screen *screen,
                        struct pipe_transfer *transfer )
 {
-   ubyte *map;
+   ubyte *map, *xfer_map;
    struct softpipe_texture *spt;
    unsigned flags = 0;
 
@@ -370,23 +344,24 @@ softpipe_transfer_map( struct pipe_screen *screen,
    /* May want to different things here depending on read/write nature
     * of the map:
     */
-   if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) 
-   {
+   if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) {
       /* Do something to notify sharing contexts of a texture change.
        * In softpipe, that would mean flushing the texture cache.
        */
       softpipe_screen(screen)->timestamp++;
    }
-   
-   return map + softpipe_transfer(transfer)->offset +
+
+   xfer_map = map + softpipe_transfer(transfer)->offset +
       transfer->y / transfer->block.height * transfer->stride +
       transfer->x / transfer->block.width * transfer->block.size;
+   /*printf("map = %p  xfer map = %p\n", map, xfer_map);*/
+   return xfer_map;
 }
 
 
 static void
 softpipe_transfer_unmap(struct pipe_screen *screen,
-                       struct pipe_transfer *transfer)
+                        struct pipe_transfer *transfer)
 {
    struct softpipe_texture *spt;
 
@@ -394,6 +369,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
    spt = softpipe_texture(transfer->texture);
 
    pipe_buffer_unmap( screen, spt->buffer );
+
+   if (transfer->usage != PIPE_TRANSFER_READ) {
+      /* Mark the texture as dirty to expire the tile caches. */
+      spt->modified = TRUE;
+   }
 }
 
 
@@ -408,13 +388,32 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
 {
    screen->texture_create = softpipe_texture_create;
    screen->texture_blanket = softpipe_texture_blanket;
-   screen->texture_release = softpipe_texture_release;
+   screen->texture_destroy = softpipe_texture_destroy;
 
    screen->get_tex_surface = softpipe_get_tex_surface;
-   screen->tex_surface_release = softpipe_tex_surface_release;
+   screen->tex_surface_destroy = softpipe_tex_surface_destroy;
 
    screen->get_tex_transfer = softpipe_get_tex_transfer;
-   screen->tex_transfer_release = softpipe_tex_transfer_release;
+   screen->tex_transfer_destroy = softpipe_tex_transfer_destroy;
    screen->transfer_map = softpipe_transfer_map;
    screen->transfer_unmap = softpipe_transfer_unmap;
 }
+
+
+boolean
+softpipe_get_texture_buffer( struct pipe_texture *texture,
+                             struct pipe_buffer **buf,
+                             unsigned *stride )
+{
+   struct softpipe_texture *tex = (struct softpipe_texture *) texture;
+
+   if (!tex)
+      return FALSE;
+
+   pipe_buffer_reference(buf, tex->buffer);
+
+   if (stride)
+      *stride = tex->stride[0];
+
+   return TRUE;
+}