Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2014 LunarG, Inc.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Chia-I Wu <olv@lunarg.com>
  26.  */
  27.  
  28. #ifndef ILO_IMAGE_H
  29. #define ILO_IMAGE_H
  30.  
  31. #include "genhw/genhw.h"
  32. #include "intel_winsys.h"
  33.  
  34. #include "ilo_core.h"
  35. #include "ilo_dev.h"
  36.  
  37. enum ilo_image_aux_type {
  38.    ILO_IMAGE_AUX_NONE,
  39.    ILO_IMAGE_AUX_HIZ,
  40.    ILO_IMAGE_AUX_MCS,
  41. };
  42.  
  43. enum ilo_image_walk_type {
  44.    /*
  45.     * LODs of each array layer are first packed together in MIPLAYOUT_BELOW.
  46.     * Array layers are then stacked together vertically.
  47.     *
  48.     * This can be used for mipmapped 2D textures.
  49.     */
  50.    ILO_IMAGE_WALK_LAYER,
  51.  
  52.    /*
  53.     * Array layers of each LOD are first stacked together vertically and
  54.     * tightly.  LODs are then packed together in MIPLAYOUT_BELOW with each LOD
  55.     * starting at page boundaries.
  56.     *
  57.     * This is usually used for non-mipmapped 2D textures, as multiple LODs are
  58.     * not supported natively.
  59.     */
  60.    ILO_IMAGE_WALK_LOD,
  61.  
  62.    /*
  63.     * 3D slices of each LOD are first packed together horizontally and tightly
  64.     * with wrapping.  LODs are then stacked together vertically and tightly.
  65.     *
  66.     * This is used for 3D textures.
  67.     */
  68.    ILO_IMAGE_WALK_3D,
  69. };
  70.  
  71. /*
  72.  * When the walk type is ILO_IMAGE_WALK_LAYER, there is only a slice in each
  73.  * LOD and this is used to describe LODs in the first array layer.  Otherwise,
  74.  * there can be multiple slices in each LOD and this is used to describe the
  75.  * first slice in each LOD.
  76.  */
  77. struct ilo_image_lod {
  78.    /* physical position in pixels */
  79.    unsigned x;
  80.    unsigned y;
  81.  
  82.    /* physical size of a slice in pixels */
  83.    unsigned slice_width;
  84.    unsigned slice_height;
  85. };
  86.  
  87. /**
  88.  * Texture layout.
  89.  */
  90. struct ilo_image {
  91.    /* size, format, etc for programming hardware states */
  92.    unsigned width0;
  93.    unsigned height0;
  94.    unsigned depth0;
  95.    unsigned sample_count;
  96.    enum pipe_format format;
  97.    bool separate_stencil;
  98.  
  99.    /*
  100.     * width, height, and size of pixel blocks for conversion between pixel
  101.     * positions and memory offsets
  102.     */
  103.    unsigned block_width;
  104.    unsigned block_height;
  105.    unsigned block_size;
  106.  
  107.    enum ilo_image_walk_type walk;
  108.    bool interleaved_samples;
  109.  
  110.    enum gen_surface_tiling tiling;
  111.  
  112.    /* physical LOD slice alignments */
  113.    unsigned align_i;
  114.    unsigned align_j;
  115.  
  116.    struct ilo_image_lod lods[PIPE_MAX_TEXTURE_LEVELS];
  117.  
  118.    /* physical layer height for ILO_IMAGE_WALK_LAYER */
  119.    unsigned walk_layer_height;
  120.  
  121.    /* distance in bytes between two pixel block rows */
  122.    unsigned bo_stride;
  123.    /* number of pixel block rows */
  124.    unsigned bo_height;
  125.  
  126.    bool scanout;
  127.  
  128.    struct intel_bo *bo;
  129.  
  130.    struct {
  131.       enum ilo_image_aux_type type;
  132.  
  133.       /* bitmask of levels that can use aux */
  134.       unsigned enables;
  135.  
  136.       /* LOD offsets for ILO_IMAGE_WALK_LOD */
  137.       unsigned walk_lod_offsets[PIPE_MAX_TEXTURE_LEVELS];
  138.  
  139.       unsigned walk_layer_height;
  140.       unsigned bo_stride;
  141.       unsigned bo_height;
  142.  
  143.       struct intel_bo *bo;
  144.    } aux;
  145. };
  146.  
  147. struct pipe_resource;
  148.  
  149. void
  150. ilo_image_init(struct ilo_image *img,
  151.                const struct ilo_dev *dev,
  152.                const struct pipe_resource *templ);
  153.  
  154. bool
  155. ilo_image_init_for_imported(struct ilo_image *img,
  156.                             const struct ilo_dev *dev,
  157.                             const struct pipe_resource *templ,
  158.                             enum gen_surface_tiling tiling,
  159.                             unsigned bo_stride);
  160.  
  161. static inline void
  162. ilo_image_cleanup(struct ilo_image *img)
  163. {
  164.    intel_bo_unref(img->bo);
  165.    intel_bo_unref(img->aux.bo);
  166. }
  167.  
  168. static inline void
  169. ilo_image_set_bo(struct ilo_image *img, struct intel_bo *bo)
  170. {
  171.    intel_bo_unref(img->bo);
  172.    img->bo = intel_bo_ref(bo);
  173. }
  174.  
  175. static inline void
  176. ilo_image_set_aux_bo(struct ilo_image *img, struct intel_bo *bo)
  177. {
  178.    intel_bo_unref(img->aux.bo);
  179.    img->aux.bo = intel_bo_ref(bo);
  180. }
  181.  
  182. static inline bool
  183. ilo_image_can_enable_aux(const struct ilo_image *img, unsigned level)
  184. {
  185.    return (img->aux.bo && (img->aux.enables & (1 << level)));
  186. }
  187.  
  188. /**
  189.  * Convert from pixel position to 2D memory offset.
  190.  */
  191. static inline void
  192. ilo_image_pos_to_mem(const struct ilo_image *img,
  193.                      unsigned pos_x, unsigned pos_y,
  194.                      unsigned *mem_x, unsigned *mem_y)
  195. {
  196.    assert(pos_x % img->block_width == 0);
  197.    assert(pos_y % img->block_height == 0);
  198.  
  199.    *mem_x = pos_x / img->block_width * img->block_size;
  200.    *mem_y = pos_y / img->block_height;
  201. }
  202.  
  203. /**
  204.  * Convert from 2D memory offset to linear offset.
  205.  */
  206. static inline unsigned
  207. ilo_image_mem_to_linear(const struct ilo_image *img,
  208.                         unsigned mem_x, unsigned mem_y)
  209. {
  210.    return mem_y * img->bo_stride + mem_x;
  211. }
  212.  
  213. /**
  214.  * Convert from 2D memory offset to raw offset.
  215.  */
  216. static inline unsigned
  217. ilo_image_mem_to_raw(const struct ilo_image *img,
  218.                      unsigned mem_x, unsigned mem_y)
  219. {
  220.    unsigned tile_w, tile_h;
  221.  
  222.    switch (img->tiling) {
  223.    case GEN6_TILING_NONE:
  224.       tile_w = 1;
  225.       tile_h = 1;
  226.       break;
  227.    case GEN6_TILING_X:
  228.       tile_w = 512;
  229.       tile_h = 8;
  230.       break;
  231.    case GEN6_TILING_Y:
  232.       tile_w = 128;
  233.       tile_h = 32;
  234.       break;
  235.    case GEN8_TILING_W:
  236.       tile_w = 64;
  237.       tile_h = 64;
  238.       break;
  239.    default:
  240.       assert(!"unknown tiling");
  241.       tile_w = 1;
  242.       tile_h = 1;
  243.       break;
  244.    }
  245.  
  246.    assert(mem_x % tile_w == 0);
  247.    assert(mem_y % tile_h == 0);
  248.  
  249.    return mem_y * img->bo_stride + mem_x * tile_h;
  250. }
  251.  
  252. /**
  253.  * Return the stride, in bytes, between slices within a level.
  254.  */
  255. static inline unsigned
  256. ilo_image_get_slice_stride(const struct ilo_image *img, unsigned level)
  257. {
  258.    unsigned h;
  259.  
  260.    switch (img->walk) {
  261.    case ILO_IMAGE_WALK_LAYER:
  262.       h = img->walk_layer_height;
  263.       break;
  264.    case ILO_IMAGE_WALK_LOD:
  265.       h = img->lods[level].slice_height;
  266.       break;
  267.    case ILO_IMAGE_WALK_3D:
  268.       if (level == 0) {
  269.          h = img->lods[0].slice_height;
  270.          break;
  271.       }
  272.       /* fall through */
  273.    default:
  274.       assert(!"no single stride to walk across slices");
  275.       h = 0;
  276.       break;
  277.    }
  278.  
  279.    assert(h % img->block_height == 0);
  280.  
  281.    return (h / img->block_height) * img->bo_stride;
  282. }
  283.  
  284. /**
  285.  * Return the physical size, in bytes, of a slice in a level.
  286.  */
  287. static inline unsigned
  288. ilo_image_get_slice_size(const struct ilo_image *img, unsigned level)
  289. {
  290.    const unsigned w = img->lods[level].slice_width;
  291.    const unsigned h = img->lods[level].slice_height;
  292.  
  293.    assert(w % img->block_width == 0);
  294.    assert(h % img->block_height == 0);
  295.  
  296.    return (w / img->block_width * img->block_size) *
  297.       (h / img->block_height);
  298. }
  299.  
  300. /**
  301.  * Return the pixel position of a slice.
  302.  */
  303. static inline void
  304. ilo_image_get_slice_pos(const struct ilo_image *img,
  305.                         unsigned level, unsigned slice,
  306.                         unsigned *x, unsigned *y)
  307. {
  308.    switch (img->walk) {
  309.    case ILO_IMAGE_WALK_LAYER:
  310.       *x = img->lods[level].x;
  311.       *y = img->lods[level].y + img->walk_layer_height * slice;
  312.       break;
  313.    case ILO_IMAGE_WALK_LOD:
  314.       *x = img->lods[level].x;
  315.       *y = img->lods[level].y + img->lods[level].slice_height * slice;
  316.       break;
  317.    case ILO_IMAGE_WALK_3D:
  318.       {
  319.          /* slices are packed horizontally with wrapping */
  320.          const unsigned sx = slice & ((1 << level) - 1);
  321.          const unsigned sy = slice >> level;
  322.  
  323.          assert(slice < u_minify(img->depth0, level));
  324.  
  325.          *x = img->lods[level].x + img->lods[level].slice_width * sx;
  326.          *y = img->lods[level].y + img->lods[level].slice_height * sy;
  327.       }
  328.       break;
  329.    default:
  330.       assert(!"unknown img walk type");
  331.       *x = 0;
  332.       *y = 0;
  333.       break;
  334.    }
  335.  
  336.    /* should not exceed the bo size */
  337.    assert(*y + img->lods[level].slice_height <=
  338.          img->bo_height * img->block_height);
  339. }
  340.  
  341. #endif /* ILO_IMAGE_H */
  342.