diff options
author | Chia-I Wu <[email protected]> | 2014-08-08 12:42:50 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2014-08-19 19:53:37 +0800 |
commit | 925359bc784399c1a65a46e2b136da3c4d30388d (patch) | |
tree | 801a4bf40798c1cf2b0379db17ab2d2e8873a0cd /src/gallium/drivers/ilo/ilo_layout.h | |
parent | 5ae9bdafd4bd50c0a72abb7cca5f8407efcb4cba (diff) |
ilo: add new resource layout code
Based on the old code, the new layout code describes the layout with the new,
well-documented, ilo_layout. It also gains new features such as MCS support
and extended ARYSPC_LOD0 that i965 comes up with (see
6345a94a9b134b1321b3b290bacde228b12af415).
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_layout.h')
-rw-r--r-- | src/gallium/drivers/ilo/ilo_layout.h | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/gallium/drivers/ilo/ilo_layout.h b/src/gallium/drivers/ilo/ilo_layout.h new file mode 100644 index 00000000000..1da9e2da799 --- /dev/null +++ b/src/gallium/drivers/ilo/ilo_layout.h @@ -0,0 +1,297 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2014 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <[email protected]> + */ + +#ifndef ILO_LAYOUT_H +#define ILO_LAYOUT_H + +#include "intel_winsys.h" + +#include "ilo_common.h" + +struct pipe_resource; + +enum ilo_layout_walk_type { + /* + * Array layers of an LOD are packed together vertically. This maps to + * ARYSPC_LOD0 for non-mipmapped 2D textures, and is extended to support + * mipmapped stencil textures and HiZ on GEN6. + */ + ILO_LAYOUT_WALK_LOD, + + /* + * LODs of an array layer are packed together. This maps to ARYSPC_FULL + * and is used for mipmapped 2D textures. + */ + ILO_LAYOUT_WALK_LAYER, + + /* + * 3D slices of an LOD are packed together, horizontally with wrapping. + * Used for 3D textures. + */ + ILO_LAYOUT_WALK_3D, +}; + +enum ilo_layout_aux_type { + ILO_LAYOUT_AUX_NONE, + ILO_LAYOUT_AUX_HIZ, + ILO_LAYOUT_AUX_MCS, +}; + +struct ilo_layout_lod { + /* physical position */ + unsigned x; + unsigned y; + + /* + * Physical size of an LOD slice. There may be multiple slices when the + * walk type is not ILO_LAYOUT_WALK_LAYER. + */ + unsigned slice_width; + unsigned slice_height; +}; + +/** + * Texture layout. + */ +struct ilo_layout { + enum ilo_layout_aux_type aux; + + /* physical width0, height0, and format */ + unsigned width0; + unsigned height0; + enum pipe_format format; + bool separate_stencil; + + /* + * width, height, and size of pixel blocks, for conversion between 2D + * coordinates and memory offsets + */ + unsigned block_width; + unsigned block_height; + unsigned block_size; + + enum ilo_layout_walk_type walk; + bool interleaved_samples; + + /* bitmask of valid tiling modes */ + unsigned valid_tilings; + enum intel_tiling_mode tiling; + + /* mipmap alignments */ + unsigned align_i; + unsigned align_j; + + struct ilo_layout_lod lods[PIPE_MAX_TEXTURE_LEVELS]; + + /* physical height of layers for ILO_LAYOUT_WALK_LAYER */ + unsigned layer_height; + + /* distance in bytes between two pixel block rows */ + unsigned bo_stride; + /* number of pixel block rows */ + unsigned bo_height; + + /* bitmask of levels that can use aux */ + unsigned aux_enables; + unsigned aux_offsets[PIPE_MAX_TEXTURE_LEVELS]; + unsigned aux_stride; + unsigned aux_height; +}; + +void ilo_layout_init(struct ilo_layout *layout, + const struct ilo_dev_info *dev, + const struct pipe_resource *templ); + +bool +ilo_layout_update_for_imported_bo(struct ilo_layout *layout, + enum intel_tiling_mode tiling, + unsigned bo_stride); + +/** + * Convert from pixel position to 2D memory offset. + */ +static inline void +ilo_layout_pos_to_mem(const struct ilo_layout *layout, + unsigned pos_x, unsigned pos_y, + unsigned *mem_x, unsigned *mem_y) +{ + assert(pos_x % layout->block_width == 0); + assert(pos_y % layout->block_height == 0); + + *mem_x = pos_x / layout->block_width * layout->block_size; + *mem_y = pos_y / layout->block_height; +} + +/** + * Convert from 2D memory offset to linear offset. + */ +static inline unsigned +ilo_layout_mem_to_linear(const struct ilo_layout *layout, + unsigned mem_x, unsigned mem_y) +{ + return mem_y * layout->bo_stride + mem_x; +} + +/** + * Convert from 2D memory offset to raw offset. + */ +static inline unsigned +ilo_layout_mem_to_raw(const struct ilo_layout *layout, + unsigned mem_x, unsigned mem_y) +{ + unsigned tile_w, tile_h; + + switch (layout->tiling) { + case INTEL_TILING_NONE: + if (layout->format == PIPE_FORMAT_S8_UINT) { + /* W-tile */ + tile_w = 64; + tile_h = 64; + } else { + tile_w = 1; + tile_h = 1; + } + break; + case INTEL_TILING_X: + tile_w = 512; + tile_h = 8; + break; + case INTEL_TILING_Y: + tile_w = 128; + tile_h = 32; + break; + default: + assert(!"unknown tiling"); + tile_w = 1; + tile_h = 1; + break; + } + + assert(mem_x % tile_w == 0); + assert(mem_y % tile_h == 0); + + return mem_y * layout->bo_stride + mem_x * tile_h; +} + +/** + * Return the stride, in bytes, between slices within a level. + */ +static inline unsigned +ilo_layout_get_slice_stride(const struct ilo_layout *layout, unsigned level) +{ + unsigned h; + + switch (layout->walk) { + case ILO_LAYOUT_WALK_LOD: + h = layout->lods[level].slice_height; + break; + case ILO_LAYOUT_WALK_LAYER: + h = layout->layer_height; + break; + case ILO_LAYOUT_WALK_3D: + if (level == 0) { + h = layout->lods[0].slice_height; + break; + } + /* fall through */ + default: + assert(!"no single stride to walk across slices"); + h = 0; + break; + } + + assert(h % layout->block_height == 0); + + return (h / layout->block_height) * layout->bo_stride; +} + +/** + * Return the physical size, in bytes, of a slice in a level. + */ +static inline unsigned +ilo_layout_get_slice_size(const struct ilo_layout *layout, unsigned level) +{ + const unsigned w = layout->lods[level].slice_width; + const unsigned h = layout->lods[level].slice_height; + + assert(w % layout->block_width == 0); + assert(h % layout->block_height == 0); + + return (w / layout->block_width * layout->block_size) * + (h / layout->block_height); +} + +/** + * Return the pixel position of a slice. + */ +static inline void +ilo_layout_get_slice_pos(const struct ilo_layout *layout, + unsigned level, unsigned slice, + unsigned *x, unsigned *y) +{ + switch (layout->walk) { + case ILO_LAYOUT_WALK_LOD: + *x = layout->lods[level].x; + *y = layout->lods[level].y + layout->lods[level].slice_height * slice; + break; + case ILO_LAYOUT_WALK_LAYER: + *x = layout->lods[level].x; + *y = layout->lods[level].y + layout->layer_height * slice; + break; + case ILO_LAYOUT_WALK_3D: + { + /* slices are packed horizontally with wrapping */ + const unsigned sx = slice & ((1 << level) - 1); + const unsigned sy = slice >> level; + + *x = layout->lods[level].x + layout->lods[level].slice_width * sx; + *y = layout->lods[level].y + layout->lods[level].slice_height * sy; + + /* should not overlap with the next level */ + if (level + 1 < Elements(layout->lods) && + layout->lods[level + 1].y) { + assert(*y + layout->lods[level].slice_height <= + layout->lods[level + 1].y); + } + break; + } + default: + assert(!"unknown layout walk type"); + break; + } + + /* should not exceed the bo size */ + assert(*y + layout->lods[level].slice_height <= + layout->bo_height * layout->block_height); +} + +unsigned +ilo_layout_get_slice_tile_offset(const struct ilo_layout *layout, + unsigned level, unsigned slice, + unsigned *x_offset, unsigned *y_offset); + +#endif /* ILO_LAYOUT_H */ |