Home | History | Annotate | Download | only in i915
      1 /**************************************************************************
      2  *
      3  * Copyright 2006 VMware, Inc.
      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 VMWARE 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 #ifndef INTEL_MIPMAP_TREE_H
     29 #define INTEL_MIPMAP_TREE_H
     30 
     31 #include <assert.h>
     32 
     33 #include "intel_screen.h"
     34 #include "intel_regions.h"
     35 #include "GL/internal/dri_interface.h"
     36 
     37 /* A layer on top of the intel_regions code which adds:
     38  *
     39  * - Code to size and layout a region to hold a set of mipmaps.
     40  * - Query to determine if a new image fits in an existing tree.
     41  * - More refcounting
     42  *     - maybe able to remove refcounting from intel_region?
     43  * - ?
     44  *
     45  * The fixed mipmap layout of intel hardware where one offset
     46  * specifies the position of all images in a mipmap hierachy
     47  * complicates the implementation of GL texture image commands,
     48  * compared to hardware where each image is specified with an
     49  * independent offset.
     50  *
     51  * In an ideal world, each texture object would be associated with a
     52  * single bufmgr buffer or 2d intel_region, and all the images within
     53  * the texture object would slot into the tree as they arrive.  The
     54  * reality can be a little messier, as images can arrive from the user
     55  * with sizes that don't fit in the existing tree, or in an order
     56  * where the tree layout cannot be guessed immediately.
     57  *
     58  * This structure encodes an idealized mipmap tree.  The GL image
     59  * commands build these where possible, otherwise store the images in
     60  * temporary system buffers.
     61  */
     62 
     63 struct intel_texture_image;
     64 
     65 struct intel_miptree_map {
     66    /** Bitfield of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_BIT */
     67    GLbitfield mode;
     68    /** Region of interest for the map. */
     69    int x, y, w, h;
     70    /** Possibly malloced temporary buffer for the mapping. */
     71    void *buffer;
     72    /** Possible pointer to a temporary linear miptree for the mapping. */
     73    struct intel_mipmap_tree *mt;
     74    /** Pointer to the start of (map_x, map_y) returned by the mapping. */
     75    void *ptr;
     76    /** Stride of the mapping. */
     77    int stride;
     78 };
     79 
     80 /**
     81  * Describes the location of each texture image within a texture region.
     82  */
     83 struct intel_mipmap_level
     84 {
     85    /** Offset to this miptree level, used in computing x_offset. */
     86    GLuint level_x;
     87    /** Offset to this miptree level, used in computing y_offset. */
     88    GLuint level_y;
     89    GLuint width;
     90    GLuint height;
     91 
     92    /**
     93     * \brief Number of 2D slices in this miplevel.
     94     *
     95     * The exact semantics of depth varies according to the texture target:
     96     *    - For GL_TEXTURE_CUBE_MAP, depth is 6.
     97     *    - For GL_TEXTURE_3D, it is the texture's depth at this miplevel. Its
     98     *      value, like width and height, varies with miplevel.
     99     *    - For other texture types, depth is 1.
    100     */
    101    GLuint depth;
    102 
    103    /**
    104     * \brief List of 2D images in this mipmap level.
    105     *
    106     * This may be a list of cube faces, array slices in 2D array texture, or
    107     * layers in a 3D texture. The list's length is \c depth.
    108     */
    109    struct intel_mipmap_slice {
    110       /**
    111        * \name Offset to slice
    112        * \{
    113        *
    114        * Hardware formats are so diverse that that there is no unified way to
    115        * compute the slice offsets, so we store them in this table.
    116        *
    117        * The (x, y) offset to slice \c s at level \c l relative the miptrees
    118        * base address is
    119        * \code
    120        *     x = mt->level[l].slice[s].x_offset
    121        *     y = mt->level[l].slice[s].y_offset
    122        */
    123       GLuint x_offset;
    124       GLuint y_offset;
    125       /** \} */
    126 
    127       /**
    128        * Mapping information. Persistent for the duration of
    129        * intel_miptree_map/unmap on this slice.
    130        */
    131       struct intel_miptree_map *map;
    132    } *slice;
    133 };
    134 
    135 
    136 struct intel_mipmap_tree
    137 {
    138    /* Effectively the key:
    139     */
    140    GLenum target;
    141 
    142    /**
    143     * This is just the same as the gl_texture_image->TexFormat or
    144     * gl_renderbuffer->Format.
    145     */
    146    mesa_format format;
    147 
    148    /**
    149     * The X offset of each image in the miptree must be aligned to this. See
    150     * the "Alignment Unit Size" section of the BSpec.
    151     */
    152    unsigned int align_w;
    153    unsigned int align_h; /**< \see align_w */
    154 
    155    GLuint first_level;
    156    GLuint last_level;
    157 
    158    /**
    159     * Level zero image dimensions.  These dimensions correspond to the
    160     * physical layout of data in memory.  Accordingly, they account for the
    161     * extra factor of 6 in depth that must be allocated in order to
    162     * accommodate cubemap textures.
    163     */
    164    GLuint physical_width0, physical_height0, physical_depth0;
    165 
    166    GLuint cpp;
    167    bool compressed;
    168 
    169    /* Derived from the above:
    170     */
    171    GLuint total_width;
    172    GLuint total_height;
    173 
    174    /* Includes image offset tables:
    175     */
    176    struct intel_mipmap_level level[MAX_TEXTURE_LEVELS];
    177 
    178    /* The data is held here:
    179     */
    180    struct intel_region *region;
    181 
    182    /* Offset into region bo where miptree starts:
    183     */
    184    uint32_t offset;
    185 
    186    /* These are also refcounted:
    187     */
    188    GLuint refcount;
    189 };
    190 
    191 enum intel_miptree_tiling_mode {
    192    INTEL_MIPTREE_TILING_ANY,
    193    INTEL_MIPTREE_TILING_Y,
    194    INTEL_MIPTREE_TILING_NONE,
    195 };
    196 
    197 struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
    198                                                GLenum target,
    199 					       mesa_format format,
    200                                                GLuint first_level,
    201                                                GLuint last_level,
    202                                                GLuint width0,
    203                                                GLuint height0,
    204                                                GLuint depth0,
    205 					       bool expect_accelerated_upload,
    206                                                enum intel_miptree_tiling_mode);
    207 
    208 struct intel_mipmap_tree *
    209 intel_miptree_create_layout(struct intel_context *intel,
    210                             GLenum target,
    211                             mesa_format format,
    212                             GLuint first_level,
    213                             GLuint last_level,
    214                             GLuint width0,
    215                             GLuint height0,
    216                             GLuint depth0);
    217 
    218 struct intel_mipmap_tree *
    219 intel_miptree_create_for_bo(struct intel_context *intel,
    220                             drm_intel_bo *bo,
    221                             mesa_format format,
    222                             uint32_t offset,
    223                             uint32_t width,
    224                             uint32_t height,
    225                             int pitch,
    226                             uint32_t tiling);
    227 
    228 struct intel_mipmap_tree*
    229 intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
    230                                      unsigned dri_attachment,
    231                                      mesa_format format,
    232                                      struct intel_region *region);
    233 
    234 struct intel_mipmap_tree*
    235 intel_miptree_create_for_image_buffer(struct intel_context *intel,
    236                                       enum __DRIimageBufferMask buffer_type,
    237                                       mesa_format format,
    238                                       uint32_t num_samples,
    239                                       struct intel_region *region);
    240 
    241 /**
    242  * Create a miptree appropriate as the storage for a non-texture renderbuffer.
    243  * The miptree has the following properties:
    244  *     - The target is GL_TEXTURE_2D.
    245  *     - There are no levels other than the base level 0.
    246  *     - Depth is 1.
    247  */
    248 struct intel_mipmap_tree*
    249 intel_miptree_create_for_renderbuffer(struct intel_context *intel,
    250                                       mesa_format format,
    251                                       uint32_t width,
    252                                       uint32_t height);
    253 
    254 /** \brief Assert that the level and layer are valid for the miptree. */
    255 static inline void
    256 intel_miptree_check_level_layer(struct intel_mipmap_tree *mt,
    257                                 uint32_t level,
    258                                 uint32_t layer)
    259 {
    260    (void) mt;
    261    (void) level;
    262    (void) layer;
    263 
    264    assert(level >= mt->first_level);
    265    assert(level <= mt->last_level);
    266    assert(layer < mt->level[level].depth);
    267 }
    268 
    269 int intel_miptree_pitch_align (struct intel_context *intel,
    270 			       struct intel_mipmap_tree *mt,
    271 			       uint32_t tiling,
    272 			       int pitch);
    273 
    274 void intel_miptree_reference(struct intel_mipmap_tree **dst,
    275                              struct intel_mipmap_tree *src);
    276 
    277 void intel_miptree_release(struct intel_mipmap_tree **mt);
    278 
    279 /* Check if an image fits an existing mipmap tree layout
    280  */
    281 bool intel_miptree_match_image(struct intel_mipmap_tree *mt,
    282                                     struct gl_texture_image *image);
    283 
    284 void
    285 intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
    286 			       GLuint level, GLuint slice,
    287 			       GLuint *x, GLuint *y);
    288 
    289 void
    290 intel_miptree_get_dimensions_for_image(struct gl_texture_image *image,
    291                                        int *width, int *height, int *depth);
    292 
    293 uint32_t
    294 intel_miptree_get_tile_offsets(struct intel_mipmap_tree *mt,
    295                                GLuint level, GLuint slice,
    296                                uint32_t *tile_x,
    297                                uint32_t *tile_y);
    298 
    299 void intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
    300                                   GLuint level,
    301                                   GLuint x, GLuint y,
    302                                   GLuint w, GLuint h, GLuint d);
    303 
    304 void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
    305                                     GLuint level,
    306                                     GLuint img, GLuint x, GLuint y);
    307 
    308 void
    309 intel_miptree_copy_teximage(struct intel_context *intel,
    310                             struct intel_texture_image *intelImage,
    311                             struct intel_mipmap_tree *dst_mt, bool invalidate);
    312 
    313 /**\}*/
    314 
    315 /* i915_mipmap_tree.c:
    316  */
    317 void i915_miptree_layout(struct intel_mipmap_tree *mt);
    318 void i945_miptree_layout(struct intel_mipmap_tree *mt);
    319 
    320 void *intel_miptree_map_raw(struct intel_context *intel,
    321                             struct intel_mipmap_tree *mt);
    322 
    323 void intel_miptree_unmap_raw(struct intel_mipmap_tree *mt);
    324 
    325 void
    326 intel_miptree_map(struct intel_context *intel,
    327 		  struct intel_mipmap_tree *mt,
    328 		  unsigned int level,
    329 		  unsigned int slice,
    330 		  unsigned int x,
    331 		  unsigned int y,
    332 		  unsigned int w,
    333 		  unsigned int h,
    334 		  GLbitfield mode,
    335 		  void **out_ptr,
    336 		  int *out_stride);
    337 
    338 void
    339 intel_miptree_unmap(struct intel_context *intel,
    340 		    struct intel_mipmap_tree *mt,
    341 		    unsigned int level,
    342 		    unsigned int slice);
    343 
    344 
    345 #endif
    346