Checkpoint lifting of intel_mipmap_tree (intel_mipmap_tree -> pipe_mipmap_tree and...
authorBrian <brian@i915.localnet.net>
Mon, 6 Aug 2007 17:22:00 +0000 (11:22 -0600)
committerBrian <brian@i915.localnet.net>
Mon, 6 Aug 2007 17:22:00 +0000 (11:22 -0600)
src/mesa/drivers/dri/i915pipe/intel_context.c
src/mesa/drivers/dri/i915pipe/intel_mipmap_tree.c
src/mesa/drivers/dri/i915pipe/intel_mipmap_tree.h
src/mesa/drivers/dri/i915pipe/intel_tex.h
src/mesa/drivers/dri/i915pipe/intel_tex_image.c
src/mesa/drivers/dri/i915pipe/intel_tex_validate.c
src/mesa/drivers/dri/intel/intel_tex_layout.c
src/mesa/drivers/dri/intel/intel_tex_layout.h
src/mesa/pipe/p_context.h
src/mesa/pipe/p_state.h

index d43b78411204bc62bba3316d91c09fe7092aa6f6..df34c360e57956d292e390df271c402badb99ffd 100644 (file)
@@ -53,6 +53,7 @@
 #include "intel_blit.h"
 #include "intel_buffer_objects.h"
 #include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
 
 #include "state_tracker/st_public.h"
 #include "state_tracker/st_context.h"
 #include "vblank.h"
 #include "utils.h"
 #include "xmlpool.h"            /* for symbolic values of enum-type options */
+
+#include "pipe/p_context.h"
+
+
+
 #ifndef INTEL_DEBUG
 int INTEL_DEBUG = (0);
 #endif
@@ -377,6 +383,26 @@ intelCreateContext(const __GLcontextModes * mesaVis,
 //   intel->pipe->glctx = ctx;
 //   intel_init_region_functions(intel->pipe);
 
+   switch (intel->intelScreen->deviceID) {
+   case PCI_CHIP_I945_G:
+   case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q33_G:
+   case PCI_CHIP_Q35_G:
+      intel->pipe->mipmap_tree_layout = i945_miptree_layout;
+      break;
+   case PCI_CHIP_I915_G:
+   case PCI_CHIP_I915_GM:
+   case PCI_CHIP_I830_M:
+   case PCI_CHIP_I855_GM:
+   case PCI_CHIP_I865_G:
+      intel->pipe->mipmap_tree_layout = i915_miptree_layout;
+   default:
+      assert(0); /*FIX*/
+   }
+
+
    /*
     * memory pools
     */
index 6717984f7d6ca776e04b4f3dcf539e061d3fb998..50e830281c4f71ac1f9cd5a896063c5f261e55af 100644 (file)
@@ -51,7 +51,7 @@ target_to_target(GLenum target)
    }
 }
 
-struct intel_mipmap_tree *
+struct pipe_mipmap_tree *
 intel_miptree_create(struct intel_context *intel,
                      GLenum target,
                      GLenum internal_format,
@@ -62,7 +62,7 @@ intel_miptree_create(struct intel_context *intel,
                      GLuint depth0, GLuint cpp, GLuint compress_byte)
 {
    GLboolean ok;
-   struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
+   struct pipe_mipmap_tree *mt = calloc(sizeof(*mt), 1);
 
    DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
        _mesa_lookup_enum_by_nr(target),
@@ -79,29 +79,7 @@ intel_miptree_create(struct intel_context *intel,
    mt->compressed = compress_byte ? 1 : 0;
    mt->refcount = 1; 
 
-   switch (intel->intelScreen->deviceID) {
-   case PCI_CHIP_I945_G:
-   case PCI_CHIP_I945_GM:
-   case PCI_CHIP_I945_GME:
-   case PCI_CHIP_G33_G:
-   case PCI_CHIP_Q33_G:
-   case PCI_CHIP_Q35_G:
-//      ok = i945_miptree_layout(mt);
-      break;
-   case PCI_CHIP_I915_G:
-   case PCI_CHIP_I915_GM:
-   case PCI_CHIP_I830_M:
-   case PCI_CHIP_I855_GM:
-   case PCI_CHIP_I865_G:
-   default:
-      /* All the i830 chips and the i915 use this layout:
-       */
-//      ok = i915_miptree_layout(mt);
-      break;
-   }
-   
-   ok = 0;                     /* TODO */
-
+   ok = intel->pipe->mipmap_tree_layout(intel->pipe, mt);
    if (ok)
       mt->region = intel->pipe->region_alloc(intel->pipe,
                                       mt->cpp, mt->pitch, mt->total_height);
@@ -116,8 +94,8 @@ intel_miptree_create(struct intel_context *intel,
 
 
 void
-intel_miptree_reference(struct intel_mipmap_tree **dst,
-                        struct intel_mipmap_tree *src)
+intel_miptree_reference(struct pipe_mipmap_tree **dst,
+                        struct pipe_mipmap_tree *src)
 {
    src->refcount++;
    *dst = src;
@@ -126,7 +104,7 @@ intel_miptree_reference(struct intel_mipmap_tree **dst,
 
 void
 intel_miptree_release(struct intel_context *intel,
-                      struct intel_mipmap_tree **mt)
+                      struct pipe_mipmap_tree **mt)
 {
    if (!*mt)
       return;
@@ -157,7 +135,7 @@ intel_miptree_release(struct intel_context *intel,
  * Not sure whether I want to pass gl_texture_image here.
  */
 GLboolean
-intel_miptree_match_image(struct intel_mipmap_tree *mt,
+intel_miptree_match_image(struct pipe_mipmap_tree *mt,
                           struct gl_texture_image *image,
                           GLuint face, GLuint level)
 {
@@ -184,7 +162,7 @@ intel_miptree_match_image(struct intel_mipmap_tree *mt,
 
 
 void
-intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
+intel_miptree_set_level_info(struct pipe_mipmap_tree *mt,
                              GLuint level,
                              GLuint nr_images,
                              GLuint x, GLuint y, GLuint w, GLuint h, GLuint d)
@@ -215,7 +193,7 @@ intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
 
 
 void
-intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
+intel_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
                                GLuint level, GLuint img, GLuint x, GLuint y)
 {
    if (img == 0 && level == 0)
@@ -237,7 +215,7 @@ intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
  * These functions present that view to mesa:
  */
 const GLuint *
-intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level)
+intel_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level)
 {
    static const GLuint zero = 0;
 
@@ -249,7 +227,7 @@ intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level)
 
 
 GLuint
-intel_miptree_image_offset(struct intel_mipmap_tree * mt,
+intel_miptree_image_offset(struct pipe_mipmap_tree * mt,
                            GLuint face, GLuint level)
 {
    if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)
@@ -269,7 +247,7 @@ intel_miptree_image_offset(struct intel_mipmap_tree * mt,
  */
 GLubyte *
 intel_miptree_image_map(struct intel_context * intel,
-                        struct intel_mipmap_tree * mt,
+                        struct pipe_mipmap_tree * mt,
                         GLuint face,
                         GLuint level,
                         GLuint * row_stride, GLuint * image_offsets)
@@ -291,7 +269,7 @@ intel_miptree_image_map(struct intel_context * intel,
 
 void
 intel_miptree_image_unmap(struct intel_context *intel,
-                          struct intel_mipmap_tree *mt)
+                          struct pipe_mipmap_tree *mt)
 {
    DBG("%s\n", __FUNCTION__);
    intel->pipe->region_unmap(intel->pipe, mt->region);
@@ -303,7 +281,7 @@ intel_miptree_image_unmap(struct intel_context *intel,
  */
 void
 intel_miptree_image_data(struct intel_context *intel,
-                         struct intel_mipmap_tree *dst,
+                         struct pipe_mipmap_tree *dst,
                          GLuint face,
                          GLuint level,
                          void *src,
@@ -336,9 +314,9 @@ intel_miptree_image_data(struct intel_context *intel,
  */
 void
 intel_miptree_image_copy(struct intel_context *intel,
-                         struct intel_mipmap_tree *dst,
+                         struct pipe_mipmap_tree *dst,
                          GLuint face, GLuint level,
-                         struct intel_mipmap_tree *src)
+                         struct pipe_mipmap_tree *src)
 {
    GLuint width = src->level[level].width;
    GLuint height = src->level[level].height;
index 09b2e362fcf099b9886db061b08279a0cc182aa0..94fb21372c5a20244cad903fc1eff6514a4ece5f 100644 (file)
 struct pipe_region;
 
 
-/* A layer on top of the pipe_regions code which adds:
- *
- * - Code to size and layout a region to hold a set of mipmaps.
- * - Query to determine if a new image fits in an existing tree.
- * - More refcounting 
- *     - maybe able to remove refcounting from pipe_region?
- * - ?
- *
- * The fixed mipmap layout of intel hardware where one offset
- * specifies the position of all images in a mipmap hierachy
- * complicates the implementation of GL texture image commands,
- * compared to hardware where each image is specified with an
- * independent offset.
- *
- * In an ideal world, each texture object would be associated with a
- * single bufmgr buffer or 2d pipe_region, and all the images within
- * the texture object would slot into the tree as they arrive.  The
- * reality can be a little messier, as images can arrive from the user
- * with sizes that don't fit in the existing tree, or in an order
- * where the tree layout cannot be guessed immediately.  
- * 
- * This structure encodes an idealized mipmap tree.  The GL image
- * commands build these where possible, otherwise store the images in
- * temporary system buffers.
- */
-
-
-/**
- * Describes the location of each texture image within a texture region.
- */
-struct intel_mipmap_level
-{
-   GLuint level_offset;
-   GLuint width;
-   GLuint height;
-   GLuint depth;
-   GLuint 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:
-    */
-   GLuint *image_offset;
-};
-
-struct intel_mipmap_tree
-{
-   /* Effectively the key:
-    */
-   GLenum target;
-   GLenum internal_format;
-
-   GLuint first_level;
-   GLuint last_level;
-
-   GLuint width0, height0, depth0; /**< Level zero image dimensions */
-   GLuint cpp;
-   GLboolean compressed;
-
-   /* Derived from the above:
-    */
-   GLuint pitch;
-   GLuint depth_pitch;          /* per-image on i945? */
-   GLuint total_height;
-
-   /* Includes image offset tables:
-    */
-   struct intel_mipmap_level level[MAX_TEXTURE_LEVELS];
-
-   /* The data is held here:
-    */
-   struct pipe_region *region;
-
-   /* These are also refcounted:
-    */
-   GLuint refcount;
-};
-
-
-
-struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
+struct pipe_mipmap_tree *intel_miptree_create(struct intel_context *intel,
                                                GLenum target,
                                                GLenum internal_format,
                                                GLuint first_level,
@@ -127,15 +45,15 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
                                                GLuint cpp,
                                                GLuint compress_byte);
 
-void intel_miptree_reference(struct intel_mipmap_tree **dst,
-                             struct intel_mipmap_tree *src);
+void intel_miptree_reference(struct pipe_mipmap_tree **dst,
+                             struct pipe_mipmap_tree *src);
 
 void intel_miptree_release(struct intel_context *intel,
-                           struct intel_mipmap_tree **mt);
+                           struct pipe_mipmap_tree **mt);
 
 /* Check if an image fits an existing mipmap tree layout
  */
-GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt,
+GLboolean intel_miptree_match_image(struct pipe_mipmap_tree *mt,
                                     struct gl_texture_image *image,
                                     GLuint face, GLuint level);
 
@@ -143,35 +61,35 @@ GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt,
  * well.
  */
 GLubyte *intel_miptree_image_map(struct intel_context *intel,
-                                 struct intel_mipmap_tree *mt,
+                                 struct pipe_mipmap_tree *mt,
                                  GLuint face,
                                  GLuint level,
                                  GLuint * row_stride, GLuint * image_stride);
 
 void intel_miptree_image_unmap(struct intel_context *intel,
-                               struct intel_mipmap_tree *mt);
+                               struct pipe_mipmap_tree *mt);
 
 
 /* Return the linear offset of an image relative to the start of the
  * tree:
  */
-GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
+GLuint intel_miptree_image_offset(struct pipe_mipmap_tree *mt,
                                   GLuint face, GLuint level);
 
 /* Return pointers to each 2d slice within an image.  Indexed by depth
  * value.
  */
-const GLuint *intel_miptree_depth_offsets(struct intel_mipmap_tree *mt,
+const GLuint *intel_miptree_depth_offsets(struct pipe_mipmap_tree *mt,
                                           GLuint level);
 
 
-void intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
+void intel_miptree_set_level_info(struct pipe_mipmap_tree *mt,
                                   GLuint level,
                                   GLuint nr_images,
                                   GLuint x, GLuint y,
                                   GLuint w, GLuint h, GLuint d);
 
-void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
+void intel_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
                                     GLuint level,
                                     GLuint img, GLuint x, GLuint y);
 
@@ -179,7 +97,7 @@ void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
 /* Upload an image into a tree
  */
 void intel_miptree_image_data(struct intel_context *intel,
-                              struct intel_mipmap_tree *dst,
+                              struct pipe_mipmap_tree *dst,
                               GLuint face,
                               GLuint level,
                               void *src,
@@ -188,14 +106,14 @@ void intel_miptree_image_data(struct intel_context *intel,
 /* Copy an image between two trees
  */
 void intel_miptree_image_copy(struct intel_context *intel,
-                              struct intel_mipmap_tree *dst,
+                              struct pipe_mipmap_tree *dst,
                               GLuint face, GLuint level,
-                              struct intel_mipmap_tree *src);
+                              struct pipe_mipmap_tree *src);
 
 /* i915_mipmap_tree.c:
  */
-GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt);
-GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt);
+GLboolean i915_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
+GLboolean i945_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
 
 
 
index 4a5081eee7a6989e89f0bd7100db659ffa8082b3..1ee239402e1c6daee82b0958707e24f0f0d31c71 100644 (file)
@@ -49,7 +49,7 @@ struct intel_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 intel_mipmap_tree *mt;
+   struct pipe_mipmap_tree *mt;
 
    GLboolean imageOverride;
    GLint depthOverride;
@@ -71,7 +71,7 @@ struct intel_texture_image
     * Else if intelImage->base.Data != NULL, image is stored there.
     * Else there is no image data.
     */
-   struct intel_mipmap_tree *mt;
+   struct pipe_mipmap_tree *mt;
 };
 
 
index 9f8e115533c63ea3b36f1d90d47ad9bcf78216bf..596493f45a17a6db1cc0feeeb5d89604e7333eeb 100644 (file)
@@ -16,9 +16,9 @@
 #include "texstore.h"
 
 #include "intel_context.h"
-#include "intel_mipmap_tree.h"
 #include "intel_buffer_objects.h"
 #include "intel_batchbuffer.h"
+#include "intel_mipmap_tree.h"
 #include "intel_tex.h"
 #include "intel_ioctl.h"
 #include "intel_blit.h"
index af18c26d55cd00ce3b09cfece487673cff46f8ad..242fe1237bbc269a0cd02d6b751cbede0c86497e 100644 (file)
@@ -6,6 +6,8 @@
 #include "intel_mipmap_tree.h"
 #include "intel_tex.h"
 
+#include "pipe/p_state.h"
+
 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
 /**
index fcb5cc390682587c36db93ff630d339b71269e30..bedd835cbb9f7136bbd97d03d57902aa2ad8a776 100644 (file)
   *   Michel Dänzer <michel@tungstengraphics.com>
   */
 
-#include "intel_mipmap_tree.h"
-#include "intel_tex_layout.h"
 #include "macros.h"
+#include "pipe/p_state.h"
+#include "intel_mipmap_tree.h"
+
 
+static GLuint minify( GLuint d )
+{
+   return MAX2(1, d>>1);
+}
 
 static int align(int value, int alignment)
 {
    return (value + alignment - 1) & ~(alignment - 1);
 }
 
-void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
+
+static void
+mipmaptree_set_level_info(struct pipe_mipmap_tree *mt,
+                          GLuint level,
+                          GLuint nr_images,
+                          GLuint x, GLuint y, GLuint w, GLuint h, GLuint d)
+{
+   assert(level < 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);
+
+   mt->level[level].image_offset = malloc(nr_images * sizeof(GLuint));
+   mt->level[level].image_offset[0] = 0;
+}
+
+
+static void
+i945_miptree_layout_2d( struct pipe_mipmap_tree *mt )
 {
    GLint align_h = 2, align_w = 4;
    GLuint level;
@@ -73,8 +113,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
    for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
       GLuint img_height;
 
-      intel_miptree_set_level_info(mt, level, 1, x, y, width, 
-                                  height, 1);
+      mipmaptree_set_level_info(mt, level, 1, x, y, width, height, 1);
 
       if (mt->compressed)
         img_height = MAX2(1, height/4);
@@ -100,3 +139,316 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
       height = minify(height);
    }
 }
+
+
+static const GLint initial_offsets[6][2] = {
+   {0, 0},
+   {0, 2},
+   {1, 0},
+   {1, 2},
+   {1, 1},
+   {1, 3}
+};
+
+static const GLint step_offsets[6][2] = {
+   {0, 2},
+   {0, 2},
+   {-1, 2},
+   {-1, 2},
+   {-1, 1},
+   {-1, 1}
+};
+
+
+GLboolean
+i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
+{
+   GLint level;
+
+   switch (mt->target) {
+   case GL_TEXTURE_CUBE_MAP:{
+         const GLuint dim = mt->width0;
+         GLuint face;
+         GLuint 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++) {
+            intel_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++) {
+            GLuint x = initial_offsets[face][0] * dim;
+            GLuint y = initial_offsets[face][1] * dim;
+            GLuint d = dim;
+
+            for (level = mt->first_level; level <= mt->last_level; level++) {
+               intel_miptree_set_image_offset(mt, level, face, x, y);
+
+               if (d == 0)
+                  _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n",
+                               face, level, mt->first_level, mt->last_level);
+
+               d >>= 1;
+               x += step_offsets[face][0] * d;
+               y += step_offsets[face][1] * d;
+            }
+         }
+         break;
+      }
+   case GL_TEXTURE_3D:{
+         GLuint width = mt->width0;
+         GLuint height = mt->height0;
+         GLuint depth = mt->depth0;
+         GLuint 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++) {
+            intel_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++) {
+            GLuint i;
+            for (i = 0; i < depth; i++) 
+               intel_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:{
+         GLuint width = mt->width0;
+         GLuint height = mt->height0;
+        GLuint 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++) {
+            intel_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 GL_TRUE;
+}
+
+
+GLboolean
+i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
+{
+   GLint level;
+
+   switch (mt->target) {
+   case GL_TEXTURE_CUBE_MAP:{
+         const GLuint dim = mt->width0;
+         GLuint face;
+         GLuint 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++) {
+            intel_miptree_set_level_info(mt, level, 6,
+                                         0, 0,
+                                         lvlWidth, lvlHeight, 1);
+           lvlWidth /= 2;
+           lvlHeight /= 2;
+        }
+
+
+         for (face = 0; face < 6; face++) {
+            GLuint x = initial_offsets[face][0] * dim;
+            GLuint y = initial_offsets[face][1] * dim;
+            GLuint 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++) {
+               intel_miptree_set_image_offset(mt, level, face, x, y);
+
+               d >>= 1;
+
+               switch (d) {
+               case 4:
+                  switch (face) {
+                  case FACE_POS_X:
+                  case FACE_NEG_X:
+                     x += step_offsets[face][0] * d;
+                     y += step_offsets[face][1] * d;
+                     break;
+                  case FACE_POS_Y:
+                  case FACE_NEG_Y:
+                     y += 12;
+                     x -= 8;
+                     break;
+                  case FACE_POS_Z:
+                  case 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 GL_TEXTURE_3D:{
+         GLuint width = mt->width0;
+         GLuint height = mt->height0;
+         GLuint depth = mt->depth0;
+         GLuint pack_x_pitch, pack_x_nr;
+         GLuint pack_y_pitch;
+         GLuint 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++) {
+            GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6;
+            GLint x = 0;
+            GLint y = 0;
+            GLint q, j;
+
+            intel_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++) {
+                  intel_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 GL_TEXTURE_1D:
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_RECTANGLE_ARB:
+         i945_miptree_layout_2d(mt);
+         break;
+   default:
+      _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()");
+   }
+
+   /*
+   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 GL_TRUE;
+}
index 1e37f8f525faa6da98e7dc138d1a4ca6ded5f6bd..cbd4b8e27ff11867f3d0f18d0ce13ae8c91ffa21 100644 (file)
@@ -33,9 +33,6 @@
 #include "macros.h"
 
 
-static GLuint minify( GLuint d )
-{
-   return MAX2(1, d>>1);
-}
+extern void i915_miptree_layout_2d( struct pipe_context *, struct pipe_mipmap_tree *mt );
 
-extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt );
+extern void i945_miptree_layout_2d( struct pipe_context *, struct pipe_mipmap_tree *mt );
index 76a25935672c74352690335e273299fc23ac0455..db9429f8d3f7134a38d995981741e1202aaf946a 100644 (file)
@@ -207,6 +207,14 @@ struct pipe_context {
                              unsigned long offset, 
                              unsigned long size, 
                              void *data);
+
+   /*
+    * Texture functions
+    */
+   GLboolean (*mipmap_tree_layout)( struct pipe_context *pipe,
+                                    struct pipe_mipmap_tree *mt );
+
+
 };
 
 
index 518110d4470a2e74bdb194c5ed774ab7b9568fb9..13b8813f4a4ff3a7751c711340acd724c44c293c 100644 (file)
@@ -292,6 +292,61 @@ struct pipe_texture_object
 };
 
 
+/**
+ * Describes the location of each texture image within a texture region.
+ */
+struct pipe_mipmap_level
+{
+   GLuint level_offset;
+   GLuint width;
+   GLuint height;
+   GLuint depth;
+   GLuint 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:
+    */
+   GLuint *image_offset;
+};
+
+struct pipe_mipmap_tree
+{
+   /* Effectively the key:
+    */
+   GLenum target;
+   GLenum internal_format;
+
+   GLuint first_level;
+   GLuint last_level;
+
+   GLuint width0, height0, depth0; /**< Level zero image dimensions */
+   GLuint cpp;
+   GLboolean compressed;
+
+   /* Derived from the above:
+    */
+   GLuint pitch;
+   GLuint depth_pitch;          /* per-image on i945? */
+   GLuint total_height;
+
+   /* Includes image offset tables:
+    */
+   struct pipe_mipmap_level level[MAX_TEXTURE_LEVELS];
+
+   /* The data is held here:
+    */
+   struct pipe_region *region;
+
+   /* These are also refcounted:
+    */
+   GLuint refcount;
+};
+
+
+
 struct pipe_buffer_handle;
 
 #define PIPE_BUFFER_FLAG_READ    0x1