Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  /*
  28.   * Authors:
  29.   *   Keith Whitwell <keith@tungstengraphics.com>
  30.   *   Michel Dänzer <michel@tungstengraphics.com>
  31.   */
  32.  
  33. #include "intel_mipmap_tree.h"
  34. #include "intel_tex_layout.h"
  35. #include "intel_context.h"
  36.  
  37. #include "main/image.h"
  38. #include "main/macros.h"
  39.  
  40. static unsigned int
  41. intel_horizontal_texture_alignment_unit(struct intel_context *intel,
  42.                                        gl_format format)
  43. {
  44.    /**
  45.     * From the "Alignment Unit Size" section of various specs, namely:
  46.     * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
  47.     * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
  48.     * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
  49.     * - BSpec (for Ivybridge and slight variations in separate stencil)
  50.     *
  51.     * +----------------------------------------------------------------------+
  52.     * |                                        | alignment unit width  ("i") |
  53.     * | Surface Property                       |-----------------------------|
  54.     * |                                        | 915 | 965 | ILK | SNB | IVB |
  55.     * +----------------------------------------------------------------------+
  56.     * | YUV 4:2:2 format                       |  8  |  4  |  4  |  4  |  4  |
  57.     * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
  58.     * | FXT1  compressed format                |  8  |  8  |  8  |  8  |  8  |
  59.     * | Depth Buffer (16-bit)                  |  4  |  4  |  4  |  4  |  8  |
  60.     * | Depth Buffer (other)                   |  4  |  4  |  4  |  4  |  4  |
  61.     * | Separate Stencil Buffer                | N/A | N/A |  8  |  8  |  8  |
  62.     * | All Others                             |  4  |  4  |  4  |  4  |  4  |
  63.     * +----------------------------------------------------------------------+
  64.     *
  65.     * On IVB+, non-special cases can be overridden by setting the SURFACE_STATE
  66.     * "Surface Horizontal Alignment" field to HALIGN_4 or HALIGN_8.
  67.     */
  68.     if (_mesa_is_format_compressed(format)) {
  69.        /* The hardware alignment requirements for compressed textures
  70.         * happen to match the block boundaries.
  71.         */
  72.       unsigned int i, j;
  73.       _mesa_get_format_block_size(format, &i, &j);
  74.       return i;
  75.     }
  76.  
  77.    return 4;
  78. }
  79.  
  80. static unsigned int
  81. intel_vertical_texture_alignment_unit(struct intel_context *intel,
  82.                                      gl_format format)
  83. {
  84.    /**
  85.     * From the "Alignment Unit Size" section of various specs, namely:
  86.     * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
  87.     * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
  88.     * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
  89.     * - BSpec (for Ivybridge and slight variations in separate stencil)
  90.     *
  91.     * +----------------------------------------------------------------------+
  92.     * |                                        | alignment unit height ("j") |
  93.     * | Surface Property                       |-----------------------------|
  94.     * |                                        | 915 | 965 | ILK | SNB | IVB |
  95.     * +----------------------------------------------------------------------+
  96.     * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
  97.     * | FXT1  compressed format                |  4  |  4  |  4  |  4  |  4  |
  98.     * | Depth Buffer                           |  2  |  2  |  2  |  4  |  4  |
  99.     * | Separate Stencil Buffer                | N/A | N/A | N/A |  4  |  8  |
  100.     * | Multisampled (4x or 8x) render target  | N/A | N/A | N/A |  4  |  4  |
  101.     * | All Others                             |  2  |  2  |  2  |  2  |  2  |
  102.     * +----------------------------------------------------------------------+
  103.     *
  104.     * On SNB+, non-special cases can be overridden by setting the SURFACE_STATE
  105.     * "Surface Vertical Alignment" field to VALIGN_2 or VALIGN_4.
  106.     *
  107.     * We currently don't support multisampling.
  108.     */
  109.    if (_mesa_is_format_compressed(format))
  110.       return 4;
  111.  
  112.    return 2;
  113. }
  114.  
  115. void
  116. intel_get_texture_alignment_unit(struct intel_context *intel,
  117.                                  gl_format format,
  118.                                  unsigned int *w, unsigned int *h)
  119. {
  120.    *w = intel_horizontal_texture_alignment_unit(intel, format);
  121.    *h = intel_vertical_texture_alignment_unit(intel, format);
  122. }
  123.  
  124. void i945_miptree_layout_2d(struct intel_mipmap_tree *mt)
  125. {
  126.    GLuint level;
  127.    GLuint x = 0;
  128.    GLuint y = 0;
  129.    GLuint width = mt->physical_width0;
  130.    GLuint height = mt->physical_height0;
  131.    GLuint depth = mt->physical_depth0; /* number of array layers. */
  132.  
  133.    mt->total_width = mt->physical_width0;
  134.  
  135.    if (mt->compressed) {
  136.        mt->total_width = ALIGN(mt->physical_width0, mt->align_w);
  137.    }
  138.  
  139.    /* May need to adjust width to accomodate the placement of
  140.     * the 2nd mipmap.  This occurs when the alignment
  141.     * constraints of mipmap placement push the right edge of the
  142.     * 2nd mipmap out past the width of its parent.
  143.     */
  144.    if (mt->first_level != mt->last_level) {
  145.        GLuint mip1_width;
  146.  
  147.        if (mt->compressed) {
  148.           mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
  149.              ALIGN(minify(mt->physical_width0, 2), mt->align_w);
  150.        } else {
  151.           mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
  152.              minify(mt->physical_width0, 2);
  153.        }
  154.  
  155.        if (mip1_width > mt->total_width) {
  156.            mt->total_width = mip1_width;
  157.        }
  158.    }
  159.  
  160.    mt->total_height = 0;
  161.  
  162.    for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
  163.       GLuint img_height;
  164.  
  165.       intel_miptree_set_level_info(mt, level, x, y, width,
  166.                                    height, depth);
  167.  
  168.       img_height = ALIGN(height, mt->align_h);
  169.       if (mt->compressed)
  170.          img_height /= mt->align_h;
  171.  
  172.       /* Because the images are packed better, the final offset
  173.        * might not be the maximal one:
  174.        */
  175.       mt->total_height = MAX2(mt->total_height, y + img_height);
  176.  
  177.       /* Layout_below: step right after second mipmap.
  178.        */
  179.       if (level == mt->first_level + 1) {
  180.          x += ALIGN(width, mt->align_w);
  181.       }
  182.       else {
  183.          y += img_height;
  184.       }
  185.  
  186.       width  = minify(width, 1);
  187.       height = minify(height, 1);
  188.    }
  189. }
  190.