/**************************************************************************
 * 
 * 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.
 * 
 **************************************************************************/

/** @file i915_tex_layout.c
 * Code to layout images in a mipmap tree for i830M-GM915 and G945 and beyond.
 */

#include "intel_mipmap_tree.h"
#include "intel_tex_layout.h"
#include "macros.h"
#include "intel_context.h"

#define FILE_DEBUG_FLAG DEBUG_TEXTURE

static GLint initial_offsets[6][2] = {
   [FACE_POS_X] = {0, 0},
   [FACE_POS_Y] = {1, 0},
   [FACE_POS_Z] = {1, 1},
   [FACE_NEG_X] = {0, 2},
   [FACE_NEG_Y] = {1, 2},
   [FACE_NEG_Z] = {1, 3},
};


static GLint step_offsets[6][2] = {
   [FACE_POS_X] = {0, 2},
   [FACE_POS_Y] = {-1, 2},
   [FACE_POS_Z] = {-1, 1},
   [FACE_NEG_X] = {0, 2},
   [FACE_NEG_Y] = {-1, 2},
   [FACE_NEG_Z] = {-1, 1},
};

/**
 * Cube texture map layout for i830M-GM915.
 *
 * Hardware layout looks like:
 *
 * +-------+-------+
 * |       |       |
 * |       |       |
 * |       |       |
 * |  +x   |  +y   |
 * |       |       |
 * |       |       |
 * |       |       |
 * |       |       |
 * +---+---+-------+
 * |   |   |       |
 * | +x| +y|       |
 * |   |   |       |
 * |   |   |       |
 * +-+-+---+  +z   |
 * | | |   |       |
 * +-+-+ +z|       |
 *   | |   |       |
 * +-+-+---+-------+
 * |       |       |
 * |       |       |
 * |       |       |
 * |  -x   |  -y   |
 * |       |       |
 * |       |       |
 * |       |       |
 * |       |       |
 * +---+---+-------+
 * |   |   |       |
 * | -x| -y|       |
 * |   |   |       |
 * |   |   |       |
 * +-+-+---+  -z   |
 * | | |   |       |
 * +-+-+ -z|       |
 *   | |   |       |
 *   +-+---+-------+
 *
 */
static void
i915_miptree_layout_cube(struct intel_context *intel,
			 struct intel_mipmap_tree * mt)
{
   const GLuint dim = mt->width0;
   GLuint face;
   GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;
   GLint level;

   assert(lvlWidth == lvlHeight); /* cubemap images are square */

   /* double pitch for cube layouts */
   mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2);
   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;
      }
   }
}

static void
i915_miptree_layout_3d(struct intel_context *intel,
		       struct intel_mipmap_tree * mt)
{
   GLuint width = mt->width0;
   GLuint height = mt->height0;
   GLuint depth = mt->depth0;
   GLuint stack_height = 0;
   GLint level;

   /* Calculate the size of a single slice. */
   mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);

   /* 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;
}

static void
i915_miptree_layout_2d(struct intel_context *intel,
		       struct intel_mipmap_tree * mt)
{
   GLuint width = mt->width0;
   GLuint height = mt->height0;
   GLuint img_height;
   GLint level;

   mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
   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);
   }
}

GLboolean
i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
{
   switch (mt->target) {
   case GL_TEXTURE_CUBE_MAP:
      i915_miptree_layout_cube(intel, mt);
      break;
   case GL_TEXTURE_3D:
      i915_miptree_layout_3d(intel, mt);
      break;
   case GL_TEXTURE_1D:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_RECTANGLE_ARB:
      i915_miptree_layout_2d(intel, mt);
      break;
   default:
      _mesa_problem(NULL, "Unexpected tex target in i915_miptree_layout()");
      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;
}


/**
 * Cube texture map layout for GM945 and later.
 *
 * The hardware layout looks like the 830-915 layout, except for the small
 * sizes.  A zoomed in view of the layout for 945 is:
 *
 * +-------+-------+
 * |  8x8  |  8x8  |
 * |       |       |
 * |       |       |
 * |  +x   |  +y   |
 * |       |       |
 * |       |       |
 * |       |       |
 * |       |       |
 * +---+---+-------+
 * |4x4|   |  8x8  |
 * | +x|   |       |
 * |   |   |       |
 * |   |   |       |
 * +---+   |  +z   |
 * |4x4|   |       |
 * | +y|   |       |
 * |   |   |       |
 * +---+   +-------+
 *
 * ...
 *
 * +-------+-------+
 * |  8x8  |  8x8  |
 * |       |       |
 * |       |       |
 * |  -x   |  -y   |
 * |       |       |
 * |       |       |
 * |       |       |
 * |       |       |
 * +---+---+-------+
 * |4x4|   |  8x8  |
 * | -x|   |       |
 * |   |   |       |
 * |   |   |       |
 * +---+   |  -z   |
 * |4x4|   |       |
 * | -y|   |       |
 * |   |   |       |
 * +---+   +---+---+---+---+---+---+---+---+---+
 * |4x4|   |4x4|   |2x2|   |2x2|   |2x2|   |2x2|
 * | +z|   | -z|   | +x|   | +y|   | +z|   | -x| ...
 * |   |   |   |   |   |   |   |   |   |   |   |
 * +---+   +---+   +---+   +---+   +---+   +---+
 *
 * The bottom row continues with the remaining 2x2 then the 1x1 mip contents
 * in order, with each of them aligned to a 4x4 block boundary.  Thus, for
 * 32x32 cube maps and smaller, the bottom row layout is going to dictate the
 * pitch of the tree.  For a tree with 4x4 images, the pitch is at least
 * 14 * 8 = 112 texels, for 2x2 it is at least 12 * 8 texels, and for 1x1
 * it is 6 * 8 texels.
 */

static void
i945_miptree_layout_cube(struct intel_context *intel,
			 struct intel_mipmap_tree * mt)
{
   const GLuint dim = mt->width0;
   GLuint face;
   GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;
   GLint level;

   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 = intel_miptree_pitch_align (intel, mt, dim * 2);
   else
      mt->pitch = intel_miptree_pitch_align (intel, mt, 14 * 8);

   if (dim >= 4)
      mt->total_height = dim * 4 + 4;
   else
      mt->total_height = 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;
	 }
      }
   }
}

static void
i945_miptree_layout_3d(struct intel_context *intel,
		       struct intel_mipmap_tree * mt)
{
   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 = intel_miptree_pitch_align (intel, mt, mt->width0);
   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++) {
      GLint x = 0;
      GLint y = 0;
      GLint q, j;

      intel_miptree_set_level_info(mt, level, depth,
				   0, mt->total_height,
				   width, height, depth);

      for (q = 0; q < depth;) {
	 for (j = 0; j < pack_x_nr && q < depth; 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);
   }
}

GLboolean
i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
{
   switch (mt->target) {
   case GL_TEXTURE_CUBE_MAP:
      i945_miptree_layout_cube(intel, mt);
      break;
   case GL_TEXTURE_3D:
      i945_miptree_layout_3d(intel, mt);
      break;
   case GL_TEXTURE_1D:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_RECTANGLE_ARB:
      i945_miptree_layout_2d(intel, mt);
      break;
   default:
      _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()");
      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;
}
