blob: 7d7e350ad7c413c31feab23cb38061ea10462145 [file] [log] [blame]
Chia-I Wu4bc47012014-08-14 13:03:25 +08001/*
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_LAYOUT_H
29#define ILO_LAYOUT_H
30
31#include "intel_winsys.h"
32
33#include "ilo_common.h"
34
35struct pipe_resource;
36
37enum ilo_layout_aux_type {
38 ILO_LAYOUT_AUX_NONE,
39 ILO_LAYOUT_AUX_HIZ,
40 ILO_LAYOUT_AUX_MCS,
41};
42
43/**
44 * Texture layout.
45 */
46struct ilo_layout {
47 enum ilo_layout_aux_type aux_type;
48 enum pipe_format format;
49 bool separate_stencil;
50
51 /*
52 * width, height, and size of pixel blocks, for conversion between 2D
53 * coordinates and memory offsets
54 */
55 unsigned block_width;
56 unsigned block_height;
57 unsigned block_size;
58
59 /* arrangements of samples and array layers */
60 bool interleaved_samples;
61 bool full_layers;
62 bool is_2d;
63
64 /* bitmask of valid tiling modes */
65 unsigned valid_tilings;
66 enum intel_tiling_mode tiling;
67
68 /* mipmap alignments */
69 unsigned align_i;
70 unsigned align_j;
71
72 struct {
73 /* physical position of a mipmap */
74 unsigned x;
75 unsigned y;
76
77 /*
78 * Physical size of a mipmap slice. For 3D textures, there may be
79 * multiple slices.
80 */
81 unsigned slice_width;
82 unsigned slice_height;
83 } levels[PIPE_MAX_TEXTURE_LEVELS];
84
85 /* physical height of array layers, cube faces, or sample layers */
86 unsigned layer_height;
87
88 /* distance in bytes between two pixel block rows */
89 unsigned bo_stride;
90 /* number of pixel block rows */
91 unsigned bo_height;
92
93 unsigned aux_stride;
94 unsigned aux_height;
95};
96
97void ilo_layout_init(struct ilo_layout *layout,
98 const struct ilo_dev_info *dev,
99 const struct pipe_resource *templ);
100
101bool
102ilo_layout_update_for_imported_bo(struct ilo_layout *layout,
103 enum intel_tiling_mode tiling,
104 unsigned bo_stride);
105
106/**
107 * Convert from pixel position to memory position.
108 */
109static inline void
110ilo_layout_pos_to_mem(const struct ilo_layout *layout,
111 unsigned x, unsigned y,
112 unsigned *mem_x, unsigned *mem_y)
113{
114 assert(x % layout->block_width == 0);
115 assert(y % layout->block_height == 0);
116
117 *mem_x = x / layout->block_width * layout->block_size;
118 *mem_y = y / layout->block_height;
119}
120
121/**
122 * Convert from memory position to memory offset.
123 */
124static inline unsigned
125ilo_layout_mem_to_off(const struct ilo_layout *layout,
126 unsigned mem_x, unsigned mem_y)
127{
128 return mem_y * layout->bo_stride + mem_x;
129}
130
131/**
132 * Return the stride, in bytes, between slices within a level.
133 */
134static inline unsigned
135ilo_layout_get_slice_stride(const struct ilo_layout *layout, unsigned level)
136{
137 unsigned y;
138
139 if (layout->is_2d) {
140 y = layout->layer_height;
141 } else if (level == 0) {
142 y = layout->levels[0].slice_height;
143 } else {
144 assert(!"no single slice stride for 3D texture with level > 0");
145 y = 0;
146 }
147
148 assert(y % layout->block_height == 0);
149
150 return (y / layout->block_height) * layout->bo_stride;
151}
152
153/**
154 * Return the physical size, in bytes, of a slice in a level.
155 */
156static inline unsigned
157ilo_layout_get_slice_size(const struct ilo_layout *layout, unsigned level)
158{
159 const unsigned w = layout->levels[level].slice_width;
160 const unsigned h = layout->levels[level].slice_height;
161
162 assert(w % layout->block_width == 0);
163 assert(h % layout->block_height == 0);
164
165 return (w / layout->block_width * layout->block_size) *
166 (h / layout->block_height);
167}
168
169/**
170 * Return the pixel position of a slice.
171 */
172static inline void
173ilo_layout_get_slice_pos(const struct ilo_layout *layout,
174 unsigned level, unsigned slice,
175 unsigned *x, unsigned *y)
176{
177 if (layout->is_2d) {
178 *x = layout->levels[level].x;
179 *y = layout->levels[level].y + layout->layer_height * slice;
180 } else {
181 const unsigned sx = slice & ((1 << level) - 1);
182 const unsigned sy = slice >> level;
183
184 *x = layout->levels[level].x + layout->levels[level].slice_width * sx;
185 *y = layout->levels[level].y + layout->levels[level].slice_height * sy;
186
187 /* should not overlap with the next level */
188 if (level + 1 < Elements(layout->levels) && layout->levels[level + 1].y) {
189 assert(*y + layout->levels[level].slice_height <=
190 layout->levels[level + 1].y);
191 }
192 }
193
194 /* should not exceed the bo size */
195 assert(*y + layout->levels[level].slice_height <=
196 layout->bo_height * layout->block_height);
197}
198
199unsigned
200ilo_layout_get_slice_tile_offset(const struct ilo_layout *layout,
201 unsigned level, unsigned slice,
202 unsigned *x_offset, unsigned *y_offset);
203
204#endif /* ILO_LAYOUT_H */