Exemplo n.º 1
0
static void
i915_miptree_layout_2d(struct intel_context *intel,
		       struct intel_mipmap_tree * mt,
		       uint32_t tiling)
{
   GLuint width = mt->width0;
   GLuint height = mt->height0;
   GLuint img_height;
   GLint level;

   mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, 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);
   }
}
Exemplo n.º 2
0
static void
i915_miptree_layout_2d(struct intel_mipmap_tree * mt)
{
   GLuint width = mt->width0;
   GLuint height = mt->height0;
   GLuint img_height;
   GLint level;

   mt->total_width = mt->width0;
   mt->total_height = 0;

   for (level = mt->first_level; level <= mt->last_level; level++) {
      intel_miptree_set_level_info(mt, level,
				   0, mt->total_height,
				   width, height, 1);

      if (mt->compressed)
	 img_height = ALIGN(height, 4) / 4;
      else
	 img_height = ALIGN(height, 2);

      mt->total_height += img_height;

      width = minify(width);
      height = minify(height);
   }
}
Exemplo n.º 3
0
static void
gen9_miptree_layout_1d(struct intel_mipmap_tree *mt)
{
   unsigned x = 0;
   unsigned width = mt->physical_width0;
   unsigned depth = mt->physical_depth0; /* number of array layers. */

   /* When this layout is used the horizontal alignment is fixed at 64 and the
    * hardware ignores the value given in the surface state
    */
   const unsigned int align_w = 64;

   mt->total_height = mt->physical_height0;
   mt->total_width = 0;

   for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
      unsigned img_width;

      intel_miptree_set_level_info(mt, level, x, 0, depth);

      img_width = ALIGN(width, align_w);

      mt->total_width = MAX2(mt->total_width, x + img_width);

      x += img_width;

      width = minify(width, 1);
   }
}
Exemplo n.º 4
0
static void
i945_miptree_layout_3d(struct intel_context *intel,
		       struct intel_mipmap_tree * mt,
		       uint32_t tiling)
{
   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, tiling, 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;
      }
Exemplo n.º 5
0
static void
i915_miptree_layout_3d(struct intel_context *intel,
		       struct intel_mipmap_tree * mt,
		       uint32_t tiling)
{
   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, tiling, 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;
}
Exemplo n.º 6
0
/**
 * 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,
			 uint32_t tiling)
{
   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, tiling, 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)
	    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;
      }
   }
}
Exemplo n.º 7
0
static void
brw_miptree_layout_texture_3d(struct brw_context *brw,
                              struct intel_mipmap_tree *mt)
{
   mt->total_width = 0;
   mt->total_height = 0;

   unsigned ysum = 0;
   unsigned bh, bw;

   _mesa_get_format_block_size(mt->format, &bw, &bh);

   for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
      unsigned WL = MAX2(mt->physical_width0 >> level, 1);
      unsigned HL = MAX2(mt->physical_height0 >> level, 1);
      unsigned DL = MAX2(mt->physical_depth0 >> level, 1);
      unsigned wL = ALIGN_NPOT(WL, mt->align_w);
      unsigned hL = ALIGN_NPOT(HL, mt->align_h);

      if (mt->target == GL_TEXTURE_CUBE_MAP)
         DL = 6;

      intel_miptree_set_level_info(mt, level, 0, 0, DL);

      for (unsigned q = 0; q < DL; q++) {
         unsigned x = (q % (1 << level)) * wL;
         unsigned y = ysum + (q >> level) * hL;

         intel_miptree_set_image_offset(mt, level, q, x / bw, y / bh);
         mt->total_width = MAX2(mt->total_width, (x + wL) / bw);
         mt->total_height = MAX2(mt->total_height, (y + hL) / bh);
      }

      ysum += ALIGN(DL, 1 << level) / (1 << level) * hL;
   }

   align_cube(mt);
}
Exemplo n.º 8
0
static void
brw_miptree_layout_texture_3d(struct brw_context *brw,
                              struct intel_mipmap_tree *mt)
{
   unsigned yscale = mt->compressed ? 4 : 1;

   mt->total_width = 0;
   mt->total_height = 0;

   unsigned ysum = 0;
   for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
      unsigned WL = MAX2(mt->physical_width0 >> level, 1);
      unsigned HL = MAX2(mt->physical_height0 >> level, 1);
      unsigned DL = MAX2(mt->physical_depth0 >> level, 1);
      unsigned wL = ALIGN(WL, mt->align_w);
      unsigned hL = ALIGN(HL, mt->align_h);

      if (mt->target == GL_TEXTURE_CUBE_MAP)
         DL = 6;

      intel_miptree_set_level_info(mt, level, 0, 0, WL, HL, DL);

      for (unsigned q = 0; q < DL; q++) {
         unsigned x = (q % (1 << level)) * wL;
         unsigned y = ysum + (q >> level) * hL;

         intel_miptree_set_image_offset(mt, level, q, x, y / yscale);
         mt->total_width = MAX2(mt->total_width, x + wL);
         mt->total_height = MAX2(mt->total_height, (y + hL) / yscale);
      }

      ysum += ALIGN(DL, 1 << level) / (1 << level) * hL;
   }

   align_cube(mt);
}
Exemplo n.º 9
0
static void
brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
{
   unsigned x = 0;
   unsigned y = 0;
   unsigned width = mt->physical_width0;
   unsigned height = mt->physical_height0;
   unsigned depth = mt->physical_depth0; /* number of array layers. */

   mt->total_width = mt->physical_width0;

   if (mt->compressed) {
       mt->total_width = ALIGN(mt->physical_width0, mt->align_w);
   }

   /* May need to adjust width 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;

       if (mt->compressed) {
          mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
             ALIGN(minify(mt->physical_width0, 2), mt->align_w);
       } else {
          mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
             minify(mt->physical_width0, 2);
       }

       if (mip1_width > mt->total_width) {
           mt->total_width = mip1_width;
       }
   }

   mt->total_height = 0;

   for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
      unsigned img_height;

      intel_miptree_set_level_info(mt, level, x, y, width,
				   height, depth);

      img_height = ALIGN(height, mt->align_h);
      if (mt->compressed)
	 img_height /= mt->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, mt->align_w);
      } else {
	 y += img_height;
      }

      width  = minify(width, 1);
      height = minify(height, 1);
   }
}
Exemplo n.º 10
0
GLboolean brw_miptree_layout(struct intel_context *intel,
                             struct intel_mipmap_tree *mt,
                             uint32_t tiling)
{
    /* XXX: these vary depending on image format: */
    /* GLint align_w = 4; */

    switch (mt->target) {
    case GL_TEXTURE_CUBE_MAP:
        if (IS_IGDNG(intel->intelScreen->deviceID)) {
            GLuint align_h = 2, align_w = 4;
            GLuint level;
            GLuint x = 0;
            GLuint y = 0;
            GLuint width = mt->width0;
            GLuint height = mt->height0;
            GLuint qpitch = 0;
            GLuint y_pitch = 0;

            mt->pitch = mt->width0;
            intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
            y_pitch = ALIGN(height, align_h);

            if (mt->compressed) {
                mt->pitch = ALIGN(mt->width0, align_w);
            }

            if (mt->first_level != mt->last_level) {
                GLuint mip1_width;

                if (mt->compressed) {
                    mip1_width = ALIGN(minify(mt->width0), align_w)
                                 + ALIGN(minify(minify(mt->width0)), align_w);
                } else {
                    mip1_width = ALIGN(minify(mt->width0), align_w)
                                 + minify(minify(mt->width0));
                }

                if (mip1_width > mt->pitch) {
                    mt->pitch = mip1_width;
                }
            }

            mt->pitch = intel_miptree_pitch_align(intel, mt, tiling, mt->pitch);

            if (mt->compressed) {
                qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4;
                mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6;
            } else {
                qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h);
                mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6;
            }

            for (level = mt->first_level; level <= mt->last_level; level++) {
                GLuint img_height;
                GLuint nr_images = 6;
                GLuint q = 0;

                intel_miptree_set_level_info(mt, level, nr_images, x, y, width,
                                             height, 1);

                for (q = 0; q < nr_images; q++)
                    intel_miptree_set_image_offset(mt, level, q,
                                                   x, y + q * qpitch);

                if (mt->compressed)
                    img_height = MAX2(1, height/4);
                else
                    img_height = ALIGN(height, align_h);

                if (level == mt->first_level + 1) {
                    x += ALIGN(width, align_w);
                }
                else {
                    y += img_height;
                }

                width  = minify(width);
                height = minify(height);
            }

            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;
        GLuint align_h = 2;
        GLuint align_w = 4;

        mt->total_height = 0;
        intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);

        if (mt->compressed) {
            mt->pitch = ALIGN(width, align_w);
            pack_y_pitch = (height + 3) / 4;
        } else {
            mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
            pack_y_pitch = ALIGN(mt->height0, align_h);
        }

        pack_x_pitch = width;
        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;
            width  = minify(width);
            height = minify(height);
            depth  = minify(depth);

            if (mt->compressed) {
                pack_y_pitch = (height + 3) / 4;

                if (pack_x_pitch > ALIGN(width, align_w)) {
                    pack_x_pitch = ALIGN(width, align_w);
                    pack_x_nr <<= 1;
                }
            } else {
                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;
                    pack_y_pitch = ALIGN(pack_y_pitch, align_h);
                }
            }

        }
        /* The 965's sampler lays cachelines out according to how accesses
         * in the texture surfaces run, so they may be "vertical" through
         * memory.  As a result, the docs say in Surface Padding Requirements:
         * Sampling Engine Surfaces that two extra rows of padding are required.
         * We don't know of similar requirements for pre-965, but given that
         * those docs are silent on padding requirements in general, let's play
         * it safe.
         */
        if (mt->target == GL_TEXTURE_CUBE_MAP)
            mt->total_height += 2;
        break;
    }
Exemplo n.º 11
0
GLboolean
i915_miptree_layout(struct intel_context *intel, struct intel_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 = 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;
            }
         }
         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 = 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;
         break;
      }

   default:{
         GLuint width = mt->width0;
         GLuint height = mt->height0;
	 GLuint img_height;

         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);
         }
         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;
}
Exemplo n.º 12
0
GLboolean
i945_miptree_layout(struct intel_context *intel, struct intel_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 = intel_miptree_pitch_align (intel, mt, dim);
         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 = 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++) {
            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;
      }
Exemplo n.º 13
0
static void
brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
{
   unsigned x = 0;
   unsigned y = 0;
   unsigned width = mt->physical_width0;
   unsigned height = mt->physical_height0;
   unsigned depth = mt->physical_depth0; /* number of array layers. */
   unsigned int bw, bh;

   _mesa_get_format_block_size(mt->format, &bw, &bh);

   mt->total_width = mt->physical_width0;

   if (mt->compressed)
       mt->total_width = ALIGN_NPOT(mt->total_width, bw);

   /* May need to adjust width to accommodate 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;

       if (mt->compressed) {
          mip1_width = ALIGN_NPOT(minify(mt->physical_width0, 1), mt->align_w) +
             ALIGN_NPOT(minify(mt->physical_width0, 2), bw);
       } else {
          mip1_width = ALIGN_NPOT(minify(mt->physical_width0, 1), mt->align_w) +
             minify(mt->physical_width0, 2);
       }

       if (mip1_width > mt->total_width) {
           mt->total_width = mip1_width;
       }
   }

   mt->total_width /= bw;
   mt->total_height = 0;

   for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
      unsigned img_height;

      intel_miptree_set_level_info(mt, level, x, y, depth);

      img_height = ALIGN_NPOT(height, mt->align_h);
      if (mt->compressed)
	 img_height /= bh;

      if (mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
         /* Compact arrays with separated miplevels */
         img_height *= depth;
      }

      /* 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_NPOT(width, mt->align_w) / bw;
      } else {
	 y += img_height;
      }

      width  = minify(width, 1);
      height = minify(height, 1);

      if (mt->target == GL_TEXTURE_3D)
         depth = minify(depth, 1);
   }
}
Exemplo n.º 14
0
void
brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt)
{
   switch (mt->target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
      brw_miptree_layout_texture_array(intel, mt);
      break;

   case GL_TEXTURE_CUBE_MAP:
      if (intel->gen >= 5) {
	 /* On Ironlake, cube maps are finally represented as just a series of
	  * MIPLAYOUT_BELOW 2D textures (like 2D texture arrays), separated by a
	  * pitch of qpitch rows, where qpitch is defined by the equation given
	  * in Volume 1 of the BSpec.
	  */
	 brw_miptree_layout_texture_array(intel, mt);
	 break;
      }
      assert(mt->physical_depth0 == 6);
      /* FALLTHROUGH */

   case GL_TEXTURE_3D: {
      GLuint width  = mt->physical_width0;
      GLuint height = mt->physical_height0;
      GLuint depth = mt->physical_depth0;
      GLuint pack_x_pitch, pack_x_nr;
      GLuint pack_y_pitch;
      GLuint level;

      mt->total_height = 0;

      if (mt->compressed) {
          mt->total_width = ALIGN(width, mt->align_w);
          pack_y_pitch = (height + 3) / 4;
      } else {
	 mt->total_width = mt->physical_width0;
	 pack_y_pitch = ALIGN(mt->physical_height0, mt->align_h);
      }

      pack_x_pitch = width;
      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,
				      0, mt->total_height,
				      width, height, depth);

	 for (q = 0; q < depth; /* empty */) {
	    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;
	    }
            if (x > mt->total_width)
               mt->total_width = x;

	    x = 0;
	    y += pack_y_pitch;
	 }


	 mt->total_height += y;
	 width  = minify(width);
	 height = minify(height);
	 if (mt->target == GL_TEXTURE_3D)
	    depth = minify(depth);

	 if (mt->compressed) {
	    pack_y_pitch = (height + 3) / 4;

	    if (pack_x_pitch > ALIGN(width, mt->align_w)) {
	       pack_x_pitch = ALIGN(width, mt->align_w);
	       pack_x_nr <<= 1;
	    }
	 } else {
            pack_x_nr <<= 1;
	    if (pack_x_pitch > 4) {
	       pack_x_pitch >>= 1;
	    }

	    if (pack_y_pitch > 2) {
	       pack_y_pitch >>= 1;
	       pack_y_pitch = ALIGN(pack_y_pitch, mt->align_h);
	    }
	 }

      }
      /* The 965's sampler lays cachelines out according to how accesses
       * in the texture surfaces run, so they may be "vertical" through
       * memory.  As a result, the docs say in Surface Padding Requirements:
       * Sampling Engine Surfaces that two extra rows of padding are required.
       */
      if (mt->target == GL_TEXTURE_CUBE_MAP)
	 mt->total_height += 2;
      break;
   }
Exemplo n.º 15
0
GLboolean brw_miptree_layout(struct intel_context *intel,
			     struct intel_mipmap_tree *mt,
			     uint32_t tiling)
{
   /* XXX: these vary depending on image format: */
   /* GLint align_w = 4; */

   switch (mt->target) {
   case GL_TEXTURE_CUBE_MAP:
      if (intel->gen == 5) {
          GLuint align_h = 2;
          GLuint level;
          GLuint qpitch = 0;
	  int h0, h1, q;

	  /* On Ironlake, cube maps are finally represented as just a series
	   * of MIPLAYOUT_BELOW 2D textures (like 2D texture arrays), separated
	   * by a pitch of qpitch rows, where qpitch is defined by the equation
	   * given in Volume 1 of the BSpec.
	   */
	  h0 = ALIGN(mt->height0, align_h);
	  h1 = ALIGN(minify(h0), align_h);
	  qpitch = (h0 + h1 + 11 * align_h);
          if (mt->compressed)
	     qpitch /= 4;

	  i945_miptree_layout_2d(intel, mt, tiling, 6);

          for (level = mt->first_level; level <= mt->last_level; level++) {
	     for (q = 0; q < 6; q++) {
		intel_miptree_set_image_offset(mt, level, q, 0, q * qpitch);
	     }
          }
	  mt->total_height = qpitch * 6;

          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;
      GLuint align_h = 2;
      GLuint align_w = 4;

      mt->total_height = 0;
      intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);

      if (mt->compressed) {
          mt->pitch = ALIGN(width, align_w);
          pack_y_pitch = (height + 3) / 4;
      } else {
	 mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
	 pack_y_pitch = ALIGN(mt->height0, align_h);
      }

      pack_x_pitch = width;
      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;
	 width  = minify(width);
	 height = minify(height);
	 depth  = minify(depth);

	 if (mt->compressed) {
	    pack_y_pitch = (height + 3) / 4;

	    if (pack_x_pitch > ALIGN(width, align_w)) {
	       pack_x_pitch = ALIGN(width, align_w);
	       pack_x_nr <<= 1;
	    }
	 } else {
	    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;
	       pack_y_pitch = ALIGN(pack_y_pitch, align_h);
	    }
	 }

      }
      /* The 965's sampler lays cachelines out according to how accesses
       * in the texture surfaces run, so they may be "vertical" through
       * memory.  As a result, the docs say in Surface Padding Requirements:
       * Sampling Engine Surfaces that two extra rows of padding are required.
       * We don't know of similar requirements for pre-965, but given that
       * those docs are silent on padding requirements in general, let's play
       * it safe.
       */
      if (mt->target == GL_TEXTURE_CUBE_MAP)
	 mt->total_height += 2;
      break;
   }
Exemplo n.º 16
0
static void
i945_miptree_layout_cube(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->total_width = dim * 2;
   else
      mt->total_width = 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,
				   0, 0,
				   lvlWidth, lvlHeight, 6);
      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;
	    }
	    break;

	 case 2:
	    y = mt->total_height - 4;
	    x = bottom_offsets[face];
	    break;

	 case 1:
	    x += 48;
	    break;

	 default:
	    x += step_offsets[face][0] * d;
	    y += step_offsets[face][1] * d;
	    break;
	 }
      }
   }
}
Exemplo n.º 17
0
void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt )
{
   GLint align_h = 2, align_w = 4;
   GLuint level;
   GLuint x = 0;
   GLuint y = 0;
   GLuint width = mt->width0;
   GLuint height = mt->height0;

   mt->pitch = mt->width0;

   if (mt->compressed) {
       align_w = intel_compressed_alignment(mt->internal_format);
       mt->pitch = ALIGN(mt->width0, align_w);
   }

   /* 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) {
       GLuint mip1_width;

       if (mt->compressed) {
           mip1_width = ALIGN(minify(mt->width0), align_w)
               + ALIGN(minify(minify(mt->width0)), align_w);
       } else {
           mip1_width = ALIGN(minify(mt->width0), align_w)
               + minify(minify(mt->width0));
       }

       if (mip1_width > mt->pitch) {
           mt->pitch = mip1_width;
       }
   }

   /* Pitch must be a whole number of dwords, even though we
    * express it in texels.
    */
   mt->pitch = intel_miptree_pitch_align (intel, mt, mt->pitch);
   mt->total_height = 0;

   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);

      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);
   }
}