Hide texture layout details from the state tracker.
authorMichel Dänzer <michel@tungstengraphics.com>
Fri, 30 Nov 2007 19:48:03 +0000 (20:48 +0100)
committerMichel Dänzer <michel@tungstengraphics.com>
Thu, 6 Dec 2007 10:18:11 +0000 (11:18 +0100)
pipe->get_tex_surface() has to be used for access to texture image data.

46 files changed:
src/mesa/drivers/dri/intel_winsys/intel_screen.c
src/mesa/pipe/failover/fo_context.c
src/mesa/pipe/failover/fo_context.h
src/mesa/pipe/failover/fo_state.c
src/mesa/pipe/i915simple/Makefile
src/mesa/pipe/i915simple/i915_context.c
src/mesa/pipe/i915simple/i915_context.h
src/mesa/pipe/i915simple/i915_state.c
src/mesa/pipe/i915simple/i915_state_sampler.c
src/mesa/pipe/i915simple/i915_surface.c
src/mesa/pipe/i915simple/i915_tex_layout.c [deleted file]
src/mesa/pipe/i915simple/i915_tex_layout.h [deleted file]
src/mesa/pipe/i915simple/i915_texture.c [new file with mode: 0644]
src/mesa/pipe/i915simple/i915_texture.h [new file with mode: 0644]
src/mesa/pipe/llvm/llvm_entry.c
src/mesa/pipe/p_context.h
src/mesa/pipe/p_inlines.h
src/mesa/pipe/p_state.h
src/mesa/pipe/softpipe/Makefile
src/mesa/pipe/softpipe/sp_context.c
src/mesa/pipe/softpipe/sp_context.h
src/mesa/pipe/softpipe/sp_quad_fs.c
src/mesa/pipe/softpipe/sp_state.h
src/mesa/pipe/softpipe/sp_state_fs.c
src/mesa/pipe/softpipe/sp_state_sampler.c
src/mesa/pipe/softpipe/sp_surface.c
src/mesa/pipe/softpipe/sp_surface.h
src/mesa/pipe/softpipe/sp_tex_layout.c [deleted file]
src/mesa/pipe/softpipe/sp_tex_layout.h [deleted file]
src/mesa/pipe/softpipe/sp_tex_sample.c
src/mesa/pipe/softpipe/sp_texture.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_texture.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_tile_cache.c
src/mesa/pipe/softpipe/sp_tile_cache.h
src/mesa/pipe/tgsi/exec/tgsi_exec.h
src/mesa/sources
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_cb_texture.h
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_mipmap_tree.c [deleted file]
src/mesa/state_tracker/st_mipmap_tree.h [deleted file]
src/mesa/state_tracker/st_texture.c [new file with mode: 0644]
src/mesa/state_tracker/st_texture.h [new file with mode: 0644]

index 01460e5be3c1f0229e548a2aff9b86e657467b75..1b520f71353769c257fac7682032f85756e8c229 100644 (file)
@@ -328,8 +328,8 @@ intelSetTexOffset(__DRIcontext *pDRICtx, int texname,
    if (!stObj)
       return;
 
-   if (stObj->mt)
-      st_miptree_release(intel->st->pipe, &stObj->mt);
+   if (stObj->pt)
+      st->pipe->texture_release(intel->st->pipe, &stObj->pt);
 
    stObj->imageOverride = GL_TRUE;
    stObj->depthOverride = depth;
index 0cc9cab408c99003d4b4babce268449067d895ff..a25563d4511cc43cfb1feeb63d11c3447b1e2bde 100644 (file)
@@ -145,7 +145,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
    failover->pipe.surface_data = hw->surface_data;
    failover->pipe.surface_copy = hw->surface_copy;
    failover->pipe.surface_fill = hw->surface_fill;
-   failover->pipe.mipmap_tree_layout = hw->mipmap_tree_layout;
+   failover->pipe.texture_create = hw->texture_create;
+   failover->pipe.texture_release = hw->texture_release;
    failover->pipe.flush = hw->flush;
 
    failover->dirty = 0;
index 759b53ccbe4a7875f70323b3da0099472445aea7..7cf18c9ec19caed9404d8256f4f529476d8e4a12 100644 (file)
@@ -85,7 +85,7 @@ struct failover_context {
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    uint sampler_units[PIPE_MAX_SAMPLERS];
-   struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+   struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
    struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
index 2cd1a50b2034ddb2de104c44cb50509047d16818..fd6137ba6622912703624697c2a701863868c569 100644 (file)
@@ -402,7 +402,7 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)
 static void
 failover_set_texture_state(struct pipe_context *pipe,
                           unsigned unit,
-                           struct pipe_mipmap_tree *texture)
+                           struct pipe_texture *texture)
 {
    struct failover_context *failover = failover_context(pipe);
 
index 391a084915d7b78d558f967da117bed1a504e944..1223b386a3dbb2e0aa7877607e8b87cb5869b33b 100644 (file)
@@ -22,7 +22,7 @@ DRIVER_SOURCES = \
        i915_strings.c \
        i915_prim_emit.c \
        i915_prim_vbuf.c \
-       i915_tex_layout.c \
+       i915_texture.c \
        i915_fpc_emit.c \
        i915_fpc_translate.c \
        i915_surface.c 
index a0ed3032b12a654f07e913d216a38f6e16645181..94649231cf3bba22bfee3adce99c7e22c0db06c1 100644 (file)
@@ -29,7 +29,7 @@
 #include "i915_winsys.h"
 #include "i915_state.h"
 #include "i915_batch.h"
-#include "i915_tex_layout.h"
+#include "i915_texture.h"
 #include "i915_reg.h"
 
 #include "pipe/draw/draw_context.h"
@@ -357,11 +357,8 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys,
    i915->pci_id = pci_id;
    i915->flags.is_i945 = is_i945;
 
-   if (i915->flags.is_i945)
-      i915->pipe.mipmap_tree_layout = i945_miptree_layout;
-   else
-      i915->pipe.mipmap_tree_layout = i915_miptree_layout;
-
+   i915->pipe.texture_create = i915_texture_create;
+   i915->pipe.texture_release = i915_texture_release;
 
    i915->dirty = ~0;
    i915->hardware_dirty = ~0;
index ee430ebc9029a7abfb7a188a9463a308b8bb9dec..8ed3465be234f79be813901594d9a71cf635d3f7 100644 (file)
@@ -150,6 +150,34 @@ struct i915_alpha_test_state {
    unsigned LIS6;
 };
 
+struct i915_texture {
+   struct pipe_texture base;
+
+   /* Derived from the above:
+    */
+   unsigned pitch;
+   unsigned depth_pitch;          /* per-image on i945? */
+   unsigned total_height;
+
+   unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+
+   /* Explicitly store the offset of each image for each cube face or
+    * depth value.  Pretty much have to accept that hardware formats
+    * are going to be so diverse that there is no unified way to
+    * compute the offsets of depth/cube images within a mipmap level,
+    * so have to store them as a lookup table:
+    */
+   unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];   /**< array [depth] of offsets */
+
+   /* Includes image offset tables:
+    */
+   unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
+
+   /* The data is held here:
+    */
+   struct pipe_region *region;
+};
+
 struct i915_context
 {
    struct pipe_context pipe;
@@ -174,7 +202,7 @@ struct i915_context
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    uint sampler_units[PIPE_MAX_SAMPLERS];
-   struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+   struct i915_texture *texture[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
 
index 468d0ce91b133823408b20c36f8cfc0fcc986df0..038fd623ea15eaedf3e9980957d51a1121df017a 100644 (file)
@@ -525,11 +525,11 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
 
 static void i915_set_texture_state(struct pipe_context *pipe,
                                   unsigned unit,
-                                  struct pipe_mipmap_tree *texture)
+                                  struct pipe_texture *texture)
 {
    struct i915_context *i915 = i915_context(pipe);
 
-   i915->texture[unit] = texture;  /* ptr, not struct */
+   i915->texture[unit] = (struct i915_texture*)texture;  /* ptr, not struct */
 
    i915->dirty |= I915_NEW_TEXTURE;
 }
index 0991e6ac0d1f766ace2924bea96d7c5984ee61f7..1816d9abdb705ba9208fdd432fdfb049e2aec1a1 100644 (file)
 static void update_sampler(struct i915_context *i915,
                            uint unit,
                           const struct i915_sampler_state *sampler,
-                          const struct pipe_mipmap_tree *mt,
+                          const struct i915_texture *tex,
                           unsigned state[3] )
 {
+   const struct pipe_texture *pt = &tex->base;
+
    /* Need to do this after updating the maps, which call the
     * intel_finalize_mipmap_tree and hence can update firstLevel:
     */
@@ -56,8 +58,8 @@ static void update_sampler(struct i915_context *i915,
    state[1] = sampler->state[1];
    state[2] = sampler->state[2];
 
-   if (mt->format == PIPE_FORMAT_YCBCR ||
-       mt->format == PIPE_FORMAT_YCBCR_REV)
+   if (pt->format == PIPE_FORMAT_YCBCR ||
+       pt->format == PIPE_FORMAT_YCBCR_REV)
       state[0] |= SS2_COLORSPACE_CONVERSION;
 
    /* 3D textures don't seem to respect the border color.
@@ -75,7 +77,7 @@ static void update_sampler(struct i915_context *i915,
       const unsigned ws = sampler->templ->wrap_s;
       const unsigned wt = sampler->templ->wrap_t;
       const unsigned wr = sampler->templ->wrap_r;
-      if (mt->target == PIPE_TEXTURE_3D &&
+      if (pt->target == PIPE_TEXTURE_3D &&
           (sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
            sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) &&
           (ws == PIPE_TEX_WRAP_CLAMP ||
@@ -105,13 +107,13 @@ void i915_update_samplers( struct i915_context *i915 )
    i915->current.sampler_enable_flags = 0x0;
 
    for (unit = 0; unit < I915_TEX_UNITS; unit++) {
-      /* determine unit enable/disable by looking for a bound mipmap tree */
+      /* determine unit enable/disable by looking for a bound texture */
       /* could also examine the fragment program? */
       if (i915->texture[unit]) {
         update_sampler( i915,
                          unit,
                          i915->sampler[unit],       /* sampler state */
-                         i915->texture[unit],        /* mipmap tree */
+                         i915->texture[unit],        /* texture */
                         i915->current.sampler[unit] /* the result */
                          );
 
@@ -179,18 +181,19 @@ static void
 i915_update_texture(struct i915_context *i915, uint unit,
                     uint state[6])
 {
-   const struct pipe_mipmap_tree *mt = i915->texture[unit];
+   const struct i915_texture *tex = i915->texture[unit];
+   const struct pipe_texture *pt = &tex->base;
    uint format, pitch;
-   const uint width = mt->width0, height = mt->height0, depth = mt->depth0;
-   const uint num_levels = mt->last_level - mt->first_level;
+   const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
+   const uint num_levels = pt->last_level - pt->first_level;
 
-   assert(mt);
+   assert(tex);
    assert(width);
    assert(height);
    assert(depth);
 
-   format = translate_texture_format(mt->format);
-   pitch = mt->pitch * mt->cpp;
+   format = translate_texture_format(pt->format);
+   pitch = tex->pitch * pt->cpp;
 
    assert(format);
    assert(pitch);
@@ -217,7 +220,7 @@ i915_update_textures(struct i915_context *i915)
    uint unit;
 
    for (unit = 0; unit < I915_TEX_UNITS; unit++) {
-      /* determine unit enable/disable by looking for a bound mipmap tree */
+      /* determine unit enable/disable by looking for a bound texture */
       /* could also examine the fragment program? */
       if (i915->texture[unit]) {
          i915_update_texture(i915, unit, i915->current.texbuffer[unit]);
index e4a5de00d776049493ca51a81322dce4dbb4ada9..385202507db4cf32992d52785bbb3d3985071136 100644 (file)
@@ -187,34 +187,35 @@ i915_put_tile(struct pipe_context *pipe,
  */
 static struct pipe_surface *
 i915_get_tex_surface(struct pipe_context *pipe,
-                     struct pipe_mipmap_tree *mt,
+                     struct pipe_texture *pt,
                      unsigned face, unsigned level, unsigned zslice)
 {
+   struct i915_texture *tex = (struct i915_texture *)pt;
    struct pipe_surface *ps;
    unsigned offset;  /* in bytes */
 
-   offset = mt->level[level].level_offset;
+   offset = tex->level_offset[level];
 
-   if (mt->target == PIPE_TEXTURE_CUBE) {
-      offset += mt->level[level].image_offset[face] * mt->cpp;
+   if (pt->target == PIPE_TEXTURE_CUBE) {
+      offset += tex->image_offset[level][face] * pt->cpp;
    }
-   else if (mt->target == PIPE_TEXTURE_3D) {
-      offset += mt->level[level].image_offset[zslice] * mt->cpp;
+   else if (pt->target == PIPE_TEXTURE_3D) {
+      offset += tex->image_offset[level][zslice] * pt->cpp;
    }
    else {
       assert(face == 0);
       assert(zslice == 0);
    }
 
-   ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format);
+   ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format);
    if (ps) {
       assert(ps->format);
       assert(ps->refcount);
-      pipe_region_reference(&ps->region, mt->region);
-      ps->cpp = mt->cpp;
-      ps->width = mt->level[level].width;
-      ps->height = mt->level[level].height;
-      ps->pitch = mt->pitch;
+      pipe_region_reference(&ps->region, tex->region);
+      ps->cpp = pt->cpp;
+      ps->width = pt->width[level];
+      ps->height = pt->height[level];
+      ps->pitch = tex->pitch;
       ps->offset = offset;
    }
    return ps;
diff --git a/src/mesa/pipe/i915simple/i915_tex_layout.c b/src/mesa/pipe/i915simple/i915_tex_layout.c
deleted file mode 100644 (file)
index cb372a7..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Michel Dänzer <michel@tungstengraphics.com>
-  */
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-
-#include "i915_tex_layout.h"
-#include "i915_debug.h"
-
-
-static unsigned minify( unsigned d )
-{
-   return MAX2(1, d>>1);
-}
-
-static int align(int value, int alignment)
-{
-   return (value + alignment - 1) & ~(alignment - 1);
-}
-
-
-static void
-i915_miptree_set_level_info(struct pipe_mipmap_tree *mt,
-                             unsigned level,
-                             unsigned nr_images,
-                             unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
-{
-   assert(level < PIPE_MAX_TEXTURE_LEVELS);
-
-   mt->level[level].width = w;
-   mt->level[level].height = h;
-   mt->level[level].depth = d;
-   mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp;
-   mt->level[level].nr_images = nr_images;
-
-   /*
-   DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
-       level, w, h, d, x, y, mt->level[level].level_offset);
-   */
-
-   /* Not sure when this would happen, but anyway: 
-    */
-   if (mt->level[level].image_offset) {
-      FREE(mt->level[level].image_offset);
-      mt->level[level].image_offset = NULL;
-   }
-
-   assert(nr_images);
-   assert(!mt->level[level].image_offset);
-
-   mt->level[level].image_offset = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
-   mt->level[level].image_offset[0] = 0;
-}
-
-
-static void
-i915_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
-                               unsigned level, unsigned img, unsigned x, unsigned y)
-{
-   if (img == 0 && level == 0)
-      assert(x == 0 && y == 0);
-
-   assert(img < mt->level[level].nr_images);
-
-   mt->level[level].image_offset[img] = (x + y * mt->pitch);
-
-   /*
-   DBG("%s level %d img %d pos %d,%d image_offset %x\n",
-       __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]);
-   */
-}
-
-
-static void
-i945_miptree_layout_2d( struct pipe_mipmap_tree *mt )
-{
-   int align_h = 2, align_w = 4;
-   unsigned level;
-   unsigned x = 0;
-   unsigned y = 0;
-   unsigned width = mt->width0;
-   unsigned height = mt->height0;
-
-   mt->pitch = mt->width0;
-
-   /* May need to adjust pitch to accomodate the placement of
-    * the 2nd mipmap.  This occurs when the alignment
-    * constraints of mipmap placement push the right edge of the
-    * 2nd mipmap out past the width of its parent.
-    */
-   if (mt->first_level != mt->last_level) {
-      unsigned mip1_width = align(minify(mt->width0), align_w)
-                       + minify(minify(mt->width0));
-
-      if (mip1_width > mt->width0)
-        mt->pitch = mip1_width;
-   }
-
-   /* Pitch must be a whole number of dwords, even though we
-    * express it in texels.
-    */
-   mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
-   mt->total_height = 0;
-
-   for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
-      unsigned img_height;
-
-      i915_miptree_set_level_info(mt, level, 1, x, y, width, height, 1);
-
-      if (mt->compressed)
-        img_height = MAX2(1, height/4);
-      else
-        img_height = align(height, align_h);
-
-
-      /* Because the images are packed better, the final offset
-       * might not be the maximal one:
-       */
-      mt->total_height = MAX2(mt->total_height, y + img_height);
-
-      /* Layout_below: step right after second mipmap.
-       */
-      if (level == mt->first_level + 1) {
-        x += align(width, align_w);
-      }
-      else {
-        y += img_height;
-      }
-
-      width  = minify(width);
-      height = minify(height);
-   }
-}
-
-
-static const int initial_offsets[6][2] = {
-   {0, 0},
-   {0, 2},
-   {1, 0},
-   {1, 2},
-   {1, 1},
-   {1, 3}
-};
-
-static const int step_offsets[6][2] = {
-   {0, 2},
-   {0, 2},
-   {-1, 2},
-   {-1, 2},
-   {-1, 1},
-   {-1, 1}
-};
-
-
-boolean
-i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
-{
-   unsigned level;
-
-   switch (mt->target) {
-   case PIPE_TEXTURE_CUBE: {
-         const unsigned dim = mt->width0;
-         unsigned face;
-         unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
-
-         assert(lvlWidth == lvlHeight); /* cubemap images are square */
-
-         /* double pitch for cube layouts */
-         mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
-         mt->total_height = dim * 4;
-
-         for (level = mt->first_level; level <= mt->last_level; level++) {
-            i915_miptree_set_level_info(mt, level, 6,
-                                         0, 0,
-                                         /*OLD: mt->pitch, mt->total_height,*/
-                                         lvlWidth, lvlHeight,
-                                         1);
-            lvlWidth /= 2;
-            lvlHeight /= 2;
-         }
-
-         for (face = 0; face < 6; face++) {
-            unsigned x = initial_offsets[face][0] * dim;
-            unsigned y = initial_offsets[face][1] * dim;
-            unsigned d = dim;
-
-            for (level = mt->first_level; level <= mt->last_level; level++) {
-               i915_miptree_set_image_offset(mt, level, face, x, y);
-               d >>= 1;
-               x += step_offsets[face][0] * d;
-               y += step_offsets[face][1] * d;
-            }
-         }
-         break;
-      }
-   case PIPE_TEXTURE_3D:{
-         unsigned width = mt->width0;
-         unsigned height = mt->height0;
-         unsigned depth = mt->depth0;
-         unsigned stack_height = 0;
-
-         /* Calculate the size of a single slice. 
-          */
-         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
-
-         /* XXX: hardware expects/requires 9 levels at minimum.
-          */
-         for (level = mt->first_level; level <= MAX2(8, mt->last_level);
-              level++) {
-            i915_miptree_set_level_info(mt, level, depth, 0, mt->total_height,
-                                         width, height, depth);
-
-
-            stack_height += MAX2(2, height);
-
-            width = minify(width);
-            height = minify(height);
-            depth = minify(depth);
-         }
-
-         /* Fixup depth image_offsets: 
-          */
-         depth = mt->depth0;
-         for (level = mt->first_level; level <= mt->last_level; level++) {
-            unsigned i;
-            for (i = 0; i < depth; i++) 
-               i915_miptree_set_image_offset(mt, level, i,
-                                              0, i * stack_height);
-
-            depth = minify(depth);
-         }
-
-
-         /* Multiply slice size by texture depth for total size.  It's
-          * remarkable how wasteful of memory the i915 texture layouts
-          * are.  They are largely fixed in the i945.
-          */
-         mt->total_height = stack_height * mt->depth0;
-         break;
-      }
-
-   default:{
-         unsigned width = mt->width0;
-         unsigned height = mt->height0;
-        unsigned img_height;
-
-         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
-         mt->total_height = 0;
-
-         for (level = mt->first_level; level <= mt->last_level; level++) {
-            i915_miptree_set_level_info(mt, level, 1,
-                                         0, mt->total_height,
-                                         width, height, 1);
-
-            if (mt->compressed)
-               img_height = MAX2(1, height / 4);
-            else
-               img_height = (MAX2(2, height) + 1) & ~1;
-
-           mt->total_height += img_height;
-
-            width = minify(width);
-            height = minify(height);
-         }
-         break;
-      }
-   }
-   /*
-   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
-       mt->pitch,
-       mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
-   */
-
-   return TRUE;
-}
-
-
-boolean
-i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
-{
-   unsigned level;
-
-   switch (mt->target) {
-   case PIPE_TEXTURE_CUBE:{
-         const unsigned dim = mt->width0;
-         unsigned face;
-         unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
-
-         assert(lvlWidth == lvlHeight); /* cubemap images are square */
-
-         /* Depending on the size of the largest images, pitch can be
-          * determined either by the old-style packing of cubemap faces,
-          * or the final row of 4x4, 2x2 and 1x1 faces below this. 
-          */
-         if (dim > 32)
-            mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
-         else
-            mt->pitch = 14 * 8;
-
-         mt->total_height = dim * 4 + 4;
-
-         /* Set all the levels to effectively occupy the whole rectangular region. 
-          */
-         for (level = mt->first_level; level <= mt->last_level; level++) {
-            i915_miptree_set_level_info(mt, level, 6,
-                                         0, 0,
-                                         lvlWidth, lvlHeight, 1);
-           lvlWidth /= 2;
-           lvlHeight /= 2;
-        }
-
-
-         for (face = 0; face < 6; face++) {
-            unsigned x = initial_offsets[face][0] * dim;
-            unsigned y = initial_offsets[face][1] * dim;
-            unsigned d = dim;
-
-            if (dim == 4 && face >= 4) {
-               y = mt->total_height - 4;
-               x = (face - 4) * 8;
-            }
-            else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
-               y = mt->total_height - 4;
-               x = face * 8;
-            }
-
-            for (level = mt->first_level; level <= mt->last_level; level++) {
-               i915_miptree_set_image_offset(mt, level, face, x, y);
-
-               d >>= 1;
-
-               switch (d) {
-               case 4:
-                  switch (face) {
-                  case PIPE_TEX_FACE_POS_X:
-                  case PIPE_TEX_FACE_NEG_X:
-                     x += step_offsets[face][0] * d;
-                     y += step_offsets[face][1] * d;
-                     break;
-                  case PIPE_TEX_FACE_POS_Y:
-                  case PIPE_TEX_FACE_NEG_Y:
-                     y += 12;
-                     x -= 8;
-                     break;
-                  case PIPE_TEX_FACE_POS_Z:
-                  case PIPE_TEX_FACE_NEG_Z:
-                     y = mt->total_height - 4;
-                     x = (face - 4) * 8;
-                     break;
-                  }
-
-               case 2:
-                  y = mt->total_height - 4;
-                  x = 16 + face * 8;
-                  break;
-
-               case 1:
-                  x += 48;
-                  break;
-
-               default:
-                  x += step_offsets[face][0] * d;
-                  y += step_offsets[face][1] * d;
-                  break;
-               }
-            }
-         }
-         break;
-      }
-   case PIPE_TEXTURE_3D:{
-         unsigned width = mt->width0;
-         unsigned height = mt->height0;
-         unsigned depth = mt->depth0;
-         unsigned pack_x_pitch, pack_x_nr;
-         unsigned pack_y_pitch;
-         unsigned level;
-
-         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
-         mt->total_height = 0;
-
-         pack_y_pitch = MAX2(mt->height0, 2);
-         pack_x_pitch = mt->pitch;
-         pack_x_nr = 1;
-
-         for (level = mt->first_level; level <= mt->last_level; level++) {
-            unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6;
-            int x = 0;
-            int y = 0;
-            unsigned q, j;
-
-            i915_miptree_set_level_info(mt, level, nr_images,
-                                         0, mt->total_height,
-                                         width, height, depth);
-
-            for (q = 0; q < nr_images;) {
-               for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
-                  i915_miptree_set_image_offset(mt, level, q, x, y);
-                  x += pack_x_pitch;
-               }
-
-               x = 0;
-               y += pack_y_pitch;
-            }
-
-
-            mt->total_height += y;
-
-            if (pack_x_pitch > 4) {
-               pack_x_pitch >>= 1;
-               pack_x_nr <<= 1;
-               assert(pack_x_pitch * pack_x_nr <= mt->pitch);
-            }
-
-            if (pack_y_pitch > 2) {
-               pack_y_pitch >>= 1;
-            }
-
-            width = minify(width);
-            height = minify(height);
-            depth = minify(depth);
-         }
-         break;
-      }
-
-   case PIPE_TEXTURE_1D:
-   case PIPE_TEXTURE_2D:
-//   case PIPE_TEXTURE_RECTANGLE:
-         i945_miptree_layout_2d(mt);
-         break;
-   default:
-      assert(0);
-      return FALSE;
-   }
-
-   /*
-   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
-       mt->pitch,
-       mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
-   */
-
-   return TRUE;
-}
-
diff --git a/src/mesa/pipe/i915simple/i915_tex_layout.h b/src/mesa/pipe/i915simple/i915_tex_layout.h
deleted file mode 100644 (file)
index e033786..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#ifndef I915_TEX_LAYOUT_H
-#define I915_TEX_LAYOUT_H
-
-struct pipe_context;
-struct pipe_mipmap_tree;
-
-
-extern boolean
-i915_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
-
-extern boolean
-i945_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
-
-
-#endif /* I915_TEX_LAYOUT_H */
diff --git a/src/mesa/pipe/i915simple/i915_texture.c b/src/mesa/pipe/i915simple/i915_texture.c
new file mode 100644 (file)
index 0000000..3bfa806
--- /dev/null
@@ -0,0 +1,539 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Michel Dänzer <michel@tungstengraphics.com>
+  */
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+
+#include "i915_context.h"
+#include "i915_texture.h"
+#include "i915_debug.h"
+
+
+static unsigned minify( unsigned d )
+{
+   return MAX2(1, d>>1);
+}
+
+static int align(int value, int alignment)
+{
+   return (value + alignment - 1) & ~(alignment - 1);
+}
+
+
+static void
+i915_miptree_set_level_info(struct i915_texture *tex,
+                             unsigned level,
+                             unsigned nr_images,
+                             unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
+{
+   struct pipe_texture *pt = &tex->base;
+
+   assert(level < PIPE_MAX_TEXTURE_LEVELS);
+
+   pt->width[level] = w;
+   pt->height[level] = h;
+   pt->depth[level] = d;
+
+   tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp;
+   tex->nr_images[level] = nr_images;
+
+   /*
+   DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
+       level, w, h, d, x, y, tex->level_offset[level]);
+   */
+
+   /* Not sure when this would happen, but anyway: 
+    */
+   if (tex->image_offset[level]) {
+      FREE(tex->image_offset[level]);
+      tex->image_offset[level] = NULL;
+   }
+
+   assert(nr_images);
+   assert(!tex->image_offset[level]);
+
+   tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
+   tex->image_offset[level][0] = 0;
+}
+
+
+static void
+i915_miptree_set_image_offset(struct i915_texture *tex,
+                             unsigned level, unsigned img, unsigned x, unsigned y)
+{
+   if (img == 0 && level == 0)
+      assert(x == 0 && y == 0);
+
+   assert(img < tex->nr_images[level]);
+
+   tex->image_offset[level][img] = (x + y * tex->pitch);
+
+   /*
+   DBG("%s level %d img %d pos %d,%d image_offset %x\n",
+       __FUNCTION__, level, img, x, y, tex->image_offset[level][img]);
+   */
+}
+
+
+static void
+i945_miptree_layout_2d( struct i915_texture *tex )
+{
+   struct pipe_texture *pt = &tex->base;
+   int align_h = 2, align_w = 4;
+   unsigned level;
+   unsigned x = 0;
+   unsigned y = 0;
+   unsigned width = pt->width[0];
+   unsigned height = pt->height[0];
+
+   tex->pitch = pt->width[0];
+
+   /* May need to adjust pitch to accomodate the placement of
+    * the 2nd mipmap.  This occurs when the alignment
+    * constraints of mipmap placement push the right edge of the
+    * 2nd mipmap out past the width of its parent.
+    */
+   if (pt->first_level != pt->last_level) {
+      unsigned mip1_width = align(minify(pt->width[0]), align_w)
+                       + minify(minify(pt->width[0]));
+
+      if (mip1_width > pt->width[0])
+        tex->pitch = mip1_width;
+   }
+
+   /* Pitch must be a whole number of dwords, even though we
+    * express it in texels.
+    */
+   tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp;
+   tex->total_height = 0;
+
+   for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
+      unsigned img_height;
+
+      i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1);
+
+      if (pt->compressed)
+        img_height = MAX2(1, height/4);
+      else
+        img_height = align(height, align_h);
+
+
+      /* Because the images are packed better, the final offset
+       * might not be the maximal one:
+       */
+      tex->total_height = MAX2(tex->total_height, y + img_height);
+
+      /* Layout_below: step right after second mipmap.
+       */
+      if (level == pt->first_level + 1) {
+        x += align(width, align_w);
+      }
+      else {
+        y += img_height;
+      }
+
+      width  = minify(width);
+      height = minify(height);
+   }
+}
+
+
+static const int initial_offsets[6][2] = {
+   {0, 0},
+   {0, 2},
+   {1, 0},
+   {1, 2},
+   {1, 1},
+   {1, 3}
+};
+
+static const int step_offsets[6][2] = {
+   {0, 2},
+   {0, 2},
+   {-1, 2},
+   {-1, 2},
+   {-1, 1},
+   {-1, 1}
+};
+
+
+static boolean
+i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
+{
+   struct pipe_texture *pt = &tex->base;
+   unsigned level;
+
+   switch (pt->target) {
+   case PIPE_TEXTURE_CUBE: {
+         const unsigned dim = pt->width[0];
+         unsigned face;
+         unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+
+         assert(lvlWidth == lvlHeight); /* cubemap images are square */
+
+         /* double pitch for cube layouts */
+         tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+         tex->total_height = dim * 4;
+
+         for (level = pt->first_level; level <= pt->last_level; level++) {
+            i915_miptree_set_level_info(tex, level, 6,
+                                         0, 0,
+                                         /*OLD: tex->pitch, tex->total_height,*/
+                                         lvlWidth, lvlHeight,
+                                         1);
+            lvlWidth /= 2;
+            lvlHeight /= 2;
+         }
+
+         for (face = 0; face < 6; face++) {
+            unsigned x = initial_offsets[face][0] * dim;
+            unsigned y = initial_offsets[face][1] * dim;
+            unsigned d = dim;
+
+            for (level = pt->first_level; level <= pt->last_level; level++) {
+               i915_miptree_set_image_offset(tex, level, face, x, y);
+               d >>= 1;
+               x += step_offsets[face][0] * d;
+               y += step_offsets[face][1] * d;
+            }
+         }
+         break;
+      }
+   case PIPE_TEXTURE_3D:{
+         unsigned width = pt->width[0];
+         unsigned height = pt->height[0];
+         unsigned depth = pt->depth[0];
+         unsigned stack_height = 0;
+
+         /* Calculate the size of a single slice. 
+          */
+         tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+
+         /* XXX: hardware expects/requires 9 levels at minimum.
+          */
+         for (level = pt->first_level; level <= MAX2(8, pt->last_level);
+              level++) {
+            i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height,
+                                         width, height, depth);
+
+
+            stack_height += MAX2(2, height);
+
+            width = minify(width);
+            height = minify(height);
+            depth = minify(depth);
+         }
+
+         /* Fixup depth image_offsets: 
+          */
+         depth = pt->depth[0];
+         for (level = pt->first_level; level <= pt->last_level; level++) {
+            unsigned i;
+            for (i = 0; i < depth; i++) 
+               i915_miptree_set_image_offset(tex, level, i,
+                                              0, i * stack_height);
+
+            depth = minify(depth);
+         }
+
+
+         /* Multiply slice size by texture depth for total size.  It's
+          * remarkable how wasteful of memory the i915 texture layouts
+          * are.  They are largely fixed in the i945.
+          */
+         tex->total_height = stack_height * pt->depth[0];
+         break;
+      }
+
+   default:{
+         unsigned width = pt->width[0];
+         unsigned height = pt->height[0];
+        unsigned img_height;
+
+         tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+         tex->total_height = 0;
+
+         for (level = pt->first_level; level <= pt->last_level; level++) {
+            i915_miptree_set_level_info(tex, level, 1,
+                                         0, tex->total_height,
+                                         width, height, 1);
+
+            if (pt->compressed)
+               img_height = MAX2(1, height / 4);
+            else
+               img_height = (MAX2(2, height) + 1) & ~1;
+
+           tex->total_height += img_height;
+
+            width = minify(width);
+            height = minify(height);
+         }
+         break;
+      }
+   }
+   /*
+   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+       tex->pitch,
+       tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp);
+   */
+
+   return TRUE;
+}
+
+
+static boolean
+i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
+{
+   struct pipe_texture *pt = &tex->base;
+   unsigned level;
+
+   switch (pt->target) {
+   case PIPE_TEXTURE_CUBE:{
+         const unsigned dim = pt->width[0];
+         unsigned face;
+         unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+
+         assert(lvlWidth == lvlHeight); /* cubemap images are square */
+
+         /* Depending on the size of the largest images, pitch can be
+          * determined either by the old-style packing of cubemap faces,
+          * or the final row of 4x4, 2x2 and 1x1 faces below this. 
+          */
+         if (dim > 32)
+            tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+         else
+            tex->pitch = 14 * 8;
+
+         tex->total_height = dim * 4 + 4;
+
+         /* Set all the levels to effectively occupy the whole rectangular region. 
+          */
+         for (level = pt->first_level; level <= pt->last_level; level++) {
+            i915_miptree_set_level_info(tex, level, 6,
+                                         0, 0,
+                                         lvlWidth, lvlHeight, 1);
+           lvlWidth /= 2;
+           lvlHeight /= 2;
+        }
+
+
+         for (face = 0; face < 6; face++) {
+            unsigned x = initial_offsets[face][0] * dim;
+            unsigned y = initial_offsets[face][1] * dim;
+            unsigned d = dim;
+
+            if (dim == 4 && face >= 4) {
+               y = tex->total_height - 4;
+               x = (face - 4) * 8;
+            }
+            else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
+               y = tex->total_height - 4;
+               x = face * 8;
+            }
+
+            for (level = pt->first_level; level <= pt->last_level; level++) {
+               i915_miptree_set_image_offset(tex, level, face, x, y);
+
+               d >>= 1;
+
+               switch (d) {
+               case 4:
+                  switch (face) {
+                  case PIPE_TEX_FACE_POS_X:
+                  case PIPE_TEX_FACE_NEG_X:
+                     x += step_offsets[face][0] * d;
+                     y += step_offsets[face][1] * d;
+                     break;
+                  case PIPE_TEX_FACE_POS_Y:
+                  case PIPE_TEX_FACE_NEG_Y:
+                     y += 12;
+                     x -= 8;
+                     break;
+                  case PIPE_TEX_FACE_POS_Z:
+                  case PIPE_TEX_FACE_NEG_Z:
+                     y = tex->total_height - 4;
+                     x = (face - 4) * 8;
+                     break;
+                  }
+
+               case 2:
+                  y = tex->total_height - 4;
+                  x = 16 + face * 8;
+                  break;
+
+               case 1:
+                  x += 48;
+                  break;
+
+               default:
+                  x += step_offsets[face][0] * d;
+                  y += step_offsets[face][1] * d;
+                  break;
+               }
+            }
+         }
+         break;
+      }
+   case PIPE_TEXTURE_3D:{
+         unsigned width = pt->width[0];
+         unsigned height = pt->height[0];
+         unsigned depth = pt->depth[0];
+         unsigned pack_x_pitch, pack_x_nr;
+         unsigned pack_y_pitch;
+         unsigned level;
+
+         tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+         tex->total_height = 0;
+
+         pack_y_pitch = MAX2(pt->height[0], 2);
+         pack_x_pitch = tex->pitch;
+         pack_x_nr = 1;
+
+         for (level = pt->first_level; level <= pt->last_level; level++) {
+            unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
+            int x = 0;
+            int y = 0;
+            unsigned q, j;
+
+            i915_miptree_set_level_info(tex, level, nr_images,
+                                         0, tex->total_height,
+                                         width, height, depth);
+
+            for (q = 0; q < nr_images;) {
+               for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
+                  i915_miptree_set_image_offset(tex, level, q, x, y);
+                  x += pack_x_pitch;
+               }
+
+               x = 0;
+               y += pack_y_pitch;
+            }
+
+
+            tex->total_height += y;
+
+            if (pack_x_pitch > 4) {
+               pack_x_pitch >>= 1;
+               pack_x_nr <<= 1;
+               assert(pack_x_pitch * pack_x_nr <= tex->pitch);
+            }
+
+            if (pack_y_pitch > 2) {
+               pack_y_pitch >>= 1;
+            }
+
+            width = minify(width);
+            height = minify(height);
+            depth = minify(depth);
+         }
+         break;
+      }
+
+   case PIPE_TEXTURE_1D:
+   case PIPE_TEXTURE_2D:
+//   case PIPE_TEXTURE_RECTANGLE:
+         i945_miptree_layout_2d(tex);
+         break;
+   default:
+      assert(0);
+      return FALSE;
+   }
+
+   /*
+   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+       tex->pitch,
+       tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp);
+   */
+
+   return TRUE;
+}
+
+void
+i915_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+   struct i915_texture *tex = REALLOC(*pt, sizeof(struct pipe_texture),
+                                     sizeof(struct i915_texture));
+
+   if (tex) {
+      struct i915_context *i915 = i915_context(pipe);
+
+      memset(&tex->base + 1, 0,
+            sizeof(struct i915_texture) - sizeof(struct pipe_texture));
+
+      if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) :
+         i915_miptree_layout(pipe, tex)) {
+        tex->region = pipe->winsys->region_alloc(pipe->winsys,
+                                                 tex->pitch * tex->base.cpp *
+                                                 tex->total_height,
+                                                 PIPE_SURFACE_FLAG_TEXTURE);
+      }
+
+      if (!tex->region) {
+        FREE(tex);
+        tex = NULL;
+      }
+   }
+
+   *pt = &tex->base;
+}
+
+void
+i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+   if (!*pt)
+      return;
+
+   /*
+   DBG("%s %p refcount will be %d\n",
+       __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
+   */
+   if (--(*pt)->refcount <= 0) {
+      struct i915_texture *tex = (struct i915_texture *)*pt;
+      uint i;
+
+      /*
+      DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
+      */
+
+      pipe->winsys->region_release(pipe->winsys, &tex->region);
+
+      for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+         if (tex->image_offset[i])
+            free(tex->image_offset[i]);
+
+      free(tex);
+   }
+   *pt = NULL;
+}
diff --git a/src/mesa/pipe/i915simple/i915_texture.h b/src/mesa/pipe/i915simple/i915_texture.h
new file mode 100644 (file)
index 0000000..84a0502
--- /dev/null
@@ -0,0 +1,16 @@
+
+#ifndef I915_TEXTURE_H
+#define I915_TEXTURE_H
+
+struct pipe_context;
+struct pipe_texture;
+
+
+extern void
+i915_texture_create(struct pipe_context *pipe, struct pipe_texture **pt);
+
+extern void
+i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+
+
+#endif /* I915_TEXTURE_H */
index 2459d14cb823b9724dbbec7925dbefc13ac46cc6..fe32e7810dc7c6745e1359ab3cbee7ffb63e2d6f 100644 (file)
@@ -194,7 +194,6 @@ void run_vertex_shader(float (*ainputs)[16][4],
 
 
 struct pipe_sampler_state;
-struct pipe_mipmap_tree;
 struct softpipe_tile_cache;
 
 #define NUM_CHANNELS 4  /* R,G,B,A */
@@ -203,7 +202,6 @@ struct softpipe_tile_cache;
 struct tgsi_sampler
 {
    const struct pipe_sampler_state *state;
-   struct pipe_mipmap_tree *texture;
    /** Get samples for four fragments in a quad */
    void (*get_samples)(struct tgsi_sampler *sampler,
                        const float s[QUAD_SIZE],
index e145b22f2ff6641591fad16e6fbed3d2131fdf22..5033209323feb5cd18014321a541d96dd11189d6 100644 (file)
@@ -155,7 +155,7 @@ struct pipe_context {
 
    void (*set_texture_state)( struct pipe_context *,
                               unsigned unit,
-                              struct pipe_mipmap_tree * );
+                              struct pipe_texture * );
 
    void (*set_viewport_state)( struct pipe_context *,
                                const struct pipe_viewport_state * );
@@ -180,7 +180,7 @@ struct pipe_context {
 
    /** Get a surface which is a "view" into a texture */
    struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe,
-                                           struct pipe_mipmap_tree *texture,
+                                           struct pipe_texture *texture,
                                            unsigned face, unsigned level,
                                            unsigned zslice);
 
@@ -237,8 +237,11 @@ struct pipe_context {
    /*
     * Texture functions
     */
-   boolean (*mipmap_tree_layout)( struct pipe_context *pipe,
-                                 struct pipe_mipmap_tree *mt );
+   void (*texture_create)(struct pipe_context *pipe,
+                         struct pipe_texture **pt);
+
+   void (*texture_release)(struct pipe_context *pipe,
+                          struct pipe_texture **pt);
 
 
    /* Flush rendering:
index 2418d016e15fb45add31274960f2387eee114b7f..c04d46dddd8a956aa1bba810d894aeaab7da86f4 100644 (file)
@@ -80,4 +80,24 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
    }
 }
 
+
+/**
+ * \sa pipe_region_reference
+ */
+static INLINE void
+pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr,
+                      struct pipe_texture *pt)
+{
+   assert(ptr);
+   if (*ptr) {
+      pipe->texture_release(pipe, ptr);
+      assert(!*ptr);
+   }
+   if (pt) {
+      /* reference the new thing */
+      pt->refcount++;
+      *ptr = pt;
+   }
+}
+
 #endif /* P_INLINES_H */
index 642734aeb807ac5bbc25c558f00d1d37ba8abb1f..077a8f5a06ff58eecab2c49cbc465c8d96d44a70 100644 (file)
@@ -288,27 +288,11 @@ struct pipe_surface
 
 
 /**
- * Describes the location of each texture image within a texture region.
+ * Texture. Represents one or several texture images on one or several mipmap
+ * levels.
  */
-struct pipe_mipmap_level
-{
-   unsigned level_offset;
-   unsigned width;
-   unsigned height;
-   unsigned depth;
-   unsigned nr_images;
-
-   /* Explicitly store the offset of each image for each cube face or
-    * depth value.  Pretty much have to accept that hardware formats
-    * are going to be so diverse that there is no unified way to
-    * compute the offsets of depth/cube images within a mipmap level,
-    * so have to store them as a lookup table:
-    */
-   unsigned *image_offset;   /**< array [depth] of offsets */
-};
-
-struct pipe_mipmap_tree
-{
+struct pipe_texture
+{ 
    /* Effectively the key:
     */
    unsigned target;            /* XXX convert to PIPE_TEXTURE_x */
@@ -318,25 +302,13 @@ struct pipe_mipmap_tree
    unsigned first_level;
    unsigned last_level;
 
-   unsigned width0, height0, depth0; /**< Level zero image dimensions */
+   unsigned width[PIPE_MAX_TEXTURE_LEVELS];
+   unsigned height[PIPE_MAX_TEXTURE_LEVELS];
+   unsigned depth[PIPE_MAX_TEXTURE_LEVELS];
    unsigned cpp;
 
    unsigned compressed:1;
 
-   /* Derived from the above:
-    */
-   unsigned pitch;
-   unsigned depth_pitch;          /* per-image on i945? */
-   unsigned total_height;
-
-   /* Includes image offset tables:
-    */
-   struct pipe_mipmap_level level[PIPE_MAX_TEXTURE_LEVELS];
-
-   /* The data is held here:
-    */
-   struct pipe_region *region;
-
    /* These are also refcounted:
     */
    unsigned refcount;
index 59628531cc84a685e302de86575234ca3e233e2a..9978884c9bd5983e07fc1d294e7fbdade0c7a16d 100644 (file)
@@ -34,7 +34,7 @@ DRIVER_SOURCES = \
        sp_state_rasterizer.c \
        sp_state_surface.c \
        sp_state_vertex.c \
-       sp_tex_layout.c \
+       sp_texture.c \
        sp_tex_sample.c \
        sp_tile_cache.c \
        sp_surface.c 
index d5e68c189de2f778165cf7d0887c79dc2e2122de..7a9fccce9ae3ad699df14f8283b6a589fbd21cbb 100644 (file)
@@ -40,7 +40,7 @@
 #include "sp_state.h"
 #include "sp_surface.h"
 #include "sp_tile_cache.h"
-#include "sp_tex_layout.h"
+#include "sp_texture.h"
 #include "sp_winsys.h"
 
 
@@ -98,9 +98,9 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp)
    uint i;
 
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      struct pipe_mipmap_tree *mt = sp->texture[i];
-      if (mt) {
-         pipe->region_map(pipe, mt->region);
+      struct softpipe_texture *spt = sp->texture[i];
+      if (spt) {
+         pipe->region_map(pipe, spt->region);
       }
    }
 }
@@ -146,9 +146,9 @@ softpipe_unmap_texture_surfaces(struct softpipe_context *sp)
    struct pipe_context *pipe = &sp->pipe;
    uint i;
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      struct pipe_mipmap_tree *mt = sp->texture[i];
-      if (mt) {
-         pipe->region_unmap(pipe, mt->region);
+      struct softpipe_texture *spt = sp->texture[i];
+      if (spt) {
+         pipe->region_unmap(pipe, spt->region);
       }
    }
 }
@@ -351,7 +351,8 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    softpipe->pipe.get_vendor = softpipe_get_vendor;
 
    /* textures */
-   softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout;
+   softpipe->pipe.texture_create = softpipe_texture_create;
+   softpipe->pipe.texture_release = softpipe_texture_release;
    softpipe->pipe.get_tex_surface = softpipe_get_tex_surface;
 
    /*
index 872766101d5ead8b14cb67bd0dfe2ed0a95a8477..d4763a98c66c4ee80002925b9655eb985685afa6 100644 (file)
@@ -89,7 +89,7 @@ struct softpipe_context {
    struct pipe_framebuffer_state framebuffer;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
-   struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+   struct softpipe_texture *texture[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
    struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
index 24c8a44c47944d3f7c68ca574f1cc709b98ec3b1..7184fcda52190ec4d130cca39db004b58dd11e0d 100644 (file)
@@ -277,7 +277,7 @@ static void shade_begin(struct quad_stage *qs)
    /* set TGSI sampler state that varies */
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
       qss->samplers[i].state = softpipe->sampler[i];
-      qss->samplers[i].texture = softpipe->texture[i];
+      qss->samplers[i].texture = &softpipe->texture[i]->base;
    }
 
 #ifdef MESA_LLVM
index 2f096a9cc97a4ff599b26f827dc209e029eaf91d..a543735b525d91177283e39bbeaf0679bbbfd1ae 100644 (file)
@@ -52,6 +52,35 @@ struct sp_fragment_shader_state {
 #endif
 };
 
+struct softpipe_texture
+{
+   struct pipe_texture base;
+
+   /* Derived from the above:
+    */
+   unsigned pitch;
+   unsigned depth_pitch;          /* per-image on i945? */
+   unsigned total_height;
+
+   unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+
+   /* Explicitly store the offset of each image for each cube face or
+    * depth value.  Pretty much have to accept that hardware formats
+    * are going to be so diverse that there is no unified way to
+    * compute the offsets of depth/cube images within a mipmap level,
+    * so have to store them as a lookup table:
+    */
+   unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];   /**< array [depth] of offsets */
+
+   /* Includes image offset tables:
+    */
+   unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
+
+   /* The data is held here:
+    */
+   struct pipe_region *region;
+};
+
 void *
 softpipe_create_alpha_test_state(struct pipe_context *,
                                  const struct pipe_alpha_test_state *);
@@ -125,7 +154,7 @@ void softpipe_set_scissor_state( struct pipe_context *,
 
 void softpipe_set_texture_state( struct pipe_context *,
                                  unsigned unit,
-                                 struct pipe_mipmap_tree * );
+                                 struct pipe_texture * );
 
 void softpipe_set_viewport_state( struct pipe_context *,
                                   const struct pipe_viewport_state * );
index 912f42d5688ee33b5c3e2e3ff752a6e1bcb29624..a360b4f02b0853cf8328a1c03c9ebfb07a236455 100644 (file)
@@ -34,6 +34,8 @@
 #include "pipe/draw/draw_context.h"
 #include "pipe/p_shader_tokens.h"
 #include "pipe/llvm/gallivm.h"
+#include "pipe/tgsi/util/tgsi_dump.h"
+#include "pipe/tgsi/exec/tgsi_sse2.h"
 
 
 void * softpipe_create_fs_state(struct pipe_context *pipe,
index 246a7d6eda741904a3ed4abd8d2c95d1ca8940ad..e71b9159e3f4b2abf616120ab82305984e13f794 100644 (file)
@@ -68,12 +68,12 @@ softpipe_delete_sampler_state(struct pipe_context *pipe,
 void
 softpipe_set_texture_state(struct pipe_context *pipe,
                            unsigned unit,
-                           struct pipe_mipmap_tree *texture)
+                           struct pipe_texture *texture)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
    assert(unit < PIPE_MAX_SAMPLERS);
-   softpipe->texture[unit] = texture;  /* ptr, not struct */
+   softpipe->texture[unit] = (struct softpipe_texture *)texture;  /* ptr, not struct */
 
    sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture);
 
index a6ab40460374b4279bc416664a39ff7b1ab45de7..c41bbc59b906322a3417d27005191cedacaa7b7f 100644 (file)
@@ -565,34 +565,35 @@ z24s8_get_tile(struct pipe_surface *ps,
  */
 struct pipe_surface *
 softpipe_get_tex_surface(struct pipe_context *pipe,
-                         struct pipe_mipmap_tree *mt,
+                         struct pipe_texture *pt,
                          unsigned face, unsigned level, unsigned zslice)
 {
+   struct softpipe_texture *spt = (struct softpipe_texture *)pt;
    struct pipe_surface *ps;
    unsigned offset;  /* in bytes */
 
-   offset = mt->level[level].level_offset;
+   offset = spt->level_offset[level];
 
-   if (mt->target == PIPE_TEXTURE_CUBE) {
-      offset += mt->level[level].image_offset[face] * mt->cpp;
+   if (pt->target == PIPE_TEXTURE_CUBE) {
+      offset += spt->image_offset[level][face] * pt->cpp;
    }
-   else if (mt->target == PIPE_TEXTURE_3D) {
-      offset += mt->level[level].image_offset[zslice] * mt->cpp;
+   else if (pt->target == PIPE_TEXTURE_3D) {
+      offset += spt->image_offset[level][zslice] * pt->cpp;
    }
    else {
       assert(face == 0);
       assert(zslice == 0);
    }
 
-   ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format);
+   ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format);
    if (ps) {
       assert(ps->format);
       assert(ps->refcount);
-      pipe_region_reference(&ps->region, mt->region);
-      ps->cpp = mt->cpp;
-      ps->width = mt->level[level].width;
-      ps->height = mt->level[level].height;
-      ps->pitch = mt->pitch;
+      pipe_region_reference(&ps->region, spt->region);
+      ps->cpp = pt->cpp;
+      ps->width = pt->width[level];
+      ps->height = pt->height[level];
+      ps->pitch = spt->pitch;
       ps->offset = offset;
    }
    return ps;
index cf87e1a92ce3d0c24d36ef9bf79aad0993074d1f..b652e7598e89e04f42c80d24ea73e808fa72bc8c 100644 (file)
@@ -41,7 +41,7 @@ struct softpipe_tile_cache;
 
 extern struct pipe_surface *
 softpipe_get_tex_surface(struct pipe_context *pipe,
-                         struct pipe_mipmap_tree *mt,
+                         struct pipe_texture *pt,
                          unsigned face, unsigned level, unsigned zslice);
 
 
diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.c b/src/mesa/pipe/softpipe/sp_tex_layout.c
deleted file mode 100644 (file)
index 8156b00..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Michel Dänzer <michel@tungstengraphics.com>
-  */
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-#include "sp_tex_layout.h"
-
-
-/* At the moment, just make softpipe use the same layout for its
- * textures as the i945.  Softpipe needs some sort of texture layout,
- * this one was handy.  May be worthwhile to simplify this code a
- * little.
- */
-
-static unsigned minify( unsigned d )
-{
-   return MAX2(1, d>>1);
-}
-
-static int align(int value, int alignment)
-{
-   return (value + alignment - 1) & ~(alignment - 1);
-}
-
-
-static void
-sp_miptree_set_level_info(struct pipe_mipmap_tree *mt,
-                             unsigned level,
-                             unsigned nr_images,
-                             unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
-{
-   assert(level < PIPE_MAX_TEXTURE_LEVELS);
-
-   mt->level[level].width = w;
-   mt->level[level].height = h;
-   mt->level[level].depth = d;
-   mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp;
-   mt->level[level].nr_images = nr_images;
-
-   /*
-   DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
-       level, w, h, d, x, y, mt->level[level].level_offset);
-   */
-
-   /* Not sure when this would happen, but anyway: 
-    */
-   if (mt->level[level].image_offset) {
-      FREE( mt->level[level].image_offset );
-      mt->level[level].image_offset = NULL;
-   }
-
-   assert(nr_images);
-   assert(!mt->level[level].image_offset);
-
-   mt->level[level].image_offset = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
-   mt->level[level].image_offset[0] = 0;
-}
-
-
-static void
-sp_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
-                               unsigned level, unsigned img, unsigned x, unsigned y)
-{
-   if (img == 0 && level == 0)
-      assert(x == 0 && y == 0);
-
-   assert(img < mt->level[level].nr_images);
-
-   mt->level[level].image_offset[img] = (x + y * mt->pitch);
-
-   /*
-   DBG("%s level %d img %d pos %d,%d image_offset %x\n",
-       __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]);
-   */
-}
-
-
-static void
-sp_miptree_layout_2d( struct pipe_mipmap_tree *mt )
-{
-   int align_h = 2, align_w = 4;
-   unsigned level;
-   unsigned x = 0;
-   unsigned y = 0;
-   unsigned width = mt->width0;
-   unsigned height = mt->height0;
-
-   mt->pitch = mt->width0;
-   /* XXX FIX THIS:
-    * we use alignment=64 bytes in sp_region_alloc(). If we change
-    * that, change this too.
-    */
-   if (mt->pitch < 16)
-      mt->pitch = 16;
-
-   /* May need to adjust pitch to accomodate the placement of
-    * the 2nd mipmap.  This occurs when the alignment
-    * constraints of mipmap placement push the right edge of the
-    * 2nd mipmap out past the width of its parent.
-    */
-   if (mt->first_level != mt->last_level) {
-      unsigned mip1_width = align(minify(mt->width0), align_w)
-                       + minify(minify(mt->width0));
-
-      if (mip1_width > mt->width0)
-        mt->pitch = mip1_width;
-   }
-
-   /* Pitch must be a whole number of dwords, even though we
-    * express it in texels.
-    */
-   mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
-   mt->total_height = 0;
-
-   for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
-      unsigned img_height;
-
-      sp_miptree_set_level_info(mt, level, 1, x, y, width, height, 1);
-
-      if (mt->compressed)
-        img_height = MAX2(1, height/4);
-      else
-        img_height = align(height, align_h);
-
-
-      /* Because the images are packed better, the final offset
-       * might not be the maximal one:
-       */
-      mt->total_height = MAX2(mt->total_height, y + img_height);
-
-      /* Layout_below: step right after second mipmap.
-       */
-      if (level == mt->first_level + 1) {
-        x += align(width, align_w);
-      }
-      else {
-        y += img_height;
-      }
-
-      width  = minify(width);
-      height = minify(height);
-   }
-}
-
-
-static const int initial_offsets[6][2] = {
-   {0, 0},
-   {0, 2},
-   {1, 0},
-   {1, 2},
-   {1, 1},
-   {1, 3}
-};
-
-static const int step_offsets[6][2] = {
-   {0, 2},
-   {0, 2},
-   {-1, 2},
-   {-1, 2},
-   {-1, 1},
-   {-1, 1}
-};
-
-
-
-boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
-{
-   unsigned level;
-
-   switch (mt->target) {
-   case PIPE_TEXTURE_CUBE:{
-         const unsigned dim = mt->width0;
-         unsigned face;
-         unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
-
-         assert(lvlWidth == lvlHeight); /* cubemap images are square */
-
-         /* Depending on the size of the largest images, pitch can be
-          * determined either by the old-style packing of cubemap faces,
-          * or the final row of 4x4, 2x2 and 1x1 faces below this. 
-          */
-         if (dim > 32)
-            mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
-         else
-            mt->pitch = 14 * 8;
-
-         mt->total_height = dim * 4 + 4;
-
-         /* Set all the levels to effectively occupy the whole rectangular region. 
-          */
-         for (level = mt->first_level; level <= mt->last_level; level++) {
-            sp_miptree_set_level_info(mt, level, 6,
-                                         0, 0,
-                                         lvlWidth, lvlHeight, 1);
-           lvlWidth /= 2;
-           lvlHeight /= 2;
-        }
-
-
-         for (face = 0; face < 6; face++) {
-            unsigned x = initial_offsets[face][0] * dim;
-            unsigned y = initial_offsets[face][1] * dim;
-            unsigned d = dim;
-
-            if (dim == 4 && face >= 4) {
-               y = mt->total_height - 4;
-               x = (face - 4) * 8;
-            }
-            else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
-               y = mt->total_height - 4;
-               x = face * 8;
-            }
-
-            for (level = mt->first_level; level <= mt->last_level; level++) {
-               sp_miptree_set_image_offset(mt, level, face, x, y);
-
-               d >>= 1;
-
-               switch (d) {
-               case 4:
-                  switch (face) {
-                  case PIPE_TEX_FACE_POS_X:
-                  case PIPE_TEX_FACE_NEG_X:
-                     x += step_offsets[face][0] * d;
-                     y += step_offsets[face][1] * d;
-                     break;
-                  case PIPE_TEX_FACE_POS_Y:
-                  case PIPE_TEX_FACE_NEG_Y:
-                     y += 12;
-                     x -= 8;
-                     break;
-                  case PIPE_TEX_FACE_POS_Z:
-                  case PIPE_TEX_FACE_NEG_Z:
-                     y = mt->total_height - 4;
-                     x = (face - 4) * 8;
-                     break;
-                  }
-
-               case 2:
-                  y = mt->total_height - 4;
-                  x = 16 + face * 8;
-                  break;
-
-               case 1:
-                  x += 48;
-                  break;
-
-               default:
-                  x += step_offsets[face][0] * d;
-                  y += step_offsets[face][1] * d;
-                  break;
-               }
-            }
-         }
-         break;
-      }
-   case PIPE_TEXTURE_3D:{
-         unsigned width = mt->width0;
-         unsigned height = mt->height0;
-         unsigned depth = mt->depth0;
-         unsigned pack_x_pitch, pack_x_nr;
-         unsigned pack_y_pitch;
-         unsigned level;
-
-         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
-         mt->total_height = 0;
-
-         pack_y_pitch = MAX2(mt->height0, 2);
-         pack_x_pitch = mt->pitch;
-         pack_x_nr = 1;
-
-         for (level = mt->first_level; level <= mt->last_level; level++) {
-            unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6;
-            int x = 0;
-            int y = 0;
-            unsigned q, j;
-
-            sp_miptree_set_level_info(mt, level, nr_images,
-                                         0, mt->total_height,
-                                         width, height, depth);
-
-            for (q = 0; q < nr_images;) {
-               for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
-                  sp_miptree_set_image_offset(mt, level, q, x, y);
-                  x += pack_x_pitch;
-               }
-
-               x = 0;
-               y += pack_y_pitch;
-            }
-
-
-            mt->total_height += y;
-
-            if (pack_x_pitch > 4) {
-               pack_x_pitch >>= 1;
-               pack_x_nr <<= 1;
-               assert(pack_x_pitch * pack_x_nr <= mt->pitch);
-            }
-
-            if (pack_y_pitch > 2) {
-               pack_y_pitch >>= 1;
-            }
-
-            width = minify(width);
-            height = minify(height);
-            depth = minify(depth);
-         }
-         break;
-      }
-
-   case PIPE_TEXTURE_1D:
-   case PIPE_TEXTURE_2D:
-//   case PIPE_TEXTURE_RECTANGLE:
-         sp_miptree_layout_2d(mt);
-         break;
-   default:
-      assert(0);
-      break;
-   }
-
-   /*
-   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
-       mt->pitch,
-       mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
-   */
-
-   return TRUE;
-}
-
diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.h b/src/mesa/pipe/softpipe/sp_tex_layout.h
deleted file mode 100644 (file)
index ea19c13..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef SP_TEX_LAYOUT_H
-#define SP_TEX_LAYOUT_H
-
-
-struct pipe_context;
-struct pipe_mipmap_tree;
-
-
-extern boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe,
-                            struct pipe_mipmap_tree *mt);
-
-
-#endif /* SP_TEX_LAYOUT_H */
-
-
index 92958400fc59e54e1181857f17425a5d5876d0fa..9e48ed0cd2cbd8c4db6815cf7a83444d8c99ead1 100644 (file)
@@ -422,7 +422,7 @@ compute_lambda(struct tgsi_sampler *sampler,
       dsdy = FABSF(dsdy);
       rho = MAX2(dsdx, dsdy);
       if (sampler->state->normalized_coords)
-         rho *= sampler->texture->width0;
+         rho *= sampler->texture->width[0];
    }
    if (t) {
       float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
@@ -432,7 +432,7 @@ compute_lambda(struct tgsi_sampler *sampler,
       dtdy = FABSF(dtdy);
       max = MAX2(dtdx, dtdy);
       if (sampler->state->normalized_coords)
-         max *= sampler->texture->height0;
+         max *= sampler->texture->height[0];
       rho = MAX2(rho, max);
    }
    if (p) {
@@ -443,7 +443,7 @@ compute_lambda(struct tgsi_sampler *sampler,
       dpdy = FABSF(dpdy);
       max = MAX2(dpdx, dpdy);
       if (sampler->state->normalized_coords)
-         max *= sampler->texture->depth0;
+         max *= sampler->texture->depth[0];
       rho = MAX2(rho, max);
    }
 
@@ -620,8 +620,8 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
                         &level0, &level1, &levelBlend, &imgFilter);
 
    if (sampler->state->normalized_coords) {
-      width = sampler->texture->level[level0].width;
-      height = sampler->texture->level[level0].height;
+      width = sampler->texture->width[level0];
+      height = sampler->texture->height[level0];
    }
    else {
       width = height = 1;
@@ -757,9 +757,9 @@ sp_get_samples_3d(struct tgsi_sampler *sampler,
                         &level0, &level1, &levelBlend, &imgFilter);
 
    if (sampler->state->normalized_coords) {
-      width = sampler->texture->level[level0].width;
-      height = sampler->texture->level[level0].height;
-      depth = sampler->texture->level[level0].depth;
+      width = sampler->texture->width[level0];
+      height = sampler->texture->height[level0];
+      depth = sampler->texture->depth[level0];
    }
    else {
       width = height = depth = 1;
@@ -883,7 +883,7 @@ sp_get_samples_cube(struct tgsi_sampler *sampler,
 /**
  * Called via tgsi_sampler::get_samples()
  * Use the sampler's state setting to get a filtered RGBA value
- * from the sampler's texture (mipmap tree).
+ * from the sampler's texture.
  *
  * XXX we can implement many versions of this function, each
  * tightly coded for a specific combination of sampler state
diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c
new file mode 100644 (file)
index 0000000..2f9a1e9
--- /dev/null
@@ -0,0 +1,425 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Michel Dänzer <michel@tungstengraphics.com>
+  */
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+
+#include "sp_context.h"
+#include "sp_state.h"
+#include "sp_texture.h"
+
+
+/* At the moment, just make softpipe use the same layout for its
+ * textures as the i945.  Softpipe needs some sort of texture layout,
+ * this one was handy.  May be worthwhile to simplify this code a
+ * little.
+ */
+
+static unsigned minify( unsigned d )
+{
+   return MAX2(1, d>>1);
+}
+
+static int align(int value, int alignment)
+{
+   return (value + alignment - 1) & ~(alignment - 1);
+}
+
+
+static void
+sp_miptree_set_level_info(struct softpipe_texture *spt,
+                         unsigned level,
+                         unsigned nr_images,
+                         unsigned x, unsigned y, unsigned w, unsigned h,
+                         unsigned d)
+{
+   struct pipe_texture *pt = &spt->base;
+
+   assert(level < PIPE_MAX_TEXTURE_LEVELS);
+
+   pt->width[level] = w;
+   pt->height[level] = h;
+   pt->depth[level] = d;
+
+   spt->nr_images[level] = nr_images;
+   spt->level_offset[level] = (x + y * spt->pitch) * pt->cpp;
+
+   /*
+   DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
+       level, w, h, d, x, y, spt->level_offset[level]);
+   */
+
+   /* Not sure when this would happen, but anyway: 
+    */
+   if (spt->image_offset[level]) {
+      FREE( spt->image_offset[level] );
+      spt->image_offset[level] = NULL;
+   }
+
+   assert(nr_images);
+   assert(!spt->image_offset[level]);
+
+   spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
+   spt->image_offset[level][0] = 0;
+}
+
+
+static void
+sp_miptree_set_image_offset(struct softpipe_texture *spt,
+                           unsigned level, unsigned img, unsigned x, unsigned y)
+{
+   if (img == 0 && level == 0)
+      assert(x == 0 && y == 0);
+
+   assert(img < spt->nr_images[level]);
+
+   spt->image_offset[level][img] = (x + y * spt->pitch);
+
+   /*
+   DBG("%s level %d img %d pos %d,%d image_offset %x\n",
+       __FUNCTION__, level, img, x, y, spt->image_offset[level][img]);
+   */
+}
+
+
+static void
+sp_miptree_layout_2d( struct softpipe_texture *spt )
+{
+   struct pipe_texture *pt = &spt->base;
+   int align_h = 2, align_w = 4;
+   unsigned level;
+   unsigned x = 0;
+   unsigned y = 0;
+   unsigned width = pt->width[0];
+   unsigned height = pt->height[0];
+
+   spt->pitch = pt->width[0];
+   /* XXX FIX THIS:
+    * we use alignment=64 bytes in sp_region_alloc(). If we change
+    * that, change this too.
+    */
+   if (spt->pitch < 16)
+      spt->pitch = 16;
+
+   /* May need to adjust pitch to accomodate the placement of
+    * the 2nd mipmap.  This occurs when the alignment
+    * constraints of mipmap placement push the right edge of the
+    * 2nd mipmap out past the width of its parent.
+    */
+   if (pt->first_level != pt->last_level) {
+      unsigned mip1_width = align(minify(pt->width[0]), align_w)
+                       + minify(minify(pt->width[0]));
+
+      if (mip1_width > pt->width[0])
+        spt->pitch = mip1_width;
+   }
+
+   /* Pitch must be a whole number of dwords, even though we
+    * express it in texels.
+    */
+   spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp;
+   spt->total_height = 0;
+
+   for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
+      unsigned img_height;
+
+      sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1);
+
+      if (pt->compressed)
+        img_height = MAX2(1, height/4);
+      else
+        img_height = align(height, align_h);
+
+
+      /* Because the images are packed better, the final offset
+       * might not be the maximal one:
+       */
+      spt->total_height = MAX2(spt->total_height, y + img_height);
+
+      /* Layout_below: step right after second mipmap.
+       */
+      if (level == pt->first_level + 1) {
+        x += align(width, align_w);
+      }
+      else {
+        y += img_height;
+      }
+
+      width  = minify(width);
+      height = minify(height);
+   }
+}
+
+
+static const int initial_offsets[6][2] = {
+   {0, 0},
+   {0, 2},
+   {1, 0},
+   {1, 2},
+   {1, 1},
+   {1, 3}
+};
+
+static const int step_offsets[6][2] = {
+   {0, 2},
+   {0, 2},
+   {-1, 2},
+   {-1, 2},
+   {-1, 1},
+   {-1, 1}
+};
+
+
+
+static boolean
+softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt)
+{
+   struct pipe_texture *pt = &spt->base;
+   unsigned level;
+
+   switch (pt->target) {
+   case PIPE_TEXTURE_CUBE:{
+         const unsigned dim = pt->width[0];
+         unsigned face;
+         unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+
+         assert(lvlWidth == lvlHeight); /* cubemap images are square */
+
+         /* Depending on the size of the largest images, pitch can be
+          * determined either by the old-style packing of cubemap faces,
+          * or the final row of 4x4, 2x2 and 1x1 faces below this. 
+          */
+         if (dim > 32)
+            spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+         else
+            spt->pitch = 14 * 8;
+
+         spt->total_height = dim * 4 + 4;
+
+         /* Set all the levels to effectively occupy the whole rectangular region. 
+          */
+         for (level = pt->first_level; level <= pt->last_level; level++) {
+            sp_miptree_set_level_info(spt, level, 6,
+                                         0, 0,
+                                         lvlWidth, lvlHeight, 1);
+           lvlWidth /= 2;
+           lvlHeight /= 2;
+        }
+
+
+         for (face = 0; face < 6; face++) {
+            unsigned x = initial_offsets[face][0] * dim;
+            unsigned y = initial_offsets[face][1] * dim;
+            unsigned d = dim;
+
+            if (dim == 4 && face >= 4) {
+               y = spt->total_height - 4;
+               x = (face - 4) * 8;
+            }
+            else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
+               y = spt->total_height - 4;
+               x = face * 8;
+            }
+
+            for (level = pt->first_level; level <= pt->last_level; level++) {
+               sp_miptree_set_image_offset(spt, level, face, x, y);
+
+               d >>= 1;
+
+               switch (d) {
+               case 4:
+                  switch (face) {
+                  case PIPE_TEX_FACE_POS_X:
+                  case PIPE_TEX_FACE_NEG_X:
+                     x += step_offsets[face][0] * d;
+                     y += step_offsets[face][1] * d;
+                     break;
+                  case PIPE_TEX_FACE_POS_Y:
+                  case PIPE_TEX_FACE_NEG_Y:
+                     y += 12;
+                     x -= 8;
+                     break;
+                  case PIPE_TEX_FACE_POS_Z:
+                  case PIPE_TEX_FACE_NEG_Z:
+                     y = spt->total_height - 4;
+                     x = (face - 4) * 8;
+                     break;
+                  }
+
+               case 2:
+                  y = spt->total_height - 4;
+                  x = 16 + face * 8;
+                  break;
+
+               case 1:
+                  x += 48;
+                  break;
+
+               default:
+                  x += step_offsets[face][0] * d;
+                  y += step_offsets[face][1] * d;
+                  break;
+               }
+            }
+         }
+         break;
+      }
+   case PIPE_TEXTURE_3D:{
+         unsigned width = pt->width[0];
+         unsigned height = pt->height[0];
+         unsigned depth = pt->depth[0];
+         unsigned pack_x_pitch, pack_x_nr;
+         unsigned pack_y_pitch;
+         unsigned level;
+
+         spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+         spt->total_height = 0;
+
+         pack_y_pitch = MAX2(pt->height[0], 2);
+         pack_x_pitch = spt->pitch;
+         pack_x_nr = 1;
+
+         for (level = pt->first_level; level <= pt->last_level; level++) {
+            unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
+            int x = 0;
+            int y = 0;
+            unsigned q, j;
+
+            sp_miptree_set_level_info(spt, level, nr_images,
+                                     0, spt->total_height,
+                                     width, height, depth);
+
+            for (q = 0; q < nr_images;) {
+               for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
+                  sp_miptree_set_image_offset(spt, level, q, x, y);
+                  x += pack_x_pitch;
+               }
+
+               x = 0;
+               y += pack_y_pitch;
+            }
+
+
+            spt->total_height += y;
+
+            if (pack_x_pitch > 4) {
+               pack_x_pitch >>= 1;
+               pack_x_nr <<= 1;
+               assert(pack_x_pitch * pack_x_nr <= spt->pitch);
+            }
+
+            if (pack_y_pitch > 2) {
+               pack_y_pitch >>= 1;
+            }
+
+            width = minify(width);
+            height = minify(height);
+            depth = minify(depth);
+         }
+         break;
+      }
+
+   case PIPE_TEXTURE_1D:
+   case PIPE_TEXTURE_2D:
+//   case PIPE_TEXTURE_RECTANGLE:
+         sp_miptree_layout_2d(spt);
+         break;
+   default:
+      assert(0);
+      break;
+   }
+
+   /*
+   DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+       spt->pitch,
+       spt->total_height, pt->cpp, spt->pitch * spt->total_height * pt->cpp);
+   */
+
+   return TRUE;
+}
+
+void
+softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+   struct softpipe_texture *spt = REALLOC(*pt, sizeof(struct pipe_texture),
+                                         sizeof(struct softpipe_texture));
+
+   if (spt) {
+      memset(&spt->base + 1, 0,
+            sizeof(struct softpipe_texture) - sizeof(struct pipe_texture));
+
+      if (softpipe_mipmap_tree_layout(pipe, spt)) {
+        spt->region = pipe->winsys->region_alloc(pipe->winsys,
+                                                 spt->pitch * (*pt)->cpp *
+                                                 spt->total_height,
+                                                 PIPE_SURFACE_FLAG_TEXTURE);
+      }
+
+      if (!spt->region) {
+        FREE(spt);
+        spt = NULL;
+      }
+   }
+
+   *pt = &spt->base;
+}
+
+void
+softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+   if (!*pt)
+      return;
+
+   /*
+   DBG("%s %p refcount will be %d\n",
+       __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
+   */
+   if (--(*pt)->refcount <= 0) {
+      struct softpipe_texture *spt = (struct softpipe_texture *)*pt;
+      uint i;
+
+      /*
+      DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
+      */
+
+      pipe->winsys->region_release(pipe->winsys, &spt->region);
+
+      for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+         if (spt->image_offset[i])
+            free(spt->image_offset[i]);
+
+      free(spt);
+   }
+   *pt = NULL;
+}
diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h
new file mode 100644 (file)
index 0000000..2aca57b
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SP_TEXTURE_H
+#define SP_TEXTURE_H
+
+
+struct pipe_context;
+struct pipe_texture;
+
+
+extern void
+softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt);
+
+extern void
+softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+
+
+#endif /* SP_TEXTURE */
+
+
index ea0c8b8f91da2d70b1b3841de79808b659f8fde5..62ee6a27c93d9604e9de1d24da4efaddd405b929 100644 (file)
@@ -51,7 +51,7 @@
 struct softpipe_tile_cache
 {
    struct pipe_surface *surface;  /**< the surface we're caching */
-   struct pipe_mipmap_tree *texture;  /**< if caching a texture */
+   struct pipe_texture *texture;  /**< if caching a texture */
    struct softpipe_cached_tile entries[NUM_ENTRIES];
    uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
    float clear_value[4];
@@ -139,7 +139,7 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
 
 void
 sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
-                          struct pipe_mipmap_tree *texture)
+                          struct pipe_texture *texture)
 {
    uint i;
 
index e66fec2e208ce07f5e361b242aa8e82e519cb571..9967aa5044a00bdcd10782b9c236baa555e69745 100644 (file)
@@ -71,7 +71,7 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);
 
 extern void
 sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
-                          struct pipe_mipmap_tree *texture);
+                          struct pipe_texture *texture);
 
 extern void
 sp_flush_tile_cache(struct softpipe_context *softpipe,
index 1d497e97fb0373d1eb756f43e46e98799fbb5171..2c62b30f150fb5760e4316dc24a10ae2153c1c9b 100644 (file)
@@ -76,7 +76,7 @@ struct softpipe_tile_cache;  /**< Opaque to TGSI */
 struct tgsi_sampler
 {
    const struct pipe_sampler_state *state;
-   struct pipe_mipmap_tree *texture;
+   struct pipe_texture *texture;
    /** Get samples for four fragments in a quad */
    void (*get_samples)(struct tgsi_sampler *sampler,
                        const float s[QUAD_SIZE],
index 2df60d1996c430093e227c4c13aba63b672c6ad8..596d3b89d5dd858d64a518700c10407bc3517b11 100644 (file)
@@ -236,7 +236,7 @@ STATETRACKER_SOURCES = \
        state_tracker/st_framebuffer.c \
        state_tracker/st_mesa_to_tgsi.c \
        state_tracker/st_program.c \
-       state_tracker/st_mipmap_tree.c
+       state_tracker/st_texture.c
 
 SHADER_SOURCES = \
        shader/arbprogparse.c \
index f25cfd386a3aa240e27fae4f0e96d6649e56b970..c4e5af02d597678957ac7413579f5d4d79e11f44 100644 (file)
@@ -51,24 +51,24 @@ update_textures(struct st_context *st)
    for (u = 0; u < st->ctx->Const.MaxTextureImageUnits; u++) {
       struct gl_texture_object *texObj
          = st->ctx->Texture.Unit[u]._Current;
-      struct pipe_mipmap_tree *mt;
+      struct pipe_texture *pt;
       if (texObj) {
          GLboolean flush, retval;
 
-         retval = st_finalize_mipmap_tree(st->ctx, st->pipe, u, &flush);
+         retval = st_finalize_texture(st->ctx, st->pipe, u, &flush);
 #if 0
-         printf("finalize_mipmap_tree returned %d, flush = %d\n",
+         printf("finalize_texture returned %d, flush = %d\n",
                 retval, flush);
 #endif
 
-         mt = st_get_texobj_mipmap_tree(texObj);
+         pt = st_get_texobj_texture(texObj);
       }
       else {
-         mt = NULL;
+         pt = NULL;
       }
 
-      st->state.texture[u] = mt;
-      st->pipe->set_texture_state(st->pipe, u, mt);
+      st->state.texture[u] = pt;
+      st->pipe->set_texture_state(st->pipe, u, pt);
    }
 }
 
index 39c0cf6b327c1e67807053a2334fac6025e8eef9..c28ad15b294b63a4b4984d0dc0b21f87a2fb19a9 100644 (file)
@@ -33,6 +33,7 @@
 #include "main/imports.h"
 #include "main/image.h"
 #include "main/macros.h"
+#include "main/texformat.h"
 #include "shader/program.h"
 #include "shader/prog_parameter.h"
 #include "shader/prog_print.h"
@@ -50,6 +51,7 @@
 #include "st_draw.h"
 #include "st_format.h"
 #include "st_mesa_to_tgsi.h"
+#include "st_texture.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
@@ -440,63 +442,20 @@ _mesa_base_format(GLenum format)
 }
 
 
-
-static struct pipe_mipmap_tree *
-alloc_mipmap_tree(struct st_context *st,
-                  GLsizei width, GLsizei height, uint pipeFormat)
-{
-   const GLbitfield flags = PIPE_SURFACE_FLAG_TEXTURE;
-   struct pipe_mipmap_tree *mt;
-   GLuint cpp;
-
-   mt = CALLOC_STRUCT(pipe_mipmap_tree);
-   if (!mt)
-      return NULL;
-
-   cpp = st_sizeof_format(pipeFormat);
-
-   mt->target = PIPE_TEXTURE_2D;
-   mt->internal_format = GL_RGBA;
-   mt->format = pipeFormat;
-   mt->first_level = 0;
-   mt->last_level = 0;
-   mt->width0 = width;
-   mt->height0 = height;
-   mt->depth0 = 1;
-   mt->cpp = cpp;
-   mt->compressed = 0;
-   mt->pitch = st->pipe->winsys->surface_pitch(st->pipe->winsys, cpp, width,
-                                              flags);
-   mt->region = st->pipe->winsys->region_alloc(st->pipe->winsys,
-                                               mt->pitch * cpp * height, flags);
-   mt->depth_pitch = 0;
-   mt->total_height = height;
-   mt->level[0].level_offset = 0;
-   mt->level[0].width = width;
-   mt->level[0].height = height;
-   mt->level[0].depth = 1;
-   mt->level[0].nr_images = 1;
-   mt->level[0].image_offset = NULL;
-   mt->refcount = 1;
-
-   return mt;
-}
-
-
 /**
- * Make mipmap tree containing an image for glDrawPixels image.
+ * Make texture containing an image for glDrawPixels image.
  * If 'pixels' is NULL, leave the texture image data undefined.
  */
-static struct pipe_mipmap_tree *
-make_mipmap_tree(struct st_context *st,
-                 GLsizei width, GLsizei height, GLenum format, GLenum type,
-                 const struct gl_pixelstore_attrib *unpack,
-                 const GLvoid *pixels)
+static struct pipe_texture *
+make_texture(struct st_context *st,
+            GLsizei width, GLsizei height, GLenum format, GLenum type,
+            const struct gl_pixelstore_attrib *unpack,
+            const GLvoid *pixels)
 {
    GLcontext *ctx = st->ctx;
    struct pipe_context *pipe = st->pipe;
    const struct gl_texture_format *mformat;
-   struct pipe_mipmap_tree *mt;
+   struct pipe_texture *pt;
    GLuint pipeFormat, cpp;
    GLenum baseFormat;
 
@@ -509,29 +468,33 @@ make_mipmap_tree(struct st_context *st,
    assert(pipeFormat);
    cpp = st_sizeof_format(pipeFormat);
 
-   mt = alloc_mipmap_tree(st, width, height, pipeFormat);
-   if (!mt)
+   pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, baseFormat, 0, 0,
+                         width, height, 1, 0);
+   if (!pt)
       return NULL;
 
    if (unpack->BufferObj && unpack->BufferObj->Name) {
       /*
-      mt->region = buffer_object_region(unpack->BufferObj);
+      pt->region = buffer_object_region(unpack->BufferObj);
       */
       printf("st_DrawPixels (sourcing from PBO not implemented yet)\n");
    }
 
    {
+      struct pipe_surface *surface;
       static const GLuint dstImageOffsets = 0;
       GLboolean success;
-      GLuint pitch = mt->pitch;
       GLubyte *dest;
       const GLbitfield imageTransferStateSave = ctx->_ImageTransferState;
 
       /* we'll do pixel transfer in a fragment shader */
       ctx->_ImageTransferState = 0x0;
 
+      surface = pipe->get_tex_surface(pipe, pt, 0, 0, 0);
+
       /* map texture region */
-      dest = pipe->region_map(pipe, mt->region);
+      (void) pipe->region_map(pipe, surface->region);
+      dest = surface->region->map + surface->offset;
 
       /* Put image into texture region.
        * Note that the image is actually going to be upside down in
@@ -542,7 +505,7 @@ make_mipmap_tree(struct st_context *st,
                                     mformat,          /* gl_texture_format */
                                     dest,             /* dest */
                                     0, 0, 0,          /* dstX/Y/Zoffset */
-                                    pitch * cpp,      /* dstRowStride, bytes */
+                                    surface->pitch * cpp, /* dstRowStride, bytes */
                                     &dstImageOffsets, /* dstImageOffsets */
                                     width, height, 1, /* size */
                                     format, type,     /* src format/type */
@@ -550,44 +513,15 @@ make_mipmap_tree(struct st_context *st,
                                     unpack);
 
       /* unmap */
-      pipe->region_unmap(pipe, mt->region);
+      pipe->region_unmap(pipe, surface->region);
+      pipe_surface_reference(&surface, NULL);
       assert(success);
 
       /* restore */
       ctx->_ImageTransferState = imageTransferStateSave;
    }
 
-#if 0
-   mt->target = PIPE_TEXTURE_2D;
-   mt->internal_format = GL_RGBA;
-   mt->format = pipeFormat;
-   mt->first_level = 0;
-   mt->last_level = 0;
-   mt->width0 = width;
-   mt->height0 = height;
-   mt->depth0 = 1;
-   mt->cpp = cpp;
-   mt->compressed = 0;
-   mt->pitch = mt->pitch;
-   mt->depth_pitch = 0;
-   mt->total_height = height;
-   mt->level[0].level_offset = 0;
-   mt->level[0].width = width;
-   mt->level[0].height = height;
-   mt->level[0].depth = 1;
-   mt->level[0].nr_images = 1;
-   mt->level[0].image_offset = NULL;
-   mt->refcount = 1;
-#endif
-   return mt;
-}
-
-
-static void
-free_mipmap_tree(struct pipe_context *pipe, struct pipe_mipmap_tree *mt)
-{
-   pipe->winsys->region_release(pipe->winsys, &mt->region);
-   free(mt);
+   return pt;
 }
 
 
@@ -693,7 +627,7 @@ static void
 draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
                    GLsizei width, GLsizei height,
                    GLfloat zoomX, GLfloat zoomY,
-                   struct pipe_mipmap_tree *mt,
+                   struct pipe_texture *pt,
                    struct st_vertex_program *stvp,
                    struct st_fragment_program *stfp,
                    const GLfloat *color,
@@ -761,9 +695,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
       pipe->set_viewport_state(pipe, &vp);
    }
 
-   /* mipmap tree state: */
+   /* texture state: */
    {
-      pipe->set_texture_state(pipe, unit, mt);
+      pipe->set_texture_state(pipe, unit, pt);
    }
 
    /* Compute window coords (y=0=bottom) with pixel zoom.
@@ -1025,14 +959,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
        any_pixel_transfer_ops(st) ||
        !compatible_formats(format, type, ps->format)) {
       /* textured quad */
-      struct pipe_mipmap_tree *mt
-         = make_mipmap_tree(ctx->st, width, height, format, type,
-                            unpack, pixels);
-      if (mt) {
+      struct pipe_texture *pt
+         = make_texture(ctx->st, width, height, format, type, unpack, pixels);
+      if (pt) {
          draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
                             width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
-                            mt, stvp, stfp, color, GL_FALSE);
-         free_mipmap_tree(st->pipe, mt);
+                            pt, stvp, stfp, color, GL_FALSE);
+        st->pipe->texture_release(st->pipe, &pt);
       }
    }
    else {
@@ -1046,26 +979,29 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
 /**
  * Create a texture which represents a bitmap image.
  */
-static struct pipe_mipmap_tree *
+static struct pipe_texture *
 make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
                     const struct gl_pixelstore_attrib *unpack,
                     const GLubyte *bitmap)
 {
    struct pipe_context *pipe = ctx->st->pipe;
-   const uint flags = PIPE_SURFACE_FLAG_TEXTURE;
+   struct pipe_surface *surface;
    uint format = 0, cpp, comp;
+   GLenum internal_format;
    ubyte *dest;
-   struct pipe_mipmap_tree *mt;
+   struct pipe_texture *pt;
    int row, col;
 
    /* find a texture format we know */
    if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_I8 )) {
       format = PIPE_FORMAT_U_I8;
+      internal_format = GL_INTENSITY8;
       cpp = 1;
       comp = 0;
    }
    else if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8_R8_G8_B8 )) {
       format = PIPE_FORMAT_U_A8_R8_G8_B8;
+      internal_format = GL_RGBA8;
       cpp = 4;
       comp = 3; /* alpha channel */ /*XXX little-endian dependency */
    }
@@ -1075,31 +1011,25 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
    }
 
    /**
-    * Create a mipmap tree.
+    * Create a texture.
     */
-   mt = CALLOC_STRUCT(pipe_mipmap_tree);
-   if (!mt)
+   pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, internal_format,
+                         0, 0, width, height, 1, 0);
+   if (!pt)
       return NULL;
 
    if (unpack->BufferObj && unpack->BufferObj->Name) {
       /*
-      mt->region = buffer_object_region(unpack->BufferObj);
+      pt->region = buffer_object_region(unpack->BufferObj);
       */
       printf("st_Bitmap (sourcing from PBO not implemented yet)\n");
    }
 
-
-   /* allocate texture region/storage */
-   mt->pitch = pipe->winsys->surface_pitch(pipe->winsys, cpp, width, flags);
-   mt->region = pipe->winsys->region_alloc(pipe->winsys,
-                                          mt->pitch * cpp * height, flags);
+   surface = pipe->get_tex_surface(pipe, pt, 0, 0, 0);
 
    /* map texture region */
-   dest = pipe->region_map(pipe, mt->region);
-   if (!dest) {
-      printf("st_Bitmap region_map() failed!?!");
-      return NULL;
-   }
+   (void) pipe->region_map(pipe, surface->region);
+   dest = surface->region->map + surface->offset;
 
    /* Put image into texture region.
     * Note that the image is actually going to be upside down in
@@ -1109,7 +1039,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
    for (row = 0; row < height; row++) {
       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
-      ubyte *destRow = dest + row * mt->pitch * cpp;
+      ubyte *destRow = dest + row * surface->pitch * cpp;
 
       if (unpack->LsbFirst) {
          /* Lsb first */
@@ -1158,30 +1088,13 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
 
    } /* row */
 
-   /* unmap */
-   pipe->region_unmap(pipe, mt->region);
-
-   mt->target = PIPE_TEXTURE_2D;
-   mt->internal_format = GL_RGBA;
-   mt->format = format;
-   mt->first_level = 0;
-   mt->last_level = 0;
-   mt->width0 = width;
-   mt->height0 = height;
-   mt->depth0 = 1;
-   mt->cpp = cpp;
-   mt->compressed = 0;
-   mt->depth_pitch = 0;
-   mt->total_height = height;
-   mt->level[0].level_offset = 0;
-   mt->level[0].width = width;
-   mt->level[0].height = height;
-   mt->level[0].depth = 1;
-   mt->level[0].nr_images = 1;
-   mt->level[0].image_offset = NULL;
-   mt->refcount = 1;
-
-   return mt;
+   /* Release surface */
+   pipe->region_unmap(pipe, surface->region);
+   pipe_surface_reference(&surface, NULL);
+
+   pt->format = format;
+
+   return pt;
 }
 
 
@@ -1193,21 +1106,21 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    struct st_fragment_program *stfp;
    struct st_vertex_program *stvp;
    struct st_context *st = ctx->st;
-   struct pipe_mipmap_tree *mt;
+   struct pipe_texture *pt;
 
    stvp = make_vertex_shader(ctx->st, GL_TRUE);
    stfp = combined_bitmap_fragment_program(ctx);
 
    st_validate_state(st);
 
-   mt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
-   if (mt) {
+   pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
+   if (pt) {
       draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
                          width, height, 1.0, 1.0,
-                         mt, stvp, stfp,
+                         pt, stvp, stfp,
                          ctx->Current.RasterColor, GL_FALSE);
 
-      free_mipmap_tree(st->pipe, mt);
+      st->pipe->texture_release(st->pipe, &pt);
    }
 }
 
@@ -1296,7 +1209,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    struct st_fragment_program *stfp;
    struct pipe_surface *psRead;
    struct pipe_surface *psTex;
-   struct pipe_mipmap_tree *mt;
+   struct pipe_texture *pt;
    GLfloat *color;
    uint format;
 
@@ -1327,11 +1240,12 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    psRead = rbRead->surface;
    format = psRead->format;
 
-   mt = alloc_mipmap_tree(ctx->st, width, height, format);
-   if (!mt)
+   pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format,
+                         rbRead->Base.InternalFormat, 0, 0, width, height, 1, 0);
+   if (!pt)
       return;
 
-   psTex = pipe->get_tex_surface(pipe, mt, 0, 0, 0);
+   psTex = pipe->get_tex_surface(pipe, pt, 0, 0, 0);
 
    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
       srcy = ctx->DrawBuffer->Height - srcy - height;
@@ -1368,10 +1282,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    /* draw textured quad */
    draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                       width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
-                      mt, stvp, stfp, color, GL_TRUE);
+                      pt, stvp, stfp, color, GL_TRUE);
 
    pipe_surface_reference(&psTex, NULL);
-   free_mipmap_tree(st->pipe, mt);
+   st->pipe->texture_release(st->pipe, &pt);
 }
 
 
index 80c92e8b7a1fa08c31fe5f7fc28d1a642b4d67e2..43681b7f8a9d410d5141bfb7e2fb95e197162260 100644 (file)
@@ -286,7 +286,7 @@ st_render_texture(GLcontext *ctx,
    struct st_renderbuffer *strb;
    struct gl_renderbuffer *rb;
    struct pipe_context *pipe = st->pipe;
-   struct pipe_mipmap_tree *mt;
+   struct pipe_texture *pt;
 
    assert(!att->Renderbuffer);
 
@@ -302,26 +302,26 @@ st_render_texture(GLcontext *ctx,
    rb->AllocStorage = NULL; /* should not get called */
    strb = st_renderbuffer(rb);
 
-   /* get the mipmap tree for the texture */
-   mt = st_get_texobj_mipmap_tree(att->Texture);
-   assert(mt);
-   assert(mt->level[att->TextureLevel].width);
+   /* get the texture for the texture object */
+   pt = st_get_texobj_texture(att->Texture);
+   assert(pt);
+   assert(pt->width[att->TextureLevel]);
 
-   rb->Width = mt->level[att->TextureLevel].width;
-   rb->Height = mt->level[att->TextureLevel].height;
+   rb->Width = pt->width[att->TextureLevel];
+   rb->Height = pt->height[att->TextureLevel];
 
-   /* the renderbuffer's surface is inside the mipmap_tree: */
-   strb->surface = pipe->get_tex_surface(pipe, mt,
+   /* the renderbuffer's surface is inside the texture */
+   strb->surface = pipe->get_tex_surface(pipe, pt,
                                          att->CubeMapFace,
                                          att->TextureLevel,
                                          att->Zoffset);
    assert(strb->surface);
 
-   init_renderbuffer_bits(strb, mt->format);
+   init_renderbuffer_bits(strb, pt->format);
 
    /*
-   printf("RENDER TO TEXTURE obj=%p mt=%p surf=%p  %d x %d\n",
-          att->Texture, mt, strb->surface, rb->Width, rb->Height);
+   printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p  %d x %d\n",
+          att->Texture, pt, strb->surface, rb->Width, rb->Height);
    */
 
    /* Invalidate buffer state so that the pipe's framebuffer state
index 461705119fae9bc323e5e6344d5a41d56a048ae9..f45d7e4275bb9eee2abcc61066a20b3dbef30c96 100644 (file)
@@ -40,7 +40,7 @@
 #include "state_tracker/st_cb_fbo.h"
 #include "state_tracker/st_cb_texture.h"
 #include "state_tracker/st_format.h"
-#include "state_tracker/st_mipmap_tree.h"
+#include "state_tracker/st_texture.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
@@ -54,8 +54,7 @@ struct st_texture_object
 {
    struct gl_texture_object base;       /* The "parent" object */
 
-   /* The mipmap tree must include at least these levels once
-    * validated:
+   /* The texture must include at least these levels once validated:
     */
    GLuint firstLevel;
    GLuint lastLevel;
@@ -67,7 +66,7 @@ struct st_texture_object
    /* On validation any active images held in main memory or in other
     * regions will be copied to this region and the old storage freed.
     */
-   struct pipe_mipmap_tree *mt;
+   struct pipe_texture *pt;
 
    GLboolean imageOverride;
    GLint depthOverride;
@@ -76,24 +75,6 @@ struct st_texture_object
 
 
 
-struct st_texture_image
-{
-   struct gl_texture_image base;
-
-   /* These aren't stored in gl_texture_image 
-    */
-   GLuint level;
-   GLuint face;
-
-   /* If stImage->mt != NULL, image data is stored here.
-    * Else if stImage->base.Data != NULL, image is stored there.
-    * Else there is no image data.
-    */
-   struct pipe_mipmap_tree *mt;
-};
-
-
-
 
 static INLINE struct st_texture_object *
 st_texture_object(struct gl_texture_object *obj)
@@ -108,11 +89,11 @@ st_texture_image(struct gl_texture_image *img)
 }
 
 
-struct pipe_mipmap_tree *
-st_get_texobj_mipmap_tree(struct gl_texture_object *texObj)
+struct pipe_texture *
+st_get_texobj_texture(struct gl_texture_object *texObj)
 {
    struct st_texture_object *stObj = st_texture_object(texObj);
-   return stObj->mt;
+   return stObj->pt;
 }
 
 
@@ -174,9 +155,9 @@ st_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj)
    struct st_texture_object *stObj = st_texture_object(texObj);
 
    return
-      stObj->mt &&
-      stObj->mt->region &&
-      intel_is_region_resident(intel, stObj->mt->region);
+      stObj->pt &&
+      stObj->pt->region &&
+      intel_is_region_resident(intel, stObj->pt->region);
 #endif
    return 1;
 }
@@ -207,11 +188,10 @@ static void
 st_DeleteTextureObject(GLcontext *ctx,
                         struct gl_texture_object *texObj)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
    struct st_texture_object *stObj = st_texture_object(texObj);
 
-   if (stObj->mt)
-      st_miptree_release(pipe, &stObj->mt);
+   if (stObj->pt)
+      ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
 
    _mesa_delete_texture_object(ctx, texObj);
 }
@@ -220,13 +200,12 @@ st_DeleteTextureObject(GLcontext *ctx,
 static void
 st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
    struct st_texture_image *stImage = st_texture_image(texImage);
 
    DBG("%s\n", __FUNCTION__);
 
-   if (stImage->mt) {
-      st_miptree_release(pipe, &stImage->mt);
+   if (stImage->pt) {
+      ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt);
    }
 
    if (texImage->Data) {
@@ -287,10 +266,10 @@ do_memcpy(void *dest, const void *src, size_t n)
 }
 
 
-/* Functions to store texture images.  Where possible, mipmap_tree's
+/* Functions to store texture images.  Where possible, textures
  * will be created or further instantiated with image data, otherwise
  * images will be stored in malloc'd memory.  A validation step is
- * required to pull those images into a mipmap tree, or otherwise
+ * required to pull those images into a texture, or otherwise
  * decide a fallback is required.
  */
 
@@ -313,17 +292,16 @@ logbase2(int n)
 /* Otherwise, store it in memory if (Border != 0) or (any dimension ==
  * 1).
  *    
- * Otherwise, if max_level >= level >= min_level, create tree with
- * space for textures from min_level down to max_level.
+ * Otherwise, if max_level >= level >= min_level, create texture with
+ * space for images from min_level down to max_level.
  *
- * Otherwise, create tree with space for textures from (level
- * 0)..(1x1).  Consider pruning this tree at a validation if the
- * saving is worth it.
+ * Otherwise, create texture with space for images from (level 0)..(1x1).
+ * Consider pruning this texture at a validation if the saving is worth it.
  */
 static void
-guess_and_alloc_mipmap_tree(struct pipe_context *pipe,
-                            struct st_texture_object *stObj,
-                            struct st_texture_image *stImage)
+guess_and_alloc_texture(struct st_context *st,
+                       struct st_texture_object *stObj,
+                       struct st_texture_image *stImage)
 {
    GLuint firstLevel;
    GLuint lastLevel;
@@ -382,23 +360,20 @@ guess_and_alloc_mipmap_tree(struct pipe_context *pipe,
       lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
    }
 
-   assert(!stObj->mt);
+   assert(!stObj->pt);
    if (stImage->base.IsCompressed)
       comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
-   stObj->mt = st_miptree_create(pipe,
+   stObj->pt = st_texture_create(st,
                                  gl_target_to_pipe(stObj->base.Target),
-                                 stImage->base.InternalFormat,
+                                 st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat),
+                                stImage->base.InternalFormat,
                                  firstLevel,
                                  lastLevel,
                                  width,
                                  height,
                                  depth,
-                                 stImage->base.TexFormat->TexelBytes,
                                  comp_byte);
 
-   stObj->mt->format
-      = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
-
    DBG("%s - success\n", __FUNCTION__);
 }
 
@@ -482,11 +457,11 @@ try_pbo_upload(GLcontext *ctx,
    else
       src_stride = width;
 
-   dst_offset = st_miptree_image_offset(stImage->mt,
+   dst_offset = st_texture_image_offset(stImage->pt,
                                            stImage->face,
                                            stImage->level);
 
-   dst_stride = stImage->mt->pitch;
+   dst_stride = stImage->pt->pitch;
 
    {
       struct _DriBufferObject *src_buffer =
@@ -495,11 +470,11 @@ try_pbo_upload(GLcontext *ctx,
       /* Temporary hack: cast to _DriBufferObject:
        */
       struct _DriBufferObject *dst_buffer =
-         (struct _DriBufferObject *)stImage->mt->region->buffer;
+         (struct _DriBufferObject *)stImage->pt->region->buffer;
 
 
       intelEmitCopyBlit(intel,
-                        stImage->mt->cpp,
+                        stImage->pt->cpp,
                         src_stride, src_buffer, src_offset,
                         dst_stride, dst_buffer, dst_offset,
                         0, 0, 0, 0, width, height,
@@ -540,7 +515,6 @@ st_TexImage(GLcontext * ctx,
               struct gl_texture_object *texObj,
               struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
    struct st_texture_object *stObj = st_texture_object(texObj);
    struct st_texture_image *stImage = st_texture_image(texImage);
    GLint postConvWidth = width;
@@ -589,58 +563,58 @@ st_TexImage(GLcontext * ctx,
    /* Release the reference to a potentially orphaned buffer.   
     * Release any old malloced memory.
     */
-   if (stImage->mt) {
-      st_miptree_release(pipe, &stImage->mt);
+   if (stImage->pt) {
+      ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt);
       assert(!texImage->Data);
    }
    else if (texImage->Data) {
       _mesa_align_free(texImage->Data);
    }
 
-   /* If this is the only texture image in the tree, could call
+   /* If this is the only texture image in the texture, could call
     * bmBufferData with NULL data to free the old block and avoid
     * waiting on any outstanding fences.
     */
-   if (stObj->mt &&
-       stObj->mt->first_level == level &&
-       stObj->mt->last_level == level &&
-       stObj->mt->target != PIPE_TEXTURE_CUBE &&
-       !st_miptree_match_image(stObj->mt, &stImage->base,
+   if (stObj->pt &&
+       stObj->pt->first_level == level &&
+       stObj->pt->last_level == level &&
+       stObj->pt->target != PIPE_TEXTURE_CUBE &&
+       !st_texture_match_image(stObj->pt, &stImage->base,
                                   stImage->face, stImage->level)) {
 
       DBG("release it\n");
-      st_miptree_release(pipe, &stObj->mt);
-      assert(!stObj->mt);
+      ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
+      assert(!stObj->pt);
    }
 
-   if (!stObj->mt) {
-      guess_and_alloc_mipmap_tree(pipe, stObj, stImage);
-      if (!stObj->mt) {
-        DBG("guess_and_alloc_mipmap_tree: failed\n");
+   if (!stObj->pt) {
+      guess_and_alloc_texture(ctx->st, stObj, stImage);
+      if (!stObj->pt) {
+        DBG("guess_and_alloc_texture: failed\n");
       }
    }
 
-   assert(!stImage->mt);
+   assert(!stImage->pt);
 
-   if (stObj->mt &&
-       st_miptree_match_image(stObj->mt, &stImage->base,
+   if (stObj->pt &&
+       st_texture_match_image(stObj->pt, &stImage->base,
                                  stImage->face, stImage->level)) {
 
-      st_miptree_reference(&stImage->mt, stObj->mt);
-      assert(stImage->mt);
+      pipe_texture_reference(ctx->st->pipe, &stImage->pt, stObj->pt);
+      assert(stImage->pt);
    }
 
-   if (!stImage->mt)
-      DBG("XXX: Image did not fit into tree - storing in local memory!\n");
+   if (!stImage->pt)
+      DBG("XXX: Image did not fit into texture - storing in local memory!\n");
 
 #if 0 /* XXX FIX when st_buffer_objects are in place */
    /* PBO fastpaths:
     */
    if (dims <= 2 &&
-       stImage->mt &&
+       stImage->pt &&
        intel_buffer_object(unpack->BufferObj) &&
        check_pbo_format(internalFormat, format,
-                        type, stImage->base.TexFormat)) {
+                        type, texImage->TexFormat)) {
 
       DBG("trying pbo upload\n");
 
@@ -650,9 +624,9 @@ st_TexImage(GLcontext * ctx,
        * performance (in particular when pipe_region_cow() is
        * required).
        */
-      if (stObj->mt == stImage->mt &&
-          stObj->mt->first_level == level &&
-          stObj->mt->last_level == level) {
+      if (stObj->pt == stImage->pt &&
+          stObj->pt->first_level == level &&
+          stObj->pt->last_level == level) {
 
          if (try_pbo_zcopy(intel, stImage, unpack,
                            internalFormat,
@@ -683,7 +657,7 @@ st_TexImage(GLcontext * ctx,
 
 
    /* intelCopyTexImage calls this function with pixels == NULL, with
-    * the expectation that the mipmap tree will be set up but nothing
+    * the expectation that the texture will be set up but nothing
     * more will be done.  This is where those calls return:
     */
    if (compressed) {
@@ -698,13 +672,9 @@ st_TexImage(GLcontext * ctx,
    if (!pixels)
       return;
 
-   if (stImage->mt) {
-      texImage->Data = st_miptree_image_map(pipe,
-                                               stImage->mt,
-                                               stImage->face,
-                                               stImage->level,
-                                               &dstRowStride,
-                                               stImage->base.ImageOffsets);
+   if (stImage->pt) {
+      texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
+      dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
    }
    else {
       /* Allocate regular memory and store the image there temporarily.   */
@@ -732,22 +702,36 @@ st_TexImage(GLcontext * ctx,
    if (compressed) {
      memcpy(texImage->Data, pixels, imageSize);
    }
-   else if (!texImage->TexFormat->StoreImage(ctx, dims, 
-                                             texImage->_BaseFormat, 
-                                             texImage->TexFormat, 
-                                             texImage->Data,
-                                             0, 0, 0, /* dstX/Y/Zoffset */
-                                             dstRowStride,
-                                             texImage->ImageOffsets,
-                                             width, height, depth,
-                                             format, type, pixels, unpack)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+   else {
+      GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height,
+                                                      format, type);
+      int i;
+
+      for (i = 0; i++ < depth;) {
+        if (!texImage->TexFormat->StoreImage(ctx, dims, 
+                                             texImage->_BaseFormat, 
+                                             texImage->TexFormat, 
+                                             texImage->Data,
+                                             0, 0, 0, /* dstX/Y/Zoffset */
+                                             dstRowStride,
+                                             texImage->ImageOffsets,
+                                             width, height, 1,
+                                             format, type, pixels, unpack)) {
+           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+        }
+
+        if (stImage->pt && i < depth) {
+           st_texture_image_unmap(ctx->st, stImage);
+           texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+           pixels += srcImageStride;
+        }
+      }
    }
 
    _mesa_unmap_teximage_pbo(ctx, unpack);
 
-   if (stImage->mt) {
-      st_miptree_image_unmap(pipe, stImage->mt);
+   if (stImage->pt) {
+      st_texture_image_unmap(ctx->st, stImage);
       texImage->Data = NULL;
    }
 
@@ -839,49 +823,58 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
    /*
    struct intel_context *intel = intel_context(ctx);
    */
-   struct pipe_context *pipe = ctx->st->pipe;
    struct st_texture_image *stImage = st_texture_image(texImage);
+   GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width,
+                                                   texImage->Height, format,
+                                                   type);
+   GLuint depth;
+   int i;
 
    /* Map */
-   if (stImage->mt) {
+   if (stImage->pt) {
       /* Image is stored in hardware format in a buffer managed by the
        * kernel.  Need to explicitly map and unmap it.
        */
-      stImage->base.Data =
-         st_miptree_image_map(pipe,
-                                 stImage->mt,
-                                 stImage->face,
-                                 stImage->level,
-                                 &stImage->base.RowStride,
-                                 stImage->base.ImageOffsets);
-      stImage->base.RowStride /= stImage->mt->cpp;
+      texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
+      texImage->RowStride = stImage->surface->pitch;
    }
    else {
       /* Otherwise, the image should actually be stored in
-       * stImage->base.Data.  This is pretty confusing for
+       * texImage->Data.  This is pretty confusing for
        * everybody, I'd much prefer to separate the two functions of
        * texImage->Data - storage for texture images in main memory
        * and access (ie mappings) of images.  In other words, we'd
        * create a new texImage->Map field and leave Data simply for
        * storage.
        */
-      assert(stImage->base.Data);
+      assert(texImage->Data);
    }
 
+   depth = texImage->Depth;
+   texImage->Depth = 1;
 
-   if (compressed) {
-      _mesa_get_compressed_teximage(ctx, target, level, pixels,
-                                   texObj, texImage);
-   } else {
-      _mesa_get_teximage(ctx, target, level, format, type, pixels,
-                        texObj, texImage);
+   for (i = 0; i++ < depth;) {
+      if (compressed) {
+        _mesa_get_compressed_teximage(ctx, target, level, pixels,
+                                      texObj, texImage);
+      } else {
+        _mesa_get_teximage(ctx, target, level, format, type, pixels,
+                           texObj, texImage);
+      }
+
+      if (stImage->pt && i < depth) {
+        st_texture_image_unmap(ctx->st, stImage);
+        texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+        pixels += dstImageStride;
+      }
    }
-     
+
+   texImage->Depth = depth;
 
    /* Unmap */
-   if (stImage->mt) {
-      st_miptree_image_unmap(pipe, stImage->mt);
-      stImage->base.Data = NULL;
+   if (stImage->pt) {
+      st_texture_image_unmap(ctx->st, stImage);
+      texImage->Data = NULL;
    }
 }
 
@@ -921,9 +914,11 @@ st_TexSubimage(GLcontext * ctx,
                  struct gl_texture_object *texObj,
                  struct gl_texture_image *texImage)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
    struct st_texture_image *stImage = st_texture_image(texImage);
    GLuint dstRowStride;
+   GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
+                                                   format, type);
+   int i;
 
    DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
        _mesa_lookup_enum_by_nr(target),
@@ -938,25 +933,28 @@ st_TexSubimage(GLcontext * ctx,
    /* Map buffer if necessary.  Need to lock to prevent other contexts
     * from uploading the buffer under us.
     */
-   if (stImage->mt) 
-      texImage->Data = st_miptree_image_map(pipe,
-                                               stImage->mt,
-                                               stImage->face,
-                                               stImage->level,
-                                               &dstRowStride,
-                                               texImage->ImageOffsets);
-
-   assert(dstRowStride);
-
-   if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
-                                        texImage->TexFormat,
-                                        texImage->Data,
-                                        xoffset, yoffset, zoffset,
-                                        dstRowStride,
-                                        texImage->ImageOffsets,
-                                        width, height, depth,
-                                        format, type, pixels, packing)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+   if (stImage->pt) {
+      texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset);
+      dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+   }
+
+   for (i = 0; i++ < depth;) {
+      if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
+                                          texImage->TexFormat,
+                                          texImage->Data,
+                                          xoffset, yoffset, 0,
+                                          dstRowStride,
+                                          texImage->ImageOffsets,
+                                          width, height, 1,
+                                          format, type, pixels, packing)) {
+        _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+      }
+
+      if (stImage->pt && i < depth) {
+        st_texture_image_unmap(ctx->st, stImage);
+        texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i);
+        pixels += srcImageStride;
+      }
    }
 
 #if 0
@@ -970,8 +968,8 @@ st_TexSubimage(GLcontext * ctx,
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 
-   if (stImage->mt) {
-      st_miptree_image_unmap(pipe, stImage->mt);
+   if (stImage->pt) {
+      st_texture_image_unmap(ctx->st, stImage);
       texImage->Data = NULL;
    }
 }
@@ -1074,7 +1072,7 @@ fallback_copy_texsubimage(GLcontext *ctx,
 {
    struct pipe_context *pipe = ctx->st->pipe;
    const uint face = texture_face(target);
-   struct pipe_mipmap_tree *mt = stImage->mt;
+   struct pipe_texture *pt = stImage->pt;
    struct pipe_surface *src_surf, *dest_surf;
    GLfloat *data;
    GLint row, yStep;
@@ -1090,7 +1088,7 @@ fallback_copy_texsubimage(GLcontext *ctx,
 
    src_surf = strb->surface;
 
-   dest_surf = pipe->get_tex_surface(pipe, mt,
+   dest_surf = pipe->get_tex_surface(pipe, pt,
                                     face, level, destZ);
 
    (void) pipe->region_map(pipe, dest_surf->region);
@@ -1150,7 +1148,7 @@ do_copy_texsubimage(GLcontext *ctx,
    struct gl_framebuffer *fb = ctx->ReadBuffer;
    struct st_renderbuffer *strb;
    struct pipe_context *pipe = ctx->st->pipe;
-   struct pipe_region *src_region, *dest_region;
+   struct pipe_surface *dest_surface;
    uint dest_format, src_format;
 
    (void) texImage;
@@ -1169,29 +1167,24 @@ do_copy_texsubimage(GLcontext *ctx,
 
    assert(strb);
    assert(strb->surface);
-   assert(stImage->mt);
+   assert(stImage->pt);
 
    if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
       srcY = strb->Base.Height - srcY - height;
    }
 
    src_format = strb->surface->format;
-   dest_format = stImage->mt->format;
+   dest_format = stImage->pt->format;
 
-   src_region = strb->surface->region;
-   dest_region = stImage->mt->region;
+   dest_surface = pipe->get_tex_surface(pipe, stImage->pt, stImage->face,
+                                       stImage->level, destZ);
 
    if (src_format == dest_format &&
        ctx->_ImageTransferState == 0x0 &&
-       src_region &&
-       dest_region &&
-       strb->surface->cpp == stImage->mt->cpp) {
+       strb->surface->region &&
+       dest_surface->region &&
+       strb->surface->cpp == stImage->pt->cpp) {
       /* do blit-style copy */
-      struct pipe_surface *dest_surface = pipe->get_tex_surface(pipe,
-                                                               stImage->mt,
-                                                               stImage->face,
-                                                               stImage->level,
-                                                               destZ);
 
       /* XXX may need to invert image depending on window
        * vs. user-created FBO
@@ -1203,12 +1196,12 @@ do_copy_texsubimage(GLcontext *ctx,
        * worth it:
        */
       intelEmitCopyBlit(intel,
-                        stImage->mt->cpp,
+                        stImage->pt->cpp,
                         -src->pitch,
                         src->buffer,
                         src->height * src->pitch * src->cpp,
-                        stImage->mt->pitch,
-                        stImage->mt->region->buffer,
+                        stImage->pt->pitch,
+                        stImage->pt->region->buffer,
                         dest_offset,
                         x, y + height, dstx, dsty, width, height,
                         GL_COPY); /* ? */
@@ -1224,8 +1217,6 @@ do_copy_texsubimage(GLcontext *ctx,
                         /* size */
                         width, height);
 #endif
-
-      pipe_surface_reference(&dest_surface, NULL);
    }
    else {
       fallback_copy_texsubimage(ctx, target, level,
@@ -1234,6 +1225,7 @@ do_copy_texsubimage(GLcontext *ctx,
                                 srcX, srcY, width, height);
    }
 
+   pipe_surface_reference(&dest_surface, NULL);
 
 #if 0
    /* GL_SGIS_generate_mipmap -- this can be accelerated now.
@@ -1267,7 +1259,7 @@ st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
       goto fail;
 #endif
 
-   /* Setup or redefine the texture object, mipmap tree and texture
+   /* Setup or redefine the texture object, texture and texture
     * image.  Don't populate yet.  
     */
    ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
@@ -1299,7 +1291,7 @@ st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
       goto fail;
 #endif
 
-   /* Setup or redefine the texture object, mipmap tree and texture
+   /* Setup or redefine the texture object, texture and texture
     * image.  Don't populate yet.  
     */
    ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
@@ -1407,28 +1399,28 @@ calculate_first_last_level(struct st_texture_object *stObj)
 
 
 static void
-copy_image_data_to_tree(struct pipe_context *pipe,
-                        struct st_texture_object *stObj,
-                        struct st_texture_image *stImage)
+copy_image_data_to_texture(struct st_context *st,
+                          struct st_texture_object *stObj,
+                          struct st_texture_image *stImage)
 {
-   if (stImage->mt) {
+   if (stImage->pt) {
       /* Copy potentially with the blitter:
        */
-      st_miptree_image_copy(pipe,
-                            stObj->mt,  /* dest miptree */
+      st_texture_image_copy(st->pipe,
+                            stObj->pt,  /* dest texture */
                             stImage->face, stImage->level,
-                            stImage->mt /* src miptree */
+                            stImage->pt /* src texture */
                             );
 
-      st_miptree_release(pipe, &stImage->mt);
+      st->pipe->texture_release(st->pipe, &stImage->pt);
    }
    else {
       assert(stImage->base.Data != NULL);
 
       /* More straightforward upload.  
        */
-      st_miptree_image_data(pipe,
-                               stObj->mt,
+      st_texture_image_data(st->pipe,
+                               stObj->pt,
                                stImage->face,
                                stImage->level,
                                stImage->base.Data,
@@ -1439,16 +1431,16 @@ copy_image_data_to_tree(struct pipe_context *pipe,
       stImage->base.Data = NULL;
    }
 
-   st_miptree_reference(&stImage->mt, stObj->mt);
+   pipe_texture_reference(st->pipe, &stImage->pt, stObj->pt);
 }
 
 
 /*  
  */
 GLboolean
-st_finalize_mipmap_tree(GLcontext *ctx,
-                        struct pipe_context *pipe, GLuint unit,
-                        GLboolean *needFlush)
+st_finalize_texture(GLcontext *ctx,
+                   struct pipe_context *pipe, GLuint unit,
+                   GLboolean *needFlush)
 {
    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
    struct st_texture_object *stObj = st_texture_object(tObj);
@@ -1465,7 +1457,7 @@ st_finalize_mipmap_tree(GLcontext *ctx,
     */
    assert(stObj->base._Complete);
 
-   /* What levels must the tree include at a minimum?
+   /* What levels must the texture include at a minimum?
     */
    calculate_first_last_level(stObj);
    firstImage =
@@ -1474,27 +1466,27 @@ st_finalize_mipmap_tree(GLcontext *ctx,
    /* Fallback case:
     */
    if (firstImage->base.Border) {
-      if (stObj->mt) {
-         st_miptree_release(pipe, &stObj->mt);
+      if (stObj->pt) {
+         ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
       }
       return GL_FALSE;
    }
 
 
-   /* If both firstImage and stObj have a tree which can contain
+   /* If both firstImage and stObj point to a texture which can contain
     * all active images, favour firstImage.  Note that because of the
     * completeness requirement, we know that the image dimensions
     * will match.
     */
-   if (firstImage->mt &&
-       firstImage->mt != stObj->mt &&
-       firstImage->mt->first_level <= stObj->firstLevel &&
-       firstImage->mt->last_level >= stObj->lastLevel) {
+   if (firstImage->pt &&
+       firstImage->pt != stObj->pt &&
+       firstImage->pt->first_level <= stObj->firstLevel &&
+       firstImage->pt->last_level >= stObj->lastLevel) {
 
-      if (stObj->mt)
-         st_miptree_release(pipe, &stObj->mt);
+      if (stObj->pt)
+         ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
 
-      st_miptree_reference(&stObj->mt, firstImage->mt);
+      pipe_texture_reference(ctx->st->pipe, &stObj->pt, firstImage->pt);
    }
 
    if (firstImage->base.IsCompressed) {
@@ -1505,48 +1497,45 @@ st_finalize_mipmap_tree(GLcontext *ctx,
       cpp = firstImage->base.TexFormat->TexelBytes;
    }
 
-   /* Check tree can hold all active levels.  Check tree matches
+   /* Check texture can hold all active levels.  Check texture matches
     * target, imageFormat, etc.
     * 
     * XXX: For some layouts (eg i945?), the test might have to be
-    * first_level == firstLevel, as the tree isn't valid except at the
+    * first_level == firstLevel, as the texture isn't valid except at the
     * original start level.  Hope to get around this by
     * programming minLod, maxLod, baseLevel into the hardware and
-    * leaving the tree alone.
+    * leaving the texture alone.
     */
-   if (stObj->mt &&
-       (stObj->mt->target != gl_target_to_pipe(stObj->base.Target) ||
-       stObj->mt->internal_format != firstImage->base.InternalFormat ||
-       stObj->mt->first_level != stObj->firstLevel ||
-       stObj->mt->last_level != stObj->lastLevel ||
-       stObj->mt->width0 != firstImage->base.Width ||
-       stObj->mt->height0 != firstImage->base.Height ||
-       stObj->mt->depth0 != firstImage->base.Depth ||
-       stObj->mt->cpp != cpp ||
-       stObj->mt->compressed != firstImage->base.IsCompressed)) {
-      st_miptree_release(pipe, &stObj->mt);
+   if (stObj->pt &&
+       (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
+       stObj->pt->internal_format != firstImage->base.InternalFormat ||
+       stObj->pt->first_level != stObj->firstLevel ||
+       stObj->pt->last_level != stObj->lastLevel ||
+       stObj->pt->width[0] != firstImage->base.Width ||
+       stObj->pt->height[0] != firstImage->base.Height ||
+       stObj->pt->depth[0] != firstImage->base.Depth ||
+       stObj->pt->cpp != cpp ||
+       stObj->pt->compressed != firstImage->base.IsCompressed)) {
+      ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
    }
 
 
-   /* May need to create a new tree:
+   /* May need to create a new texture:
     */
-   if (!stObj->mt) {
-      stObj->mt = st_miptree_create(pipe,
+   if (!stObj->pt) {
+      stObj->pt = st_texture_create(ctx->st,
                                     gl_target_to_pipe(stObj->base.Target),
-                                    firstImage->base.InternalFormat,
+                                    st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
+                                   firstImage->base.InternalFormat,
                                     stObj->firstLevel,
                                     stObj->lastLevel,
                                     firstImage->base.Width,
                                     firstImage->base.Height,
                                     firstImage->base.Depth,
-                                    cpp,
                                     comp_byte);
-
-      stObj->mt->format
-         = st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
    }
 
-   /* Pull in any images not in the object's tree:
+   /* Pull in any images not in the object's texture:
     */
    nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
    for (face = 0; face < nr_faces; face++) {
@@ -1554,10 +1543,10 @@ st_finalize_mipmap_tree(GLcontext *ctx,
          struct st_texture_image *stImage =
             st_texture_image(stObj->base.Image[face][i]);
 
-         /* Need to import images in main memory or held in other trees.
+         /* Need to import images in main memory or held in other textures.
           */
-         if (stObj->mt != stImage->mt) {
-            copy_image_data_to_tree(pipe, stObj, stImage);
+         if (stObj->pt != stImage->pt) {
+            copy_image_data_to_texture(ctx->st, stObj, stImage);
            *needFlush = GL_TRUE;
          }
       }
index 7a1867dc58ad122797e7c60bfef5f6d9466cdbcb..7f8082b029de2b3f8ac84d980c5113d474e12923 100644 (file)
@@ -2,14 +2,14 @@
 #define ST_CB_TEXTURE_H
 
 
-extern struct pipe_mipmap_tree *
-st_get_texobj_mipmap_tree(struct gl_texture_object *texObj);
+extern struct pipe_texture *
+st_get_texobj_texture(struct gl_texture_object *texObj);
 
 
 extern GLboolean
-st_finalize_mipmap_tree(GLcontext *ctx,
-                        struct pipe_context *pipe, GLuint unit,
-                        GLboolean *needFlush);
+st_finalize_texture(GLcontext *ctx,
+                   struct pipe_context *pipe, GLuint unit,
+                   GLboolean *needFlush);
 
 
 extern void
index a6045230a0f063ca4b6439de61f70c785a9d1a45..db97014c5a7ae0bbd450e42dacce8ca8df22a55b 100644 (file)
@@ -36,7 +36,6 @@
 struct st_context;
 struct st_region;
 struct st_texture_object;
-struct st_texture_image;
 struct st_fragment_program;
 struct draw_context;
 struct draw_stage;
@@ -61,6 +60,25 @@ struct st_tracked_state {
 
 
 
+struct st_texture_image
+{
+   struct gl_texture_image base;
+
+   /* These aren't stored in gl_texture_image 
+    */
+   GLuint level;
+   GLuint face;
+
+   /* If stImage->pt != NULL, image data is stored here.
+    * Else if stImage->base.Data != NULL, image is stored there.
+    * Else there is no image data.
+    */
+   struct pipe_texture *pt;
+
+   struct pipe_surface *surface;
+};
+
+
 
 struct st_context
 {
@@ -91,7 +109,7 @@ struct st_context
       struct pipe_constant_buffer constants[2];
       struct pipe_feedback_state feedback;
       struct pipe_framebuffer_state framebuffer;
-      struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+      struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
       struct pipe_poly_stipple poly_stipple;
       struct pipe_scissor_state scissor;
       struct pipe_viewport_state viewport;
diff --git a/src/mesa/state_tracker/st_mipmap_tree.c b/src/mesa/state_tracker/st_mipmap_tree.c
deleted file mode 100644 (file)
index 6ccf331..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "st_mipmap_tree.h"
-#include "enums.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_winsys.h"
-
-
-#define DBG if(0) printf
-
-#if 0
-static GLenum
-target_to_target(GLenum target)
-{
-   switch (target) {
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
-      return GL_TEXTURE_CUBE_MAP_ARB;
-   default:
-      return target;
-   }
-}
-#endif
-
-struct pipe_mipmap_tree *
-st_miptree_create(struct pipe_context *pipe,
-                  unsigned target,
-                     GLenum internal_format,
-                     GLuint first_level,
-                     GLuint last_level,
-                     GLuint width0,
-                     GLuint height0,
-                     GLuint depth0, GLuint cpp, GLuint compress_byte)
-{
-   GLboolean ok;
-   struct pipe_mipmap_tree *mt = calloc(sizeof(*mt), 1);
-   GLbitfield flags = 0x0;
-
-   assert(target <= PIPE_TEXTURE_CUBE);
-
-   DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
-       _mesa_lookup_enum_by_nr(target),
-       _mesa_lookup_enum_by_nr(internal_format), first_level, last_level);
-
-   mt->target = target;
-   mt->internal_format = internal_format;
-   mt->first_level = first_level;
-   mt->last_level = last_level;
-   mt->width0 = width0;
-   mt->height0 = height0;
-   mt->depth0 = depth0;
-   mt->cpp = compress_byte ? compress_byte : cpp;
-   mt->compressed = compress_byte ? 1 : 0;
-   mt->refcount = 1; 
-
-   ok = pipe->mipmap_tree_layout(pipe, mt);
-   if (ok) {
-      mt->region = pipe->winsys->region_alloc(pipe->winsys,
-                                             mt->pitch * mt->cpp *
-                                             mt->total_height, flags);
-   }
-
-   if (!mt->region) {
-      free(mt);
-      return NULL;
-   }
-
-   return mt;
-}
-
-
-void
-st_miptree_reference(struct pipe_mipmap_tree **dst,
-                        struct pipe_mipmap_tree *src)
-{
-   src->refcount++;
-   *dst = src;
-   DBG("%s %p refcount now %d\n", __FUNCTION__, (void *) src, src->refcount);
-}
-
-void
-st_miptree_release(struct pipe_context *pipe,
-                   struct pipe_mipmap_tree **mt)
-{
-   if (!*mt)
-      return;
-
-   DBG("%s %p refcount will be %d\n",
-       __FUNCTION__, (void *) *mt, (*mt)->refcount - 1);
-   if (--(*mt)->refcount <= 0) {
-      GLuint i;
-
-      DBG("%s deleting %p\n", __FUNCTION__, (void *) *mt);
-
-      pipe->winsys->region_release(pipe->winsys, &((*mt)->region));
-
-      for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
-         if ((*mt)->level[i].image_offset)
-            free((*mt)->level[i].image_offset);
-
-      free(*mt);
-   }
-   *mt = NULL;
-}
-
-
-
-
-/* Can the image be pulled into a unified mipmap tree.  This mirrors
- * the completeness test in a lot of ways.
- *
- * Not sure whether I want to pass gl_texture_image here.
- */
-GLboolean
-st_miptree_match_image(struct pipe_mipmap_tree *mt,
-                          struct gl_texture_image *image,
-                          GLuint face, GLuint level)
-{
-   /* Images with borders are never pulled into mipmap trees. 
-    */
-   if (image->Border) 
-      return GL_FALSE;
-
-   if (image->InternalFormat != mt->internal_format ||
-       image->IsCompressed != mt->compressed)
-      return GL_FALSE;
-
-   /* Test image dimensions against the base level image adjusted for
-    * minification.  This will also catch images not present in the
-    * tree, changed targets, etc.
-    */
-   if (image->Width != mt->level[level].width ||
-       image->Height != mt->level[level].height ||
-       image->Depth != mt->level[level].depth)
-      return GL_FALSE;
-
-   return GL_TRUE;
-}
-
-
-/* Although we use the image_offset[] array to store relative offsets
- * to cube faces, Mesa doesn't know anything about this and expects
- * each cube face to be treated as a separate image.
- *
- * These functions present that view to mesa:
- */
-const GLuint *
-st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level)
-{
-   static const GLuint zero = 0;
-
-   if (mt->target != PIPE_TEXTURE_3D || mt->level[level].nr_images == 1)
-      return &zero;
-   else
-      return mt->level[level].image_offset;
-}
-
-
-/**
- * Return the offset to the given mipmap texture image within the
- * texture memory buffer, in bytes.
- */
-GLuint
-st_miptree_image_offset(const struct pipe_mipmap_tree * mt,
-                        GLuint face, GLuint level)
-{
-   if (mt->target == PIPE_TEXTURE_CUBE)
-      return (mt->level[level].level_offset +
-              mt->level[level].image_offset[face] * mt->cpp);
-   else
-      return mt->level[level].level_offset;
-}
-
-
-GLuint
-st_miptree_texel_offset(const struct pipe_mipmap_tree * mt,
-                        GLuint face, GLuint level,
-                        GLuint col, GLuint row, GLuint img)
-{
-   GLuint imgOffset = st_miptree_image_offset(mt, face, level);
-
-   return imgOffset + row * (mt->pitch + col) * mt->cpp;
-}
-
-
-
-/**
- * Map a teximage in a mipmap tree.
- * \param row_stride  returns row stride in bytes
- * \param image_stride  returns image stride in bytes (for 3D textures).
- * \return address of mapping
- */
-GLubyte *
-st_miptree_image_map(struct pipe_context *pipe,
-                        struct pipe_mipmap_tree * mt,
-                        GLuint face,
-                        GLuint level,
-                        GLuint * row_stride, GLuint * image_offsets)
-{
-   GLubyte *ptr;
-   DBG("%s \n", __FUNCTION__);
-
-   if (row_stride)
-      *row_stride = mt->pitch * mt->cpp;
-
-   if (image_offsets)
-      memcpy(image_offsets, mt->level[level].image_offset,
-             mt->level[level].depth * sizeof(GLuint));
-
-   ptr = pipe->region_map(pipe, mt->region);
-
-   return ptr + st_miptree_image_offset(mt, face, level);
-}
-
-void
-st_miptree_image_unmap(struct pipe_context *pipe,
-                          struct pipe_mipmap_tree *mt)
-{
-   DBG("%s\n", __FUNCTION__);
-   pipe->region_unmap(pipe, mt->region);
-}
-
-
-
-/* Upload data for a particular image.
- */
-void
-st_miptree_image_data(struct pipe_context *pipe,
-                      struct pipe_mipmap_tree *dst,
-                      GLuint face,
-                      GLuint level,
-                      void *src,
-                      GLuint src_row_pitch, GLuint src_image_pitch)
-{
-   GLuint depth = dst->level[level].depth;
-   GLuint i;
-   GLuint height = 0;
-   const GLubyte *srcUB = src;
-   struct pipe_surface *dst_surface;
-
-   DBG("%s\n", __FUNCTION__);
-   for (i = 0; i < depth; i++) {
-      height = dst->level[level].height;
-      if(dst->compressed)
-        height /= 4;
-
-      dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
-
-      pipe->surface_data(pipe, dst_surface,
-                        0, 0,                             /* dstx, dsty */
-                        srcUB,
-                        src_row_pitch,
-                        0, 0,                             /* source x, y */
-                        dst->level[level].width, height); /* width, height */
-
-      pipe_surface_reference(&dst_surface, NULL);
-
-      srcUB += src_image_pitch * dst->cpp;
-   }
-}
-
-/* Copy mipmap image between trees
- */
-void
-st_miptree_image_copy(struct pipe_context *pipe,
-                         struct pipe_mipmap_tree *dst,
-                         GLuint face, GLuint level,
-                         struct pipe_mipmap_tree *src)
-{
-   GLuint width = src->level[level].width;
-   GLuint height = src->level[level].height;
-   GLuint depth = src->level[level].depth;
-   struct pipe_surface *src_surface;
-   struct pipe_surface *dst_surface;
-   GLuint i;
-
-   if (dst->compressed)
-      height /= 4;
-   for (i = 0; i < depth; i++) {
-      dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
-      src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
-
-      pipe->surface_copy(pipe,
-                        dst_surface,
-                        0, 0, /* destX, Y */
-                        src_surface,
-                        0, 0, /* srcX, Y */
-                        width, height);
-
-      pipe_surface_reference(&dst_surface, NULL);
-      pipe_surface_reference(&src_surface, NULL);
-   }
-
-}
diff --git a/src/mesa/state_tracker/st_mipmap_tree.h b/src/mesa/state_tracker/st_mipmap_tree.h
deleted file mode 100644 (file)
index 3e7fd7f..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#ifndef ST_MIPMAP_TREE_H
-#define ST_MIPMAP_TREE_H
-
-
-#include "main/mtypes.h"
-
-struct pipe_context;
-struct pipe_mipmap_tree;
-struct pipe_region;
-
-
-extern struct pipe_mipmap_tree *
-st_miptree_create(struct pipe_context *pipe,
-                  GLenum target,
-                  GLenum internal_format,
-                  GLuint first_level,
-                  GLuint last_level,
-                  GLuint width0,
-                  GLuint height0,
-                  GLuint depth0,
-                  GLuint cpp,
-                  GLuint compress_byte);
-
-extern void
-st_miptree_reference(struct pipe_mipmap_tree **dst,
-                     struct pipe_mipmap_tree *src);
-
-extern void
-st_miptree_release(struct pipe_context *pipe, struct pipe_mipmap_tree **mt);
-
-
-/* Check if an image fits an existing mipmap tree layout
- */
-extern GLboolean
-st_miptree_match_image(struct pipe_mipmap_tree *mt,
-                       struct gl_texture_image *image,
-                       GLuint face, GLuint level);
-
-/* Return a pointer to an image within a tree.  Return image stride as
- * well.
- */
-extern GLubyte *
-st_miptree_image_map(struct pipe_context *pipe,
-                     struct pipe_mipmap_tree *mt,
-                     GLuint face, GLuint level,
-                     GLuint * row_stride, GLuint * image_stride);
-
-extern void
-st_miptree_image_unmap(struct pipe_context *pipe,
-                       struct pipe_mipmap_tree *mt);
-
-
-/* Return pointers to each 2d slice within an image.  Indexed by depth
- * value.
- */
-extern const GLuint *
-st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level);
-
-
-/* Return the linear offset of an image relative to the start of the
- * tree:
- */
-extern GLuint
-st_miptree_image_offset(const struct pipe_mipmap_tree *mt,
-                        GLuint face, GLuint level);
-
-extern GLuint
-st_miptree_texel_offset(const struct pipe_mipmap_tree * mt,
-                        GLuint face, GLuint level,
-                        GLuint col, GLuint row, GLuint img);
-
-
-/* Upload an image into a tree
- */
-extern void
-st_miptree_image_data(struct pipe_context *pipe,
-                      struct pipe_mipmap_tree *dst,
-                      GLuint face, GLuint level, void *src,
-                      GLuint src_row_pitch, GLuint src_image_pitch);
-
-
-/* Copy an image between two trees
- */
-extern void
-st_miptree_image_copy(struct pipe_context *pipe,
-                      struct pipe_mipmap_tree *dst,
-                      GLuint face, GLuint level,
-                      struct pipe_mipmap_tree *src);
-
-
-#endif
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
new file mode 100644 (file)
index 0000000..a5582c3
--- /dev/null
@@ -0,0 +1,276 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "st_context.h"
+#include "st_format.h"
+#include "st_texture.h"
+#include "enums.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_winsys.h"
+
+
+#define DBG if(0) printf
+
+#if 0
+static GLenum
+target_to_target(GLenum target)
+{
+   switch (target) {
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+      return GL_TEXTURE_CUBE_MAP_ARB;
+   default:
+      return target;
+   }
+}
+#endif
+
+struct pipe_texture *
+st_texture_create(struct st_context *st,
+                  unsigned target,
+                 unsigned format,
+                 GLenum internal_format,
+                 GLuint first_level,
+                 GLuint last_level,
+                 GLuint width0,
+                 GLuint height0,
+                 GLuint depth0,
+                 GLuint compress_byte)
+{
+   struct pipe_texture *pt = CALLOC_STRUCT(pipe_texture);
+
+   assert(target <= PIPE_TEXTURE_CUBE);
+
+   DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
+       _mesa_lookup_enum_by_nr(target),
+       _mesa_lookup_enum_by_nr(internal_format), first_level, last_level);
+
+   if (!pt)
+      return NULL;
+
+   assert(format);
+
+   pt->target = target;
+   pt->format = format;
+   pt->internal_format = internal_format;
+   pt->first_level = first_level;
+   pt->last_level = last_level;
+   pt->width[0] = width0;
+   pt->height[0] = height0;
+   pt->depth[0] = depth0;
+   pt->compressed = compress_byte ? 1 : 0;
+   pt->cpp = pt->compressed ? compress_byte : st_sizeof_format(format);
+   pt->refcount = 1; 
+
+   st->pipe->texture_create(st->pipe, &pt);
+
+   return pt;
+}
+
+
+
+
+/* Can the image be pulled into a unified mipmap texture.  This mirrors
+ * the completeness test in a lot of ways.
+ *
+ * Not sure whether I want to pass gl_texture_image here.
+ */
+GLboolean
+st_texture_match_image(struct pipe_texture *pt,
+                          struct gl_texture_image *image,
+                          GLuint face, GLuint level)
+{
+   /* Images with borders are never pulled into mipmap textures. 
+    */
+   if (image->Border) 
+      return GL_FALSE;
+
+   if (image->InternalFormat != pt->internal_format ||
+       image->IsCompressed != pt->compressed)
+      return GL_FALSE;
+
+   /* Test image dimensions against the base level image adjusted for
+    * minification.  This will also catch images not present in the
+    * texture, changed targets, etc.
+    */
+   if (image->Width != pt->width[level] ||
+       image->Height != pt->height[level] ||
+       image->Depth != pt->depth[level])
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+
+#if 000
+/* Although we use the image_offset[] array to store relative offsets
+ * to cube faces, Mesa doesn't know anything about this and expects
+ * each cube face to be treated as a separate image.
+ *
+ * These functions present that view to mesa:
+ */
+const GLuint *
+st_texture_depth_offsets(struct pipe_texture *pt, GLuint level)
+{
+   static const GLuint zero = 0;
+
+   if (pt->target != PIPE_TEXTURE_3D || pt->level[level].nr_images == 1)
+      return &zero;
+   else
+      return pt->level[level].image_offset;
+}
+
+
+/**
+ * Return the offset to the given mipmap texture image within the
+ * texture memory buffer, in bytes.
+ */
+GLuint
+st_texture_image_offset(const struct pipe_texture * pt,
+                        GLuint face, GLuint level)
+{
+   if (pt->target == PIPE_TEXTURE_CUBE)
+      return (pt->level[level].level_offset +
+              pt->level[level].image_offset[face] * pt->cpp);
+   else
+      return pt->level[level].level_offset;
+}
+#endif
+
+
+/**
+ * Map a teximage in a mipmap texture.
+ * \param row_stride  returns row stride in bytes
+ * \param image_stride  returns image stride in bytes (for 3D textures).
+ * \return address of mapping
+ */
+GLubyte *
+st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
+                    GLuint zoffset)
+{
+   struct pipe_texture *pt = stImage->pt;
+   DBG("%s \n", __FUNCTION__);
+
+   stImage->surface = st->pipe->get_tex_surface(st->pipe, pt, stImage->face,
+                                               stImage->level, zoffset);
+
+   (void) st->pipe->region_map(st->pipe, stImage->surface->region);
+
+   return stImage->surface->region->map + stImage->surface->offset;
+}
+
+void
+st_texture_image_unmap(struct st_context *st, struct st_texture_image *stImage)
+{
+   DBG("%s\n", __FUNCTION__);
+
+   st->pipe->region_unmap(st->pipe, stImage->surface->region);
+
+   pipe_surface_reference(&stImage->surface, NULL);
+}
+
+
+
+/* Upload data for a particular image.
+ */
+void
+st_texture_image_data(struct pipe_context *pipe,
+                      struct pipe_texture *dst,
+                      GLuint face,
+                      GLuint level,
+                      void *src,
+                      GLuint src_row_pitch, GLuint src_image_pitch)
+{
+   GLuint depth = dst->depth[level];
+   GLuint i;
+   GLuint height = 0;
+   const GLubyte *srcUB = src;
+   struct pipe_surface *dst_surface;
+
+   DBG("%s\n", __FUNCTION__);
+   for (i = 0; i < depth; i++) {
+      height = dst->height[level];
+      if(dst->compressed)
+        height /= 4;
+
+      dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
+
+      pipe->surface_data(pipe, dst_surface,
+                        0, 0,                             /* dstx, dsty */
+                        srcUB,
+                        src_row_pitch,
+                        0, 0,                             /* source x, y */
+                        dst->width[level], height); /* width, height */
+
+      pipe_surface_reference(&dst_surface, NULL);
+
+      srcUB += src_image_pitch * dst->cpp;
+   }
+}
+
+/* Copy mipmap image between textures
+ */
+void
+st_texture_image_copy(struct pipe_context *pipe,
+                         struct pipe_texture *dst,
+                         GLuint face, GLuint level,
+                         struct pipe_texture *src)
+{
+   GLuint width = src->width[level];
+   GLuint height = src->height[level];
+   GLuint depth = src->depth[level];
+   struct pipe_surface *src_surface;
+   struct pipe_surface *dst_surface;
+   GLuint i;
+
+   if (dst->compressed)
+      height /= 4;
+   for (i = 0; i < depth; i++) {
+      dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
+      src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
+
+      pipe->surface_copy(pipe,
+                        dst_surface,
+                        0, 0, /* destX, Y */
+                        src_surface,
+                        0, 0, /* srcX, Y */
+                        width, height);
+
+      pipe_surface_reference(&dst_surface, NULL);
+      pipe_surface_reference(&src_surface, NULL);
+   }
+
+}
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
new file mode 100644 (file)
index 0000000..b25e3f3
--- /dev/null
@@ -0,0 +1,109 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#ifndef ST_TEXTURE_H
+#define ST_TEXTURE_H
+
+
+#include "main/mtypes.h"
+
+struct pipe_context;
+struct pipe_texture;
+struct pipe_region;
+
+
+extern struct pipe_texture *
+st_texture_create(struct st_context *st,
+                  unsigned target,
+                 unsigned format,
+                  GLenum internal_format,
+                  GLuint first_level,
+                  GLuint last_level,
+                  GLuint width0,
+                  GLuint height0,
+                  GLuint depth0,
+                  GLuint compress_byte);
+
+
+/* Check if an image fits an existing texture
+ */
+extern GLboolean
+st_texture_match_image(struct pipe_texture *pt,
+                       struct gl_texture_image *image,
+                       GLuint face, GLuint level);
+
+/* Return a pointer to an image within a texture.  Return image stride as
+ * well.
+ */
+extern GLubyte *
+st_texture_image_map(struct st_context *st,
+                     struct st_texture_image *stImage,
+                    GLuint zoffset);
+
+extern void
+st_texture_image_unmap(struct st_context *st,
+                       struct st_texture_image *stImage);
+
+
+/* Return pointers to each 2d slice within an image.  Indexed by depth
+ * value.
+ */
+extern const GLuint *
+st_texture_depth_offsets(struct pipe_texture *pt, GLuint level);
+
+
+/* Return the linear offset of an image relative to the start of its region:
+ */
+extern GLuint
+st_texture_image_offset(const struct pipe_texture *pt,
+                        GLuint face, GLuint level);
+
+extern GLuint
+st_texture_texel_offset(const struct pipe_texture * pt,
+                        GLuint face, GLuint level,
+                        GLuint col, GLuint row, GLuint img);
+
+
+/* Upload an image into a texture
+ */
+extern void
+st_texture_image_data(struct pipe_context *pipe,
+                      struct pipe_texture *dst,
+                      GLuint face, GLuint level, void *src,
+                      GLuint src_row_pitch, GLuint src_image_pitch);
+
+
+/* Copy an image between two textures
+ */
+extern void
+st_texture_image_copy(struct pipe_context *pipe,
+                      struct pipe_texture *dst,
+                      GLuint face, GLuint level,
+                      struct pipe_texture *src);
+
+
+#endif