i965/miptree: Tell when brw_miptree_layout() fails
[mesa.git] / src / mesa / drivers / dri / i965 / brw_tex_layout.c
1 /*
2 * Copyright 2006 VMware, Inc.
3 * Copyright © 2006 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file brw_tex_layout.cpp
28 *
29 * Code to lay out images in a mipmap tree.
30 *
31 * \author Keith Whitwell <keithw@vmware.com>
32 * \author Michel Dänzer <daenzer@vmware.com>
33 */
34
35 #include "intel_mipmap_tree.h"
36 #include "brw_context.h"
37 #include "main/macros.h"
38 #include "main/glformats.h"
39
40 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
41
42 static unsigned int
43 tr_mode_horizontal_texture_alignment(const struct intel_mipmap_tree *mt)
44 {
45 unsigned ret_align, divisor, multiplier_ys;
46
47 /* Values in below tables specifiy the horizontal alignment requirement
48 * in elements for TRMODE_YF surface. An element is defined as a pixel in
49 * uncompressed surface formats, and as a compression block in compressed
50 * surface formats. For MSFMT_DEPTH_STENCIL type multisampled surfaces, an
51 * element is a sample.
52 */
53 const unsigned align_1d_yf[] = {4096, 2048, 1024, 512, 256};
54 const unsigned align_2d_yf[] = {64, 64, 32, 32, 16};
55 const unsigned align_3d_yf[] = {16, 8, 8, 8, 4};
56
57 assert(mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE);
58
59 /* Alignment computations below assume a power of 2 cpp. */
60 assert (mt->cpp >= 1 && mt->cpp <= 16 && _mesa_is_pow_two(mt->cpp));
61 /* Compute array index. */
62 const int i = ffs(mt->cpp) - 1;
63
64 switch(mt->target) {
65 case GL_TEXTURE_1D:
66 case GL_TEXTURE_1D_ARRAY:
67 ret_align = align_1d_yf[i];
68 multiplier_ys = 16;
69 break;
70 case GL_TEXTURE_2D:
71 case GL_TEXTURE_RECTANGLE:
72 case GL_TEXTURE_2D_ARRAY:
73 case GL_TEXTURE_CUBE_MAP:
74 case GL_TEXTURE_CUBE_MAP_ARRAY:
75 case GL_TEXTURE_2D_MULTISAMPLE:
76 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
77 ret_align = align_2d_yf[i];
78 multiplier_ys = 4;
79 break;
80 case GL_TEXTURE_3D:
81 ret_align = align_3d_yf[i];
82 multiplier_ys = 4;
83 break;
84 default:
85 unreachable("not reached");
86 }
87
88 if (mt->tr_mode == INTEL_MIPTREE_TRMODE_YS)
89 ret_align *= multiplier_ys;
90
91 assert(_mesa_is_pow_two(mt->num_samples));
92
93 switch (mt->num_samples) {
94 case 2:
95 case 4:
96 divisor = 2;
97 break;
98 case 8:
99 case 16:
100 divisor = 4;
101 break;
102 default:
103 divisor = 1;
104 break;
105 }
106 return ret_align / divisor;
107 }
108
109
110 static unsigned int
111 intel_horizontal_texture_alignment_unit(struct brw_context *brw,
112 struct intel_mipmap_tree *mt,
113 uint32_t layout_flags)
114 {
115 if (layout_flags & MIPTREE_LAYOUT_FORCE_HALIGN16)
116 return 16;
117
118 /**
119 * +----------------------------------------------------------------------+
120 * | | alignment unit width ("i") |
121 * | Surface Property |-----------------------------|
122 * | | 915 | 965 | ILK | SNB | IVB |
123 * +----------------------------------------------------------------------+
124 * | YUV 4:2:2 format | 8 | 4 | 4 | 4 | 4 |
125 * | BC1-5 compressed format (DXTn/S3TC) | 4 | 4 | 4 | 4 | 4 |
126 * | FXT1 compressed format | 8 | 8 | 8 | 8 | 8 |
127 * | Depth Buffer (16-bit) | 4 | 4 | 4 | 4 | 8 |
128 * | Depth Buffer (other) | 4 | 4 | 4 | 4 | 4 |
129 * | Separate Stencil Buffer | N/A | N/A | 8 | 8 | 8 |
130 * | All Others | 4 | 4 | 4 | 4 | 4 |
131 * +----------------------------------------------------------------------+
132 *
133 * On IVB+, non-special cases can be overridden by setting the SURFACE_STATE
134 * "Surface Horizontal Alignment" field to HALIGN_4 or HALIGN_8.
135 */
136
137 if (brw->gen >= 7 && mt->format == MESA_FORMAT_Z_UNORM16)
138 return 8;
139
140 return 4;
141 }
142
143 static unsigned int
144 tr_mode_vertical_texture_alignment(const struct intel_mipmap_tree *mt)
145 {
146 unsigned ret_align, divisor, multiplier_ys;
147
148 /* Vertical alignment tables for TRMODE_YF */
149 const unsigned align_2d_yf[] = {64, 32, 32, 16, 16};
150 const unsigned align_3d_yf[] = {16, 16, 16, 8, 8};
151
152 assert(mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE);
153
154 /* Alignment computations below assume a power of 2 cpp. */
155 assert (mt->cpp >= 1 && mt->cpp <= 16 && _mesa_is_pow_two(mt->cpp)) ;
156 /* Compute array index. */
157 const int i = ffs(mt->cpp) - 1;
158
159 switch(mt->target) {
160 case GL_TEXTURE_2D:
161 case GL_TEXTURE_RECTANGLE:
162 case GL_TEXTURE_2D_ARRAY:
163 case GL_TEXTURE_CUBE_MAP:
164 case GL_TEXTURE_CUBE_MAP_ARRAY:
165 case GL_TEXTURE_2D_MULTISAMPLE:
166 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
167 ret_align = align_2d_yf[i];
168 multiplier_ys = 4;
169 break;
170 case GL_TEXTURE_3D:
171 ret_align = align_3d_yf[i];
172 multiplier_ys = 2;
173 break;
174 case GL_TEXTURE_1D:
175 case GL_TEXTURE_1D_ARRAY:
176 default:
177 unreachable("Unexpected miptree target");
178 }
179
180 if (mt->tr_mode == INTEL_MIPTREE_TRMODE_YS)
181 ret_align *= multiplier_ys;
182
183 assert(_mesa_is_pow_two(mt->num_samples));
184
185 switch (mt->num_samples) {
186 case 4:
187 case 8:
188 divisor = 2;
189 break;
190 case 16:
191 divisor = 4;
192 break;
193 default:
194 divisor = 1;
195 break;
196 }
197 return ret_align / divisor;
198 }
199
200 static unsigned int
201 intel_vertical_texture_alignment_unit(struct brw_context *brw,
202 const struct intel_mipmap_tree *mt)
203 {
204 /**
205 * +----------------------------------------------------------------------+
206 * | | alignment unit height ("j") |
207 * | Surface Property |-----------------------------|
208 * | | 915 | 965 | ILK | SNB | IVB |
209 * +----------------------------------------------------------------------+
210 * | BC1-5 compressed format (DXTn/S3TC) | 4 | 4 | 4 | 4 | 4 |
211 * | FXT1 compressed format | 4 | 4 | 4 | 4 | 4 |
212 * | Depth Buffer | 2 | 2 | 2 | 4 | 4 |
213 * | Separate Stencil Buffer | N/A | N/A | N/A | 4 | 8 |
214 * | Multisampled (4x or 8x) render target | N/A | N/A | N/A | 4 | 4 |
215 * | All Others | 2 | 2 | 2 | * | * |
216 * +----------------------------------------------------------------------+
217 *
218 * Where "*" means either VALIGN_2 or VALIGN_4 depending on the setting of
219 * the SURFACE_STATE "Surface Vertical Alignment" field.
220 */
221
222 /* Broadwell only supports VALIGN of 4, 8, and 16. The BSpec says 4
223 * should always be used, except for stencil buffers, which should be 8.
224 */
225 if (brw->gen >= 8)
226 return 4;
227
228 if (mt->num_samples > 1)
229 return 4;
230
231 GLenum base_format = _mesa_get_format_base_format(mt->format);
232
233 if (brw->gen >= 6 &&
234 (base_format == GL_DEPTH_COMPONENT ||
235 base_format == GL_DEPTH_STENCIL)) {
236 return 4;
237 }
238
239 if (brw->gen == 7) {
240 /* On Gen7, we prefer a vertical alignment of 4 when possible, because
241 * that allows Y tiled render targets.
242 *
243 * From the Ivy Bridge PRM, Vol4 Part1 2.12.2.1 (SURFACE_STATE for most
244 * messages), on p64, under the heading "Surface Vertical Alignment":
245 *
246 * Value of 1 [VALIGN_4] is not supported for format YCRCB_NORMAL
247 * (0x182), YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY
248 * (0x190)
249 *
250 * VALIGN_4 is not supported for surface format R32G32B32_FLOAT.
251 */
252 if (base_format == GL_YCBCR_MESA || mt->format == MESA_FORMAT_RGB_FLOAT32)
253 return 2;
254
255 return 4;
256 }
257
258 return 2;
259 }
260
261 static void
262 gen9_miptree_layout_1d(struct intel_mipmap_tree *mt)
263 {
264 unsigned x = 0;
265 unsigned width = mt->physical_width0;
266 unsigned depth = mt->physical_depth0; /* number of array layers. */
267
268 /* When this layout is used the horizontal alignment is fixed at 64 and the
269 * hardware ignores the value given in the surface state
270 */
271 const unsigned int halign = 64;
272
273 mt->total_height = mt->physical_height0;
274 mt->total_width = 0;
275
276 for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
277 unsigned img_width;
278
279 intel_miptree_set_level_info(mt, level, x, 0, depth);
280
281 img_width = ALIGN(width, halign);
282
283 mt->total_width = MAX2(mt->total_width, x + img_width);
284
285 x += img_width;
286
287 width = minify(width, 1);
288 }
289 }
290
291 static void
292 brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
293 {
294 unsigned x = 0;
295 unsigned y = 0;
296 unsigned width = mt->physical_width0;
297 unsigned height = mt->physical_height0;
298 /* Number of layers of array texture or slices of 3d texture (gen9+). */
299 unsigned depth = mt->physical_depth0;
300 unsigned int bw, bh;
301
302 _mesa_get_format_block_size(mt->format, &bw, &bh);
303
304 mt->total_width = mt->physical_width0;
305 mt->total_width = ALIGN_NPOT(mt->total_width, bw);
306
307 /* May need to adjust width to accommodate the placement of
308 * the 2nd mipmap. This occurs when the alignment
309 * constraints of mipmap placement push the right edge of the
310 * 2nd mipmap out past the width of its parent.
311 */
312 if (mt->first_level != mt->last_level) {
313 unsigned mip1_width;
314
315 mip1_width = ALIGN_NPOT(minify(mt->physical_width0, 1), mt->halign) +
316 ALIGN_NPOT(minify(mt->physical_width0, 2), bw);
317
318 if (mip1_width > mt->total_width)
319 mt->total_width = mip1_width;
320 }
321
322 mt->total_width /= bw;
323 mt->total_height = 0;
324
325 for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
326 unsigned img_height;
327
328 intel_miptree_set_level_info(mt, level, x, y, depth);
329
330 img_height = ALIGN_NPOT(height, mt->valign);
331 img_height /= bh;
332
333 if (mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
334 /* Compact arrays with separated miplevels */
335 img_height *= depth;
336 }
337
338 /* Because the images are packed better, the final offset
339 * might not be the maximal one:
340 */
341 mt->total_height = MAX2(mt->total_height, y + img_height);
342
343 /* Layout_below: step right after second mipmap.
344 */
345 if (level == mt->first_level + 1) {
346 x += ALIGN_NPOT(width, mt->halign) / bw;
347 } else {
348 y += img_height;
349 }
350
351 width = minify(width, 1);
352 height = minify(height, 1);
353
354 if (mt->target == GL_TEXTURE_3D)
355 depth = minify(depth, 1);
356 }
357 }
358
359 unsigned
360 brw_miptree_get_horizontal_slice_pitch(const struct brw_context *brw,
361 const struct intel_mipmap_tree *mt,
362 unsigned level)
363 {
364 if ((brw->gen < 9 && mt->target == GL_TEXTURE_3D) ||
365 (brw->gen == 4 && mt->target == GL_TEXTURE_CUBE_MAP)) {
366 return ALIGN_NPOT(minify(mt->physical_width0, level), mt->halign);
367 } else {
368 return 0;
369 }
370 }
371
372 unsigned
373 brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw,
374 const struct intel_mipmap_tree *mt,
375 unsigned level)
376 {
377 if (brw->gen >= 9) {
378 /* ALL_SLICES_AT_EACH_LOD isn't supported on Gen8+ but this code will
379 * effectively end up with a packed qpitch anyway whenever
380 * mt->first_level == mt->last_level.
381 */
382 assert(mt->array_layout != ALL_SLICES_AT_EACH_LOD);
383
384 /* On Gen9 we can pick whatever qpitch we like as long as it's aligned
385 * to the vertical alignment so we don't need to add any extra rows.
386 */
387 unsigned qpitch = mt->total_height;
388
389 /* If the surface might be used as a stencil buffer or HiZ buffer then
390 * it needs to be a multiple of 8.
391 */
392 const GLenum base_format = _mesa_get_format_base_format(mt->format);
393 if (_mesa_is_depth_or_stencil_format(base_format))
394 qpitch = ALIGN(qpitch, 8);
395
396 /* 3D textures need to be aligned to the tile height. At this point we
397 * don't know which tiling will be used so let's just align it to 32
398 */
399 if (mt->target == GL_TEXTURE_3D)
400 qpitch = ALIGN(qpitch, 32);
401
402 return qpitch;
403
404 } else if (mt->target == GL_TEXTURE_3D ||
405 (brw->gen == 4 && mt->target == GL_TEXTURE_CUBE_MAP) ||
406 mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
407 return ALIGN_NPOT(minify(mt->physical_height0, level), mt->valign);
408
409 } else {
410 const unsigned h0 = ALIGN_NPOT(mt->physical_height0, mt->valign);
411 const unsigned h1 = ALIGN_NPOT(minify(mt->physical_height0, 1), mt->valign);
412
413 return h0 + h1 + (brw->gen >= 7 ? 12 : 11) * mt->valign;
414 }
415 }
416
417 static void
418 align_cube(struct intel_mipmap_tree *mt)
419 {
420 /* The 965's sampler lays cachelines out according to how accesses
421 * in the texture surfaces run, so they may be "vertical" through
422 * memory. As a result, the docs say in Surface Padding Requirements:
423 * Sampling Engine Surfaces that two extra rows of padding are required.
424 */
425 if (mt->target == GL_TEXTURE_CUBE_MAP)
426 mt->total_height += 2;
427 }
428
429 bool
430 gen9_use_linear_1d_layout(const struct brw_context *brw,
431 const struct intel_mipmap_tree *mt)
432 {
433 /* On Gen9+ the mipmap levels of a 1D surface are all laid out in a
434 * horizontal line. This isn't done for depth/stencil buffers however
435 * because those will be using a tiled layout
436 */
437 if (brw->gen >= 9 &&
438 (mt->target == GL_TEXTURE_1D ||
439 mt->target == GL_TEXTURE_1D_ARRAY)) {
440 GLenum base_format = _mesa_get_format_base_format(mt->format);
441
442 if (base_format != GL_DEPTH_COMPONENT &&
443 base_format != GL_DEPTH_STENCIL &&
444 base_format != GL_STENCIL_INDEX)
445 return true;
446 }
447
448 return false;
449 }
450
451 static void
452 brw_miptree_layout_texture_array(struct brw_context *brw,
453 struct intel_mipmap_tree *mt)
454 {
455 unsigned height = mt->physical_height0;
456 bool layout_1d = gen9_use_linear_1d_layout(brw, mt);
457 int physical_qpitch;
458
459 if (layout_1d)
460 gen9_miptree_layout_1d(mt);
461 else
462 brw_miptree_layout_2d(mt);
463
464 if (layout_1d) {
465 physical_qpitch = 1;
466 /* When using the horizontal layout the qpitch specifies the distance in
467 * pixels between array slices. The total_width is forced to be a
468 * multiple of the horizontal alignment in brw_miptree_layout_1d (in
469 * this case it's always 64). The vertical alignment is ignored.
470 */
471 mt->qpitch = mt->total_width;
472 } else {
473 mt->qpitch = brw_miptree_get_vertical_slice_pitch(brw, mt, 0);
474 /* Unlike previous generations the qpitch is a multiple of the
475 * compressed block size on Gen9 so physical_qpitch matches mt->qpitch.
476 */
477 physical_qpitch = (mt->compressed && brw->gen < 9 ? mt->qpitch / 4 :
478 mt->qpitch);
479 }
480
481 for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
482 unsigned img_height;
483 img_height = ALIGN_NPOT(height, mt->valign);
484 if (mt->compressed)
485 img_height /= mt->valign;
486
487 for (unsigned q = 0; q < mt->level[level].depth; q++) {
488 if (mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
489 intel_miptree_set_image_offset(mt, level, q, 0, q * img_height);
490 } else {
491 intel_miptree_set_image_offset(mt, level, q, 0, q * physical_qpitch);
492 }
493 }
494 height = minify(height, 1);
495 }
496 if (mt->array_layout == ALL_LOD_IN_EACH_SLICE)
497 mt->total_height = physical_qpitch * mt->physical_depth0;
498
499 align_cube(mt);
500 }
501
502 static void
503 brw_miptree_layout_texture_3d(struct brw_context *brw,
504 struct intel_mipmap_tree *mt)
505 {
506 mt->total_width = 0;
507 mt->total_height = 0;
508
509 unsigned ysum = 0;
510 unsigned bh, bw;
511
512 _mesa_get_format_block_size(mt->format, &bw, &bh);
513
514 for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
515 unsigned WL = MAX2(mt->physical_width0 >> level, 1);
516 unsigned HL = MAX2(mt->physical_height0 >> level, 1);
517 unsigned DL = MAX2(mt->physical_depth0 >> level, 1);
518 unsigned wL = ALIGN_NPOT(WL, mt->halign);
519 unsigned hL = ALIGN_NPOT(HL, mt->valign);
520
521 if (mt->target == GL_TEXTURE_CUBE_MAP)
522 DL = 6;
523
524 intel_miptree_set_level_info(mt, level, 0, 0, DL);
525
526 for (unsigned q = 0; q < DL; q++) {
527 unsigned x = (q % (1 << level)) * wL;
528 unsigned y = ysum + (q >> level) * hL;
529
530 intel_miptree_set_image_offset(mt, level, q, x / bw, y / bh);
531 mt->total_width = MAX2(mt->total_width, (x + wL) / bw);
532 mt->total_height = MAX2(mt->total_height, (y + hL) / bh);
533 }
534
535 ysum += ALIGN(DL, 1 << level) / (1 << level) * hL;
536 }
537
538 align_cube(mt);
539 }
540
541 /**
542 * \brief Helper function for intel_miptree_create().
543 */
544 static uint32_t
545 brw_miptree_choose_tiling(struct brw_context *brw,
546 const struct intel_mipmap_tree *mt,
547 uint32_t layout_flags)
548 {
549 if (mt->format == MESA_FORMAT_S_UINT8) {
550 /* The stencil buffer is W tiled. However, we request from the kernel a
551 * non-tiled buffer because the GTT is incapable of W fencing.
552 */
553 return I915_TILING_NONE;
554 }
555
556 /* Do not support changing the tiling for miptrees with pre-allocated BOs. */
557 assert((layout_flags & MIPTREE_LAYOUT_FOR_BO) == 0);
558
559 /* Some usages may want only one type of tiling, like depth miptrees (Y
560 * tiled), or temporary BOs for uploading data once (linear).
561 */
562 switch (layout_flags & MIPTREE_LAYOUT_TILING_ANY) {
563 case MIPTREE_LAYOUT_TILING_ANY:
564 break;
565 case MIPTREE_LAYOUT_TILING_Y:
566 return I915_TILING_Y;
567 case MIPTREE_LAYOUT_TILING_NONE:
568 return I915_TILING_NONE;
569 }
570
571 if (mt->num_samples > 1) {
572 /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
573 * Surface"):
574 *
575 * [DevSNB+]: For multi-sample render targets, this field must be
576 * 1. MSRTs can only be tiled.
577 *
578 * Our usual reason for preferring X tiling (fast blits using the
579 * blitting engine) doesn't apply to MSAA, since we'll generally be
580 * downsampling or upsampling when blitting between the MSAA buffer
581 * and another buffer, and the blitting engine doesn't support that.
582 * So use Y tiling, since it makes better use of the cache.
583 */
584 return I915_TILING_Y;
585 }
586
587 GLenum base_format = _mesa_get_format_base_format(mt->format);
588 if (base_format == GL_DEPTH_COMPONENT ||
589 base_format == GL_DEPTH_STENCIL_EXT)
590 return I915_TILING_Y;
591
592 /* 1D textures (and 1D array textures) don't get any benefit from tiling,
593 * in fact it leads to a less efficient use of memory space and bandwidth
594 * due to tile alignment.
595 */
596 if (mt->logical_height0 == 1)
597 return I915_TILING_NONE;
598
599 int minimum_pitch = mt->total_width * mt->cpp;
600
601 /* If the width is much smaller than a tile, don't bother tiling. */
602 if (minimum_pitch < 64)
603 return I915_TILING_NONE;
604
605 if (ALIGN(minimum_pitch, 512) >= 32768) {
606 perf_debug("%dx%d miptree too large to blit, falling back to untiled",
607 mt->total_width, mt->total_height);
608 return I915_TILING_NONE;
609 }
610
611 /* Pre-gen6 doesn't have BLORP to handle Y-tiling, so use X-tiling. */
612 if (brw->gen < 6)
613 return I915_TILING_X;
614
615 /* From the Sandybridge PRM, Volume 1, Part 2, page 32:
616 * "NOTE: 128BPE Format Color Buffer ( render target ) MUST be either TileX
617 * or Linear."
618 * 128 bits per pixel translates to 16 bytes per pixel. This is necessary
619 * all the way back to 965, but is permitted on Gen7+.
620 */
621 if (brw->gen < 7 && mt->cpp >= 16)
622 return I915_TILING_X;
623
624 /* From the Ivy Bridge PRM, Vol4 Part1 2.12.2.1 (SURFACE_STATE for most
625 * messages), on p64, under the heading "Surface Vertical Alignment":
626 *
627 * This field must be set to VALIGN_4 for all tiled Y Render Target
628 * surfaces.
629 *
630 * So if the surface is renderable and uses a vertical alignment of 2,
631 * force it to be X tiled. This is somewhat conservative (it's possible
632 * that the client won't ever render to this surface), but it's difficult
633 * to know that ahead of time. And besides, since we use a vertical
634 * alignment of 4 as often as we can, this shouldn't happen very often.
635 */
636 if (brw->gen == 7 && mt->valign == 2 &&
637 brw->format_supported_as_render_target[mt->format]) {
638 return I915_TILING_X;
639 }
640
641 return I915_TILING_Y | I915_TILING_X;
642 }
643
644 static void
645 intel_miptree_set_total_width_height(struct brw_context *brw,
646 struct intel_mipmap_tree *mt)
647 {
648 switch (mt->target) {
649 case GL_TEXTURE_CUBE_MAP:
650 if (brw->gen == 4) {
651 /* Gen4 stores cube maps as 3D textures. */
652 assert(mt->physical_depth0 == 6);
653 brw_miptree_layout_texture_3d(brw, mt);
654 } else {
655 /* All other hardware stores cube maps as 2D arrays. */
656 brw_miptree_layout_texture_array(brw, mt);
657 }
658 break;
659
660 case GL_TEXTURE_3D:
661 if (brw->gen >= 9)
662 brw_miptree_layout_texture_array(brw, mt);
663 else
664 brw_miptree_layout_texture_3d(brw, mt);
665 break;
666
667 case GL_TEXTURE_1D_ARRAY:
668 case GL_TEXTURE_2D_ARRAY:
669 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
670 case GL_TEXTURE_CUBE_MAP_ARRAY:
671 brw_miptree_layout_texture_array(brw, mt);
672 break;
673
674 default:
675 switch (mt->msaa_layout) {
676 case INTEL_MSAA_LAYOUT_UMS:
677 case INTEL_MSAA_LAYOUT_CMS:
678 brw_miptree_layout_texture_array(brw, mt);
679 break;
680 case INTEL_MSAA_LAYOUT_NONE:
681 case INTEL_MSAA_LAYOUT_IMS:
682 if (gen9_use_linear_1d_layout(brw, mt))
683 gen9_miptree_layout_1d(mt);
684 else
685 brw_miptree_layout_2d(mt);
686 break;
687 }
688 break;
689 }
690
691 DBG("%s: %dx%dx%d\n", __func__,
692 mt->total_width, mt->total_height, mt->cpp);
693 }
694
695 static void
696 intel_miptree_set_alignment(struct brw_context *brw,
697 struct intel_mipmap_tree *mt,
698 uint32_t layout_flags)
699 {
700 /**
701 * From the "Alignment Unit Size" section of various specs, namely:
702 * - Gen3 Spec: "Memory Data Formats" Volume, Section 1.20.1.4
703 * - i965 and G45 PRMs: Volume 1, Section 6.17.3.4.
704 * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
705 * - BSpec (for Ivybridge and slight variations in separate stencil)
706 */
707 bool gen6_hiz_or_stencil = false;
708
709 if (brw->gen == 6 && mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
710 const GLenum base_format = _mesa_get_format_base_format(mt->format);
711 gen6_hiz_or_stencil = _mesa_is_depth_or_stencil_format(base_format);
712 }
713
714 if (gen6_hiz_or_stencil) {
715 /* On gen6, we use ALL_SLICES_AT_EACH_LOD for stencil/hiz because the
716 * hardware doesn't support multiple mip levels on stencil/hiz.
717 *
718 * PRM Vol 2, Part 1, 7.5.3 Hierarchical Depth Buffer:
719 * "The hierarchical depth buffer does not support the LOD field"
720 *
721 * PRM Vol 2, Part 1, 7.5.4.1 Separate Stencil Buffer:
722 * "The stencil depth buffer does not support the LOD field"
723 */
724 if (mt->format == MESA_FORMAT_S_UINT8) {
725 /* Stencil uses W tiling, so we force W tiling alignment for the
726 * ALL_SLICES_AT_EACH_LOD miptree layout.
727 */
728 mt->halign = 64;
729 mt->valign = 64;
730 assert((layout_flags & MIPTREE_LAYOUT_FORCE_HALIGN16) == 0);
731 } else {
732 /* Depth uses Y tiling, so we force need Y tiling alignment for the
733 * ALL_SLICES_AT_EACH_LOD miptree layout.
734 */
735 mt->halign = 128 / mt->cpp;
736 mt->valign = 32;
737 }
738 } else if (mt->compressed) {
739 /* The hardware alignment requirements for compressed textures
740 * happen to match the block boundaries.
741 */
742 _mesa_get_format_block_size(mt->format, &mt->halign, &mt->valign);
743
744 /* On Gen9+ we can pick our own alignment for compressed textures but it
745 * has to be a multiple of the block size. The minimum alignment we can
746 * pick is 4 so we effectively have to align to 4 times the block
747 * size
748 */
749 if (brw->gen >= 9) {
750 mt->halign *= 4;
751 mt->valign *= 4;
752 }
753 } else if (mt->format == MESA_FORMAT_S_UINT8) {
754 mt->halign = 8;
755 mt->valign = brw->gen >= 7 ? 8 : 4;
756 } else if (brw->gen >= 9 && mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE) {
757 mt->halign = tr_mode_horizontal_texture_alignment(mt);
758 mt->valign = tr_mode_vertical_texture_alignment(mt);
759 } else {
760 mt->halign =
761 intel_horizontal_texture_alignment_unit(brw, mt, layout_flags);
762 mt->valign = intel_vertical_texture_alignment_unit(brw, mt);
763 }
764 }
765
766 bool
767 brw_miptree_layout(struct brw_context *brw,
768 struct intel_mipmap_tree *mt,
769 uint32_t layout_flags)
770 {
771 mt->tr_mode = INTEL_MIPTREE_TRMODE_NONE;
772
773 intel_miptree_set_alignment(brw, mt, layout_flags);
774 intel_miptree_set_total_width_height(brw, mt);
775
776 if (!mt->total_width || !mt->total_height)
777 return false;
778
779 /* On Gen9+ the alignment values are expressed in multiples of the block
780 * size
781 */
782 if (brw->gen >= 9) {
783 unsigned int i, j;
784 _mesa_get_format_block_size(mt->format, &i, &j);
785 mt->halign /= i;
786 mt->valign /= j;
787 }
788
789 if ((layout_flags & MIPTREE_LAYOUT_FOR_BO) == 0)
790 mt->tiling = brw_miptree_choose_tiling(brw, mt, layout_flags);
791
792 return true;
793 }
794