Ejemplo n.º 1
0
static void
brw_miptree_layout_texture_array(struct intel_context *intel,
				 struct intel_mipmap_tree *mt)
{
   GLuint level;
   GLuint qpitch = 0;
   int h0, h1, q;

   h0 = ALIGN(mt->physical_height0, mt->align_h);
   h1 = ALIGN(minify(mt->physical_height0), mt->align_h);
   if (mt->array_spacing_lod0)
      qpitch = h0;
   else
      qpitch = (h0 + h1 + (intel->gen >= 7 ? 12 : 11) * mt->align_h);
   if (mt->compressed)
      qpitch /= 4;

   i945_miptree_layout_2d(mt);

   for (level = mt->first_level; level <= mt->last_level; level++) {
      for (q = 0; q < mt->physical_depth0; q++) {
	 intel_miptree_set_image_offset(mt, level, q, 0, q * qpitch);
      }
   }
   mt->total_height = qpitch * mt->physical_depth0;
}
Ejemplo n.º 2
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;
   }