/**************************************************************************
 * 
 * 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_inlines.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 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_int(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_int(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_int(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_int(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->buffer = pipe->winsys->buffer_create(pipe->winsys, 64,
                                                   PIPE_BUFFER_USAGE_PIXEL,
                                                   tex->pitch * tex->base.cpp *
                                                   tex->total_height);

      if (!tex->buffer) {
	 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->buffer_reference(pipe->winsys, &tex->buffer, NULL);

      for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
         if (tex->image_offset[i])
            FREE(tex->image_offset[i]);

      FREE(tex);
   }
   *pt = NULL;
}
