8307cb68f9c1e6a575a6551eea98c47e43f366a8
[mesa.git] / src / gallium / drivers / ilo / core / ilo_image.h
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 enum pipe_texture_target target;
92
93 /* size, format, etc for programming hardware states */
94 unsigned width0;
95 unsigned height0;
96 unsigned depth0;
97 unsigned array_size;
98 unsigned level_count;
99 unsigned sample_count;
100 enum pipe_format format;
101 bool separate_stencil;
102
103 /*
104 * width, height, and size of pixel blocks for conversion between pixel
105 * positions and memory offsets
106 */
107 unsigned block_width;
108 unsigned block_height;
109 unsigned block_size;
110
111 enum ilo_image_walk_type walk;
112 bool interleaved_samples;
113
114 enum gen_surface_tiling tiling;
115
116 /* physical LOD slice alignments */
117 unsigned align_i;
118 unsigned align_j;
119
120 struct ilo_image_lod lods[PIPE_MAX_TEXTURE_LEVELS];
121
122 /* physical layer height for ILO_IMAGE_WALK_LAYER */
123 unsigned walk_layer_height;
124
125 /* distance in bytes between two pixel block rows */
126 unsigned bo_stride;
127 /* number of pixel block rows */
128 unsigned bo_height;
129
130 bool scanout;
131
132 struct {
133 enum ilo_image_aux_type type;
134
135 /* bitmask of levels that can use aux */
136 unsigned enables;
137
138 /* LOD offsets for ILO_IMAGE_WALK_LOD */
139 unsigned walk_lod_offsets[PIPE_MAX_TEXTURE_LEVELS];
140
141 unsigned walk_layer_height;
142 unsigned bo_stride;
143 unsigned bo_height;
144
145 /* managed by users */
146 struct intel_bo *bo;
147 } aux;
148
149 /* managed by users */
150 struct intel_bo *bo;
151 };
152
153 struct pipe_resource;
154
155 void
156 ilo_image_init(struct ilo_image *img,
157 const struct ilo_dev *dev,
158 const struct pipe_resource *templ);
159
160 bool
161 ilo_image_init_for_imported(struct ilo_image *img,
162 const struct ilo_dev *dev,
163 const struct pipe_resource *templ,
164 enum gen_surface_tiling tiling,
165 unsigned bo_stride);
166
167 static inline bool
168 ilo_image_can_enable_aux(const struct ilo_image *img, unsigned level)
169 {
170 return (img->aux.bo && (img->aux.enables & (1 << level)));
171 }
172
173 /**
174 * Convert from pixel position to 2D memory offset.
175 */
176 static inline void
177 ilo_image_pos_to_mem(const struct ilo_image *img,
178 unsigned pos_x, unsigned pos_y,
179 unsigned *mem_x, unsigned *mem_y)
180 {
181 assert(pos_x % img->block_width == 0);
182 assert(pos_y % img->block_height == 0);
183
184 *mem_x = pos_x / img->block_width * img->block_size;
185 *mem_y = pos_y / img->block_height;
186 }
187
188 /**
189 * Convert from 2D memory offset to linear offset.
190 */
191 static inline unsigned
192 ilo_image_mem_to_linear(const struct ilo_image *img,
193 unsigned mem_x, unsigned mem_y)
194 {
195 return mem_y * img->bo_stride + mem_x;
196 }
197
198 /**
199 * Convert from 2D memory offset to raw offset.
200 */
201 static inline unsigned
202 ilo_image_mem_to_raw(const struct ilo_image *img,
203 unsigned mem_x, unsigned mem_y)
204 {
205 unsigned tile_w, tile_h;
206
207 switch (img->tiling) {
208 case GEN6_TILING_NONE:
209 tile_w = 1;
210 tile_h = 1;
211 break;
212 case GEN6_TILING_X:
213 tile_w = 512;
214 tile_h = 8;
215 break;
216 case GEN6_TILING_Y:
217 tile_w = 128;
218 tile_h = 32;
219 break;
220 case GEN8_TILING_W:
221 tile_w = 64;
222 tile_h = 64;
223 break;
224 default:
225 assert(!"unknown tiling");
226 tile_w = 1;
227 tile_h = 1;
228 break;
229 }
230
231 assert(mem_x % tile_w == 0);
232 assert(mem_y % tile_h == 0);
233
234 return mem_y * img->bo_stride + mem_x * tile_h;
235 }
236
237 /**
238 * Return the stride, in bytes, between slices within a level.
239 */
240 static inline unsigned
241 ilo_image_get_slice_stride(const struct ilo_image *img, unsigned level)
242 {
243 unsigned h;
244
245 switch (img->walk) {
246 case ILO_IMAGE_WALK_LAYER:
247 h = img->walk_layer_height;
248 break;
249 case ILO_IMAGE_WALK_LOD:
250 h = img->lods[level].slice_height;
251 break;
252 case ILO_IMAGE_WALK_3D:
253 if (level == 0) {
254 h = img->lods[0].slice_height;
255 break;
256 }
257 /* fall through */
258 default:
259 assert(!"no single stride to walk across slices");
260 h = 0;
261 break;
262 }
263
264 assert(h % img->block_height == 0);
265
266 return (h / img->block_height) * img->bo_stride;
267 }
268
269 /**
270 * Return the physical size, in bytes, of a slice in a level.
271 */
272 static inline unsigned
273 ilo_image_get_slice_size(const struct ilo_image *img, unsigned level)
274 {
275 const unsigned w = img->lods[level].slice_width;
276 const unsigned h = img->lods[level].slice_height;
277
278 assert(w % img->block_width == 0);
279 assert(h % img->block_height == 0);
280
281 return (w / img->block_width * img->block_size) *
282 (h / img->block_height);
283 }
284
285 /**
286 * Return the pixel position of a slice.
287 */
288 static inline void
289 ilo_image_get_slice_pos(const struct ilo_image *img,
290 unsigned level, unsigned slice,
291 unsigned *x, unsigned *y)
292 {
293 switch (img->walk) {
294 case ILO_IMAGE_WALK_LAYER:
295 *x = img->lods[level].x;
296 *y = img->lods[level].y + img->walk_layer_height * slice;
297 break;
298 case ILO_IMAGE_WALK_LOD:
299 *x = img->lods[level].x;
300 *y = img->lods[level].y + img->lods[level].slice_height * slice;
301 break;
302 case ILO_IMAGE_WALK_3D:
303 {
304 /* slices are packed horizontally with wrapping */
305 const unsigned sx = slice & ((1 << level) - 1);
306 const unsigned sy = slice >> level;
307
308 assert(slice < u_minify(img->depth0, level));
309
310 *x = img->lods[level].x + img->lods[level].slice_width * sx;
311 *y = img->lods[level].y + img->lods[level].slice_height * sy;
312 }
313 break;
314 default:
315 assert(!"unknown img walk type");
316 *x = 0;
317 *y = 0;
318 break;
319 }
320
321 /* should not exceed the bo size */
322 assert(*y + img->lods[level].slice_height <=
323 img->bo_height * img->block_height);
324 }
325
326 #endif /* ILO_IMAGE_H */