ilo: check the tilings of imported handles
[mesa.git] / src / gallium / drivers / ilo / ilo_resource.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2013 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 #include "ilo_screen.h"
29 #include "ilo_resource.h"
30
31 /* use PIPE_BIND_CUSTOM to indicate MCS */
32 #define ILO_BIND_MCS PIPE_BIND_CUSTOM
33
34 struct tex_layout {
35 const struct ilo_dev_info *dev;
36 const struct pipe_resource *templ;
37
38 bool has_depth, has_stencil;
39 bool hiz, separate_stencil;
40
41 enum pipe_format format;
42 unsigned block_width, block_height, block_size;
43 bool compressed;
44
45 enum intel_tiling_mode tiling;
46 unsigned valid_tilings; /* bitmask of valid tiling modes */
47
48 bool array_spacing_full;
49 bool interleaved;
50
51 struct {
52 int w, h, d;
53 struct ilo_texture_slice *slices;
54 } levels[PIPE_MAX_TEXTURE_LEVELS];
55
56 int align_i, align_j;
57 int qpitch;
58
59 int width, height;
60
61 int bo_stride, bo_height;
62 int hiz_stride, hiz_height;
63 };
64
65 /*
66 * From the Ivy Bridge PRM, volume 1 part 1, page 105:
67 *
68 * "In addition to restrictions on maximum height, width, and depth,
69 * surfaces are also restricted to a maximum size in bytes. This
70 * maximum is 2 GB for all products and all surface types."
71 */
72 static const size_t max_resource_size = 1u << 31;
73
74 static const char *
75 resource_get_bo_name(const struct pipe_resource *templ)
76 {
77 static const char *target_names[PIPE_MAX_TEXTURE_TYPES] = {
78 [PIPE_BUFFER] = "buf",
79 [PIPE_TEXTURE_1D] = "tex-1d",
80 [PIPE_TEXTURE_2D] = "tex-2d",
81 [PIPE_TEXTURE_3D] = "tex-3d",
82 [PIPE_TEXTURE_CUBE] = "tex-cube",
83 [PIPE_TEXTURE_RECT] = "tex-rect",
84 [PIPE_TEXTURE_1D_ARRAY] = "tex-1d-array",
85 [PIPE_TEXTURE_2D_ARRAY] = "tex-2d-array",
86 [PIPE_TEXTURE_CUBE_ARRAY] = "tex-cube-array",
87 };
88 const char *name = target_names[templ->target];
89
90 if (templ->target == PIPE_BUFFER) {
91 switch (templ->bind) {
92 case PIPE_BIND_VERTEX_BUFFER:
93 name = "buf-vb";
94 break;
95 case PIPE_BIND_INDEX_BUFFER:
96 name = "buf-ib";
97 break;
98 case PIPE_BIND_CONSTANT_BUFFER:
99 name = "buf-cb";
100 break;
101 case PIPE_BIND_STREAM_OUTPUT:
102 name = "buf-so";
103 break;
104 default:
105 break;
106 }
107 }
108
109 return name;
110 }
111
112 static enum intel_domain_flag
113 resource_get_bo_initial_domain(const struct pipe_resource *templ)
114 {
115 return (templ->bind & (PIPE_BIND_DEPTH_STENCIL |
116 PIPE_BIND_RENDER_TARGET |
117 PIPE_BIND_STREAM_OUTPUT)) ?
118 INTEL_DOMAIN_RENDER : 0;
119 }
120
121 static void
122 tex_layout_init_qpitch(struct tex_layout *layout)
123 {
124 const struct pipe_resource *templ = layout->templ;
125 int h0, h1;
126
127 if (templ->array_size <= 1)
128 return;
129
130 h0 = align(layout->levels[0].h, layout->align_j);
131
132 if (!layout->array_spacing_full) {
133 layout->qpitch = h0;
134 return;
135 }
136
137 h1 = align(layout->levels[1].h, layout->align_j);
138
139 /*
140 * From the Sandy Bridge PRM, volume 1 part 1, page 115:
141 *
142 * "The following equation is used for surface formats other than
143 * compressed textures:
144 *
145 * QPitch = (h0 + h1 + 11j)"
146 *
147 * "The equation for compressed textures (BC* and FXT1 surface formats)
148 * follows:
149 *
150 * QPitch = (h0 + h1 + 11j) / 4"
151 *
152 * "[DevSNB] Errata: Sampler MSAA Qpitch will be 4 greater than the
153 * value calculated in the equation above, for every other odd Surface
154 * Height starting from 1 i.e. 1,5,9,13"
155 *
156 * From the Ivy Bridge PRM, volume 1 part 1, page 111-112:
157 *
158 * "If Surface Array Spacing is set to ARYSPC_FULL (note that the depth
159 * buffer and stencil buffer have an implied value of ARYSPC_FULL):
160 *
161 * QPitch = (h0 + h1 + 12j)
162 * QPitch = (h0 + h1 + 12j) / 4 (compressed)
163 *
164 * (There are many typos or missing words here...)"
165 *
166 * To access the N-th slice, an offset of (Stride * QPitch * N) is added to
167 * the base address. The PRM divides QPitch by 4 for compressed formats
168 * because the block height for those formats are 4, and it wants QPitch to
169 * mean the number of memory rows, as opposed to texel rows, between
170 * slices. Since we use texel rows in tex->slice_offsets, we do not need
171 * to divide QPitch by 4.
172 */
173 layout->qpitch = h0 + h1 +
174 ((layout->dev->gen >= ILO_GEN(7)) ? 12 : 11) * layout->align_j;
175
176 if (layout->dev->gen == ILO_GEN(6) && templ->nr_samples > 1 &&
177 templ->height0 % 4 == 1)
178 layout->qpitch += 4;
179 }
180
181 static void
182 tex_layout_init_alignments(struct tex_layout *layout)
183 {
184 const struct pipe_resource *templ = layout->templ;
185
186 /*
187 * From the Sandy Bridge PRM, volume 1 part 1, page 113:
188 *
189 * "surface format align_i align_j
190 * YUV 4:2:2 formats 4 *see below
191 * BC1-5 4 4
192 * FXT1 8 4
193 * all other formats 4 *see below"
194 *
195 * "- align_j = 4 for any depth buffer
196 * - align_j = 2 for separate stencil buffer
197 * - align_j = 4 for any render target surface is multisampled (4x)
198 * - align_j = 4 for any render target surface with Surface Vertical
199 * Alignment = VALIGN_4
200 * - align_j = 2 for any render target surface with Surface Vertical
201 * Alignment = VALIGN_2
202 * - align_j = 2 for all other render target surface
203 * - align_j = 2 for any sampling engine surface with Surface Vertical
204 * Alignment = VALIGN_2
205 * - align_j = 4 for any sampling engine surface with Surface Vertical
206 * Alignment = VALIGN_4"
207 *
208 * From the Sandy Bridge PRM, volume 4 part 1, page 86:
209 *
210 * "This field (Surface Vertical Alignment) must be set to VALIGN_2 if
211 * the Surface Format is 96 bits per element (BPE)."
212 *
213 * They can be rephrased as
214 *
215 * align_i align_j
216 * compressed formats block width block height
217 * PIPE_FORMAT_S8_UINT 4 2
218 * other depth/stencil formats 4 4
219 * 4x multisampled 4 4
220 * bpp 96 4 2
221 * others 4 2 or 4
222 */
223
224 /*
225 * From the Ivy Bridge PRM, volume 1 part 1, page 110:
226 *
227 * "surface defined by surface format align_i align_j
228 * 3DSTATE_DEPTH_BUFFER D16_UNORM 8 4
229 * not D16_UNORM 4 4
230 * 3DSTATE_STENCIL_BUFFER N/A 8 8
231 * SURFACE_STATE BC*, ETC*, EAC* 4 4
232 * FXT1 8 4
233 * all others (set by SURFACE_STATE)"
234 *
235 * From the Ivy Bridge PRM, volume 4 part 1, page 63:
236 *
237 * "- This field (Surface Vertical Aligment) is intended to be set to
238 * VALIGN_4 if the surface was rendered as a depth buffer, for a
239 * multisampled (4x) render target, or for a multisampled (8x)
240 * render target, since these surfaces support only alignment of 4.
241 * - Use of VALIGN_4 for other surfaces is supported, but uses more
242 * memory.
243 * - This field must be set to VALIGN_4 for all tiled Y Render Target
244 * surfaces.
245 * - Value of 1 is not supported for format YCRCB_NORMAL (0x182),
246 * YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY (0x190)
247 * - If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
248 * must be set to VALIGN_4."
249 * - VALIGN_4 is not supported for surface format R32G32B32_FLOAT."
250 *
251 * "- This field (Surface Horizontal Aligment) is intended to be set to
252 * HALIGN_8 only if the surface was rendered as a depth buffer with
253 * Z16 format or a stencil buffer, since these surfaces support only
254 * alignment of 8.
255 * - Use of HALIGN_8 for other surfaces is supported, but uses more
256 * memory.
257 * - This field must be set to HALIGN_4 if the Surface Format is BC*.
258 * - This field must be set to HALIGN_8 if the Surface Format is
259 * FXT1."
260 *
261 * They can be rephrased as
262 *
263 * align_i align_j
264 * compressed formats block width block height
265 * PIPE_FORMAT_Z16_UNORM 8 4
266 * PIPE_FORMAT_S8_UINT 8 8
267 * other depth/stencil formats 4 or 8 4
268 * 2x or 4x multisampled 4 or 8 4
269 * tiled Y 4 or 8 4 (if rt)
270 * PIPE_FORMAT_R32G32B32_FLOAT 4 or 8 2
271 * others 4 or 8 2 or 4
272 */
273
274 if (layout->compressed) {
275 /* this happens to be the case */
276 layout->align_i = layout->block_width;
277 layout->align_j = layout->block_height;
278 }
279 else if (layout->has_depth || layout->has_stencil) {
280 if (layout->dev->gen >= ILO_GEN(7)) {
281 switch (layout->format) {
282 case PIPE_FORMAT_Z16_UNORM:
283 layout->align_i = 8;
284 layout->align_j = 4;
285 break;
286 case PIPE_FORMAT_S8_UINT:
287 layout->align_i = 8;
288 layout->align_j = 8;
289 break;
290 default:
291 layout->align_i = 4;
292 layout->align_j = 4;
293 break;
294 }
295 }
296 else {
297 switch (layout->format) {
298 case PIPE_FORMAT_S8_UINT:
299 layout->align_i = 4;
300 layout->align_j = 2;
301 break;
302 default:
303 layout->align_i = 4;
304 layout->align_j = 4;
305 break;
306 }
307 }
308 }
309 else {
310 const bool valign_4 = (templ->nr_samples > 1) ||
311 (layout->dev->gen >= ILO_GEN(7) &&
312 layout->tiling == INTEL_TILING_Y &&
313 (templ->bind & PIPE_BIND_RENDER_TARGET));
314
315 if (valign_4)
316 assert(layout->block_size != 12);
317
318 layout->align_i = 4;
319 layout->align_j = (valign_4) ? 4 : 2;
320 }
321
322 /*
323 * the fact that align i and j are multiples of block width and height
324 * respectively is what makes the size of the bo a multiple of the block
325 * size, slices start at block boundaries, and many of the computations
326 * work.
327 */
328 assert(layout->align_i % layout->block_width == 0);
329 assert(layout->align_j % layout->block_height == 0);
330
331 /* make sure align() works */
332 assert(util_is_power_of_two(layout->align_i) &&
333 util_is_power_of_two(layout->align_j));
334 assert(util_is_power_of_two(layout->block_width) &&
335 util_is_power_of_two(layout->block_height));
336 }
337
338 static void
339 tex_layout_init_levels(struct tex_layout *layout)
340 {
341 const struct pipe_resource *templ = layout->templ;
342 int last_level, lv;
343
344 last_level = templ->last_level;
345
346 /* need at least 2 levels to compute full qpitch */
347 if (last_level == 0 && templ->array_size > 1 && layout->array_spacing_full)
348 last_level++;
349
350 /* compute mip level sizes */
351 for (lv = 0; lv <= last_level; lv++) {
352 int w, h, d;
353
354 w = u_minify(templ->width0, lv);
355 h = u_minify(templ->height0, lv);
356 d = u_minify(templ->depth0, lv);
357
358 /*
359 * From the Sandy Bridge PRM, volume 1 part 1, page 114:
360 *
361 * "The dimensions of the mip maps are first determined by applying
362 * the sizing algorithm presented in Non-Power-of-Two Mipmaps
363 * above. Then, if necessary, they are padded out to compression
364 * block boundaries."
365 */
366 w = align(w, layout->block_width);
367 h = align(h, layout->block_height);
368
369 /*
370 * From the Sandy Bridge PRM, volume 1 part 1, page 111:
371 *
372 * "If the surface is multisampled (4x), these values must be
373 * adjusted as follows before proceeding:
374 *
375 * W_L = ceiling(W_L / 2) * 4
376 * H_L = ceiling(H_L / 2) * 4"
377 *
378 * From the Ivy Bridge PRM, volume 1 part 1, page 108:
379 *
380 * "If the surface is multisampled and it is a depth or stencil
381 * surface or Multisampled Surface StorageFormat in SURFACE_STATE
382 * is MSFMT_DEPTH_STENCIL, W_L and H_L must be adjusted as follows
383 * before proceeding:
384 *
385 * #samples W_L = H_L =
386 * 2 ceiling(W_L / 2) * 4 HL [no adjustment]
387 * 4 ceiling(W_L / 2) * 4 ceiling(H_L / 2) * 4
388 * 8 ceiling(W_L / 2) * 8 ceiling(H_L / 2) * 4
389 * 16 ceiling(W_L / 2) * 8 ceiling(H_L / 2) * 8"
390 *
391 * For interleaved samples (4x), where pixels
392 *
393 * (x, y ) (x+1, y )
394 * (x, y+1) (x+1, y+1)
395 *
396 * would be is occupied by
397 *
398 * (x, y , si0) (x+1, y , si0) (x, y , si1) (x+1, y , si1)
399 * (x, y+1, si0) (x+1, y+1, si0) (x, y+1, si1) (x+1, y+1, si1)
400 * (x, y , si2) (x+1, y , si2) (x, y , si3) (x+1, y , si3)
401 * (x, y+1, si2) (x+1, y+1, si2) (x, y+1, si3) (x+1, y+1, si3)
402 *
403 * Thus the need to
404 *
405 * w = align(w, 2) * 2;
406 * y = align(y, 2) * 2;
407 */
408 if (layout->interleaved) {
409 switch (templ->nr_samples) {
410 case 0:
411 case 1:
412 break;
413 case 2:
414 w = align(w, 2) * 2;
415 break;
416 case 4:
417 w = align(w, 2) * 2;
418 h = align(h, 2) * 2;
419 break;
420 case 8:
421 w = align(w, 2) * 4;
422 h = align(h, 2) * 2;
423 break;
424 case 16:
425 w = align(w, 2) * 4;
426 h = align(h, 2) * 4;
427 break;
428 default:
429 assert(!"unsupported sample count");
430 break;
431 }
432 }
433
434 layout->levels[lv].w = w;
435 layout->levels[lv].h = h;
436 layout->levels[lv].d = d;
437 }
438 }
439
440 static void
441 tex_layout_init_spacing(struct tex_layout *layout)
442 {
443 const struct pipe_resource *templ = layout->templ;
444
445 if (layout->dev->gen >= ILO_GEN(7)) {
446 /*
447 * It is not explicitly states, but render targets are expected to be
448 * UMS/CMS (samples non-interleaved) and depth/stencil buffers are
449 * expected to be IMS (samples interleaved).
450 *
451 * See "Multisampled Surface Storage Format" field of SURFACE_STATE.
452 */
453 if (layout->has_depth || layout->has_stencil) {
454 layout->interleaved = true;
455
456 /*
457 * From the Ivy Bridge PRM, volume 1 part 1, page 111:
458 *
459 * "note that the depth buffer and stencil buffer have an implied
460 * value of ARYSPC_FULL"
461 */
462 layout->array_spacing_full = true;
463 }
464 else {
465 layout->interleaved = false;
466
467 /*
468 * From the Ivy Bridge PRM, volume 4 part 1, page 66:
469 *
470 * "If Multisampled Surface Storage Format is MSFMT_MSS and
471 * Number of Multisamples is not MULTISAMPLECOUNT_1, this field
472 * (Surface Array Spacing) must be set to ARYSPC_LOD0."
473 *
474 * As multisampled resources are not mipmapped, we never use
475 * ARYSPC_FULL for them.
476 */
477 if (templ->nr_samples > 1)
478 assert(templ->last_level == 0);
479 layout->array_spacing_full = (templ->last_level > 0);
480 }
481 }
482 else {
483 /* GEN6 supports only interleaved samples */
484 layout->interleaved = true;
485
486 /*
487 * From the Sandy Bridge PRM, volume 1 part 1, page 115:
488 *
489 * "The separate stencil buffer does not support mip mapping, thus
490 * the storage for LODs other than LOD 0 is not needed. The
491 * following QPitch equation applies only to the separate stencil
492 * buffer:
493 *
494 * QPitch = h_0"
495 *
496 * GEN6 does not support compact spacing otherwise.
497 */
498 layout->array_spacing_full = (layout->format != PIPE_FORMAT_S8_UINT);
499 }
500 }
501
502 static void
503 tex_layout_init_tiling(struct tex_layout *layout)
504 {
505 const struct pipe_resource *templ = layout->templ;
506 const enum pipe_format format = layout->format;
507 const unsigned tile_none = 1 << INTEL_TILING_NONE;
508 const unsigned tile_x = 1 << INTEL_TILING_X;
509 const unsigned tile_y = 1 << INTEL_TILING_Y;
510 unsigned valid_tilings = tile_none | tile_x | tile_y;
511
512 /*
513 * From the Sandy Bridge PRM, volume 1 part 2, page 32:
514 *
515 * "Display/Overlay Y-Major not supported.
516 * X-Major required for Async Flips"
517 */
518 if (unlikely(templ->bind & PIPE_BIND_SCANOUT))
519 valid_tilings &= tile_x;
520
521 /*
522 * From the Sandy Bridge PRM, volume 3 part 2, page 158:
523 *
524 * "The cursor surface address must be 4K byte aligned. The cursor must
525 * be in linear memory, it cannot be tiled."
526 */
527 if (unlikely(templ->bind & (PIPE_BIND_CURSOR | PIPE_BIND_LINEAR)))
528 valid_tilings &= tile_none;
529
530 /*
531 * From the Ivy Bridge PRM, volume 4 part 1, page 76:
532 *
533 * "The MCS surface must be stored as Tile Y."
534 */
535 if (templ->bind & ILO_BIND_MCS)
536 valid_tilings &= tile_y;
537
538 /*
539 * From the Sandy Bridge PRM, volume 2 part 1, page 318:
540 *
541 * "[DevSNB+]: This field (Tiled Surface) must be set to TRUE. Linear
542 * Depth Buffer is not supported."
543 *
544 * "The Depth Buffer, if tiled, must use Y-Major tiling."
545 *
546 * From the Sandy Bridge PRM, volume 1 part 2, page 22:
547 *
548 * "W-Major Tile Format is used for separate stencil."
549 *
550 * Since the HW does not support W-tiled fencing, we have to do it in the
551 * driver.
552 */
553 if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
554 switch (format) {
555 case PIPE_FORMAT_S8_UINT:
556 valid_tilings &= tile_none;
557 break;
558 default:
559 valid_tilings &= tile_y;
560 break;
561 }
562 }
563
564 if (templ->bind & PIPE_BIND_RENDER_TARGET) {
565 /*
566 * From the Sandy Bridge PRM, volume 1 part 2, page 32:
567 *
568 * "NOTE: 128BPE Format Color buffer ( render target ) MUST be
569 * either TileX or Linear."
570 */
571 if (layout->block_size == 16)
572 valid_tilings &= ~tile_y;
573
574 /*
575 * From the Ivy Bridge PRM, volume 4 part 1, page 63:
576 *
577 * "This field (Surface Vertical Aligment) must be set to VALIGN_4
578 * for all tiled Y Render Target surfaces."
579 *
580 * "VALIGN_4 is not supported for surface format R32G32B32_FLOAT."
581 */
582 if (layout->dev->gen >= ILO_GEN(7) && layout->block_size == 12)
583 valid_tilings &= ~tile_y;
584 }
585
586 /* no conflicting binding flags */
587 assert(valid_tilings);
588
589 layout->valid_tilings = valid_tilings;
590
591 if (templ->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) {
592 /*
593 * heuristically set a minimum width/height for enabling tiling
594 */
595 if (templ->width0 < 64 && (valid_tilings & ~tile_x))
596 valid_tilings &= ~tile_x;
597
598 if ((templ->width0 < 32 || templ->height0 < 16) &&
599 (templ->width0 < 16 || templ->height0 < 32) &&
600 (valid_tilings & ~tile_y))
601 valid_tilings &= ~tile_y;
602 }
603 else {
604 /* force linear if we are not sure where the texture is bound to */
605 if (valid_tilings & tile_none)
606 valid_tilings &= tile_none;
607 }
608
609 /* prefer tiled over linear */
610 if (valid_tilings & tile_y)
611 layout->tiling = INTEL_TILING_Y;
612 else if (valid_tilings & tile_x)
613 layout->tiling = INTEL_TILING_X;
614 else
615 layout->tiling = INTEL_TILING_NONE;
616 }
617
618 static void
619 tex_layout_init_format(struct tex_layout *layout)
620 {
621 const struct pipe_resource *templ = layout->templ;
622 enum pipe_format format;
623
624 switch (templ->format) {
625 case PIPE_FORMAT_ETC1_RGB8:
626 format = PIPE_FORMAT_R8G8B8X8_UNORM;
627 break;
628 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
629 if (layout->separate_stencil)
630 format = PIPE_FORMAT_Z24X8_UNORM;
631 else
632 format = templ->format;
633 break;
634 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
635 if (layout->separate_stencil)
636 format = PIPE_FORMAT_Z32_FLOAT;
637 else
638 format = templ->format;
639 break;
640 default:
641 format = templ->format;
642 break;
643 }
644
645 layout->format = format;
646
647 layout->block_width = util_format_get_blockwidth(format);
648 layout->block_height = util_format_get_blockheight(format);
649 layout->block_size = util_format_get_blocksize(format);
650 layout->compressed = util_format_is_compressed(format);
651 }
652
653 static void
654 tex_layout_init_hiz(struct tex_layout *layout)
655 {
656 const struct pipe_resource *templ = layout->templ;
657 const struct util_format_description *desc;
658
659 desc = util_format_description(templ->format);
660 layout->has_depth = util_format_has_depth(desc);
661 layout->has_stencil = util_format_has_stencil(desc);
662
663 if (!layout->has_depth)
664 return;
665
666 layout->hiz = true;
667
668 /* no point in having HiZ */
669 if (templ->usage == PIPE_USAGE_STAGING)
670 layout->hiz = false;
671
672 if (layout->dev->gen == ILO_GEN(6)) {
673 /*
674 * From the Sandy Bridge PRM, volume 2 part 1, page 312:
675 *
676 * "The hierarchical depth buffer does not support the LOD field, it
677 * is assumed by hardware to be zero. A separate hierarachical
678 * depth buffer is required for each LOD used, and the
679 * corresponding buffer's state delivered to hardware each time a
680 * new depth buffer state with modified LOD is delivered."
681 *
682 * But we have a stronger requirement. Because of layer offsetting
683 * (check out the callers of ilo_texture_get_slice_offset()), we already
684 * have to require the texture to be non-mipmapped and non-array.
685 */
686 if (templ->last_level > 0 || templ->array_size > 1 || templ->depth0 > 1)
687 layout->hiz = false;
688 }
689
690 if (ilo_debug & ILO_DEBUG_NOHIZ)
691 layout->hiz = false;
692
693 if (layout->has_stencil) {
694 /*
695 * From the Sandy Bridge PRM, volume 2 part 1, page 317:
696 *
697 * "This field (Separate Stencil Buffer Enable) must be set to the
698 * same value (enabled or disabled) as Hierarchical Depth Buffer
699 * Enable."
700 *
701 * GEN7+ requires separate stencil buffers.
702 */
703 if (layout->dev->gen >= ILO_GEN(7))
704 layout->separate_stencil = true;
705 else
706 layout->separate_stencil = layout->hiz;
707
708 if (layout->separate_stencil)
709 layout->has_stencil = false;
710 }
711 }
712
713 static void
714 tex_layout_init(struct tex_layout *layout,
715 struct pipe_screen *screen,
716 const struct pipe_resource *templ,
717 struct ilo_texture_slice **slices)
718 {
719 struct ilo_screen *is = ilo_screen(screen);
720
721 memset(layout, 0, sizeof(*layout));
722
723 layout->dev = &is->dev;
724 layout->templ = templ;
725
726 /* note that there are dependencies between these functions */
727 tex_layout_init_hiz(layout);
728 tex_layout_init_format(layout);
729 tex_layout_init_tiling(layout);
730 tex_layout_init_spacing(layout);
731 tex_layout_init_levels(layout);
732 tex_layout_init_alignments(layout);
733 tex_layout_init_qpitch(layout);
734
735 if (slices) {
736 int lv;
737
738 for (lv = 0; lv <= templ->last_level; lv++)
739 layout->levels[lv].slices = slices[lv];
740 }
741 }
742
743 static void
744 tex_layout_align(struct tex_layout *layout)
745 {
746 int align_w = 1, align_h = 1, pad_h = 0;
747
748 /*
749 * From the Sandy Bridge PRM, volume 1 part 1, page 118:
750 *
751 * "To determine the necessary padding on the bottom and right side of
752 * the surface, refer to the table in Section 7.18.3.4 for the i and j
753 * parameters for the surface format in use. The surface must then be
754 * extended to the next multiple of the alignment unit size in each
755 * dimension, and all texels contained in this extended surface must
756 * have valid GTT entries."
757 *
758 * "For cube surfaces, an additional two rows of padding are required
759 * at the bottom of the surface. This must be ensured regardless of
760 * whether the surface is stored tiled or linear. This is due to the
761 * potential rotation of cache line orientation from memory to cache."
762 *
763 * "For compressed textures (BC* and FXT1 surface formats), padding at
764 * the bottom of the surface is to an even compressed row, which is
765 * equal to a multiple of 8 uncompressed texel rows. Thus, for padding
766 * purposes, these surfaces behave as if j = 8 only for surface
767 * padding purposes. The value of 4 for j still applies for mip level
768 * alignment and QPitch calculation."
769 */
770 if (layout->templ->bind & PIPE_BIND_SAMPLER_VIEW) {
771 align_w = MAX2(align_w, layout->align_i);
772 align_h = MAX2(align_h, layout->align_j);
773
774 if (layout->templ->target == PIPE_TEXTURE_CUBE)
775 pad_h += 2;
776
777 if (layout->compressed)
778 align_h = MAX2(align_h, layout->align_j * 2);
779 }
780
781 /*
782 * From the Sandy Bridge PRM, volume 1 part 1, page 118:
783 *
784 * "If the surface contains an odd number of rows of data, a final row
785 * below the surface must be allocated."
786 */
787 if (layout->templ->bind & PIPE_BIND_RENDER_TARGET)
788 align_h = MAX2(align_h, 2);
789
790 /*
791 * Depth Buffer Clear/Resolve works in 8x4 sample blocks. In
792 * ilo_texture_can_enable_hiz(), we always return true for the first slice.
793 * To avoid out-of-bound access, we have to pad.
794 */
795 if (layout->hiz) {
796 align_w = MAX2(align_w, 8);
797 align_h = MAX2(align_h, 4);
798 }
799
800 layout->width = align(layout->width, align_w);
801 layout->height = align(layout->height + pad_h, align_h);
802 }
803
804 /**
805 * Layout a 2D texture.
806 */
807 static void
808 tex_layout_2d(struct tex_layout *layout)
809 {
810 const struct pipe_resource *templ = layout->templ;
811 unsigned int level_x, level_y, num_slices;
812 int lv;
813
814 level_x = 0;
815 level_y = 0;
816 for (lv = 0; lv <= templ->last_level; lv++) {
817 const unsigned int level_w = layout->levels[lv].w;
818 const unsigned int level_h = layout->levels[lv].h;
819 int slice;
820
821 /* set slice offsets */
822 if (layout->levels[lv].slices) {
823 for (slice = 0; slice < templ->array_size; slice++) {
824 layout->levels[lv].slices[slice].x = level_x;
825 /* slices are qpitch apart in Y-direction */
826 layout->levels[lv].slices[slice].y =
827 level_y + layout->qpitch * slice;
828 }
829 }
830
831 /* extend the size of the monolithic bo to cover this mip level */
832 if (layout->width < level_x + level_w)
833 layout->width = level_x + level_w;
834 if (layout->height < level_y + level_h)
835 layout->height = level_y + level_h;
836
837 /* MIPLAYOUT_BELOW */
838 if (lv == 1)
839 level_x += align(level_w, layout->align_i);
840 else
841 level_y += align(level_h, layout->align_j);
842 }
843
844 num_slices = templ->array_size;
845 /* samples of the same index are stored in a slice */
846 if (templ->nr_samples > 1 && !layout->interleaved)
847 num_slices *= templ->nr_samples;
848
849 /* we did not take slices into consideration in the computation above */
850 layout->height += layout->qpitch * (num_slices - 1);
851
852 tex_layout_align(layout);
853 }
854
855 /**
856 * Layout a 3D texture.
857 */
858 static void
859 tex_layout_3d(struct tex_layout *layout)
860 {
861 const struct pipe_resource *templ = layout->templ;
862 unsigned int level_y;
863 int lv;
864
865 level_y = 0;
866 for (lv = 0; lv <= templ->last_level; lv++) {
867 const unsigned int level_w = layout->levels[lv].w;
868 const unsigned int level_h = layout->levels[lv].h;
869 const unsigned int level_d = layout->levels[lv].d;
870 const unsigned int slice_pitch = align(level_w, layout->align_i);
871 const unsigned int slice_qpitch = align(level_h, layout->align_j);
872 const unsigned int num_slices_per_row = 1 << lv;
873 int slice;
874
875 for (slice = 0; slice < level_d; slice += num_slices_per_row) {
876 int i;
877
878 /* set slice offsets */
879 if (layout->levels[lv].slices) {
880 for (i = 0; i < num_slices_per_row && slice + i < level_d; i++) {
881 layout->levels[lv].slices[slice + i].x = slice_pitch * i;
882 layout->levels[lv].slices[slice + i].y = level_y;
883 }
884 }
885
886 /* move on to the next slice row */
887 level_y += slice_qpitch;
888 }
889
890 /* rightmost slice */
891 slice = MIN2(num_slices_per_row, level_d) - 1;
892
893 /* extend the size of the monolithic bo to cover this slice */
894 if (layout->width < slice_pitch * slice + level_w)
895 layout->width = slice_pitch * slice + level_w;
896 if (lv == templ->last_level)
897 layout->height = (level_y - slice_qpitch) + level_h;
898 }
899
900 tex_layout_align(layout);
901 }
902
903 /* note that this may force the texture to be linear */
904 static bool
905 tex_layout_calculate_bo_size(struct tex_layout *layout)
906 {
907 assert(layout->width % layout->block_width == 0);
908 assert(layout->height % layout->block_height == 0);
909 assert(layout->qpitch % layout->block_height == 0);
910
911 layout->bo_stride =
912 (layout->width / layout->block_width) * layout->block_size;
913 layout->bo_height = layout->height / layout->block_height;
914
915 while (true) {
916 int w = layout->bo_stride, h = layout->bo_height;
917 int align_w, align_h;
918
919 /*
920 * From the Haswell PRM, volume 5, page 163:
921 *
922 * "For linear surfaces, additional padding of 64 bytes is required
923 * at the bottom of the surface. This is in addition to the padding
924 * required above."
925 */
926 if (layout->dev->gen >= ILO_GEN(7.5) &&
927 (layout->templ->bind & PIPE_BIND_SAMPLER_VIEW) &&
928 layout->tiling == INTEL_TILING_NONE) {
929 layout->bo_height +=
930 (64 + layout->bo_stride - 1) / layout->bo_stride;
931 }
932
933 /*
934 * From the Sandy Bridge PRM, volume 4 part 1, page 81:
935 *
936 * "- For linear render target surfaces, the pitch must be a
937 * multiple of the element size for non-YUV surface formats.
938 * Pitch must be a multiple of 2 * element size for YUV surface
939 * formats.
940 * - For other linear surfaces, the pitch can be any multiple of
941 * bytes.
942 * - For tiled surfaces, the pitch must be a multiple of the tile
943 * width."
944 *
945 * Different requirements may exist when the bo is used in different
946 * places, but our alignments here should be good enough that we do not
947 * need to check layout->templ->bind.
948 */
949 switch (layout->tiling) {
950 case INTEL_TILING_X:
951 align_w = 512;
952 align_h = 8;
953 break;
954 case INTEL_TILING_Y:
955 align_w = 128;
956 align_h = 32;
957 break;
958 default:
959 if (layout->format == PIPE_FORMAT_S8_UINT) {
960 /*
961 * From the Sandy Bridge PRM, volume 1 part 2, page 22:
962 *
963 * "A 4KB tile is subdivided into 8-high by 8-wide array of
964 * Blocks for W-Major Tiles (W Tiles). Each Block is 8 rows by 8
965 * bytes."
966 *
967 * Since we asked for INTEL_TILING_NONE instead of the non-existent
968 * INTEL_TILING_W, we want to align to W tiles here.
969 */
970 align_w = 64;
971 align_h = 64;
972 }
973 else {
974 /* some good enough values */
975 align_w = 64;
976 align_h = 2;
977 }
978 break;
979 }
980
981 w = align(w, align_w);
982 h = align(h, align_h);
983
984 /* make sure the bo is mappable */
985 if (layout->tiling != INTEL_TILING_NONE) {
986 /*
987 * Usually only the first 256MB of the GTT is mappable.
988 *
989 * See also how intel_context::max_gtt_map_object_size is calculated.
990 */
991 const size_t mappable_gtt_size = 256 * 1024 * 1024;
992
993 /*
994 * Be conservative. We may be able to switch from VALIGN_4 to
995 * VALIGN_2 if the layout was Y-tiled, but let's keep it simple.
996 */
997 if (mappable_gtt_size / w / 4 < h) {
998 if (layout->valid_tilings & (1 << INTEL_TILING_NONE)) {
999 layout->tiling = INTEL_TILING_NONE;
1000 continue;
1001 }
1002 else {
1003 ilo_warn("cannot force texture to be linear\n");
1004 }
1005 }
1006 }
1007
1008 layout->bo_stride = w;
1009 layout->bo_height = h;
1010 break;
1011 }
1012
1013 return (layout->bo_height <= max_resource_size / layout->bo_stride);
1014 }
1015
1016 static void
1017 tex_layout_calculate_hiz_size(struct tex_layout *layout)
1018 {
1019 const struct pipe_resource *templ = layout->templ;
1020 const int hz_align_j = 8;
1021 int hz_width, hz_height;
1022
1023 if (!layout->hiz)
1024 return;
1025
1026 /*
1027 * See the Sandy Bridge PRM, volume 2 part 1, page 312, and the Ivy Bridge
1028 * PRM, volume 2 part 1, page 312-313.
1029 *
1030 * It seems HiZ buffer is aligned to 8x8, with every two rows packed into a
1031 * memory row.
1032 */
1033
1034 hz_width = align(layout->levels[0].w, 16);
1035
1036 if (templ->target == PIPE_TEXTURE_3D) {
1037 unsigned lv;
1038
1039 hz_height = 0;
1040
1041 for (lv = 0; lv <= templ->last_level; lv++) {
1042 const unsigned h = align(layout->levels[lv].h, hz_align_j);
1043 hz_height += h * layout->levels[lv].d;
1044 }
1045
1046 hz_height /= 2;
1047 }
1048 else {
1049 const unsigned h0 = align(layout->levels[0].h, hz_align_j);
1050 unsigned hz_qpitch = h0;
1051
1052 if (layout->array_spacing_full) {
1053 const unsigned h1 = align(layout->levels[1].h, hz_align_j);
1054 const unsigned htail =
1055 ((layout->dev->gen >= ILO_GEN(7)) ? 12 : 11) * hz_align_j;
1056
1057 hz_qpitch += h1 + htail;
1058 }
1059
1060 hz_height = hz_qpitch * templ->array_size / 2;
1061
1062 if (layout->dev->gen >= ILO_GEN(7))
1063 hz_height = align(hz_height, 8);
1064 }
1065
1066 /* align to Y-tile */
1067 layout->hiz_stride = align(hz_width, 128);
1068 layout->hiz_height = align(hz_height, 32);
1069 }
1070
1071 static void
1072 tex_free_slices(struct ilo_texture *tex)
1073 {
1074 FREE(tex->slices[0]);
1075 }
1076
1077 static bool
1078 tex_alloc_slices(struct ilo_texture *tex)
1079 {
1080 const struct pipe_resource *templ = &tex->base;
1081 struct ilo_texture_slice *slices;
1082 int depth, lv;
1083
1084 /* sum the depths of all levels */
1085 depth = 0;
1086 for (lv = 0; lv <= templ->last_level; lv++)
1087 depth += u_minify(templ->depth0, lv);
1088
1089 /*
1090 * There are (depth * tex->base.array_size) slices in total. Either depth
1091 * is one (non-3D) or templ->array_size is one (non-array), but it does
1092 * not matter.
1093 */
1094 slices = CALLOC(depth * templ->array_size, sizeof(*slices));
1095 if (!slices)
1096 return false;
1097
1098 tex->slices[0] = slices;
1099
1100 /* point to the respective positions in the buffer */
1101 for (lv = 1; lv <= templ->last_level; lv++) {
1102 tex->slices[lv] = tex->slices[lv - 1] +
1103 u_minify(templ->depth0, lv - 1) * templ->array_size;
1104 }
1105
1106 return true;
1107 }
1108
1109 static bool
1110 tex_import_handle(struct ilo_texture *tex,
1111 const struct tex_layout *layout,
1112 const struct winsys_handle *handle)
1113 {
1114 struct ilo_screen *is = ilo_screen(tex->base.screen);
1115 const char *name = resource_get_bo_name(&tex->base);
1116 enum intel_tiling_mode tiling;
1117 unsigned long pitch;
1118
1119 tex->bo = intel_winsys_import_handle(is->winsys, name, handle,
1120 tex->bo_height, &tiling, &pitch);
1121 if (!tex->bo)
1122 return false;
1123
1124 if (!(layout->valid_tilings & (1 << tiling))) {
1125 ilo_err("imported handle has incompatible tiling\n");
1126 intel_bo_unreference(tex->bo);
1127 tex->bo = NULL;
1128 return false;
1129 }
1130
1131 tex->tiling = tiling;
1132 tex->bo_stride = pitch;
1133
1134 return true;
1135 }
1136
1137 static bool
1138 tex_create_bo(struct ilo_texture *tex)
1139 {
1140 struct ilo_screen *is = ilo_screen(tex->base.screen);
1141 const char *name = resource_get_bo_name(&tex->base);
1142 const enum intel_domain_flag initial_domain =
1143 resource_get_bo_initial_domain(&tex->base);
1144
1145 tex->bo = intel_winsys_alloc_bo(is->winsys, name, tex->tiling,
1146 tex->bo_stride, tex->bo_height, initial_domain);
1147
1148 return (tex->bo != NULL);
1149 }
1150
1151 static bool
1152 tex_create_separate_stencil(struct ilo_texture *tex)
1153 {
1154 struct pipe_resource templ = tex->base;
1155 struct pipe_resource *s8;
1156
1157 /*
1158 * Unless PIPE_BIND_DEPTH_STENCIL is set, the resource may have other
1159 * tilings. But that should be fine since it will never be bound as the
1160 * stencil buffer, and our transfer code can handle all tilings.
1161 */
1162 templ.format = PIPE_FORMAT_S8_UINT;
1163
1164 s8 = tex->base.screen->resource_create(tex->base.screen, &templ);
1165 if (!s8)
1166 return false;
1167
1168 tex->separate_s8 = ilo_texture(s8);
1169
1170 assert(tex->separate_s8->bo_format == PIPE_FORMAT_S8_UINT);
1171
1172 return true;
1173 }
1174
1175 static bool
1176 tex_create_hiz(struct ilo_texture *tex, const struct tex_layout *layout)
1177 {
1178 struct ilo_screen *is = ilo_screen(tex->base.screen);
1179 const struct pipe_resource *templ = layout->templ;
1180 unsigned lv;
1181
1182 tex->hiz.bo = intel_winsys_alloc_bo(is->winsys, "hiz texture",
1183 INTEL_TILING_Y, layout->hiz_stride, layout->hiz_height,
1184 INTEL_DOMAIN_RENDER);
1185 if (!tex->hiz.bo)
1186 return false;
1187
1188 tex->hiz.bo_stride = layout->hiz_stride;
1189
1190 /*
1191 * From the Sandy Bridge PRM, volume 2 part 1, page 313-314:
1192 *
1193 * "A rectangle primitive representing the clear area is delivered. The
1194 * primitive must adhere to the following restrictions on size:
1195 *
1196 * - If Number of Multisamples is NUMSAMPLES_1, the rectangle must be
1197 * aligned to an 8x4 pixel block relative to the upper left corner
1198 * of the depth buffer, and contain an integer number of these pixel
1199 * blocks, and all 8x4 pixels must be lit.
1200 *
1201 * - If Number of Multisamples is NUMSAMPLES_4, the rectangle must be
1202 * aligned to a 4x2 pixel block (8x4 sample block) relative to the
1203 * upper left corner of the depth buffer, and contain an integer
1204 * number of these pixel blocks, and all samples of the 4x2 pixels
1205 * must be lit
1206 *
1207 * - If Number of Multisamples is NUMSAMPLES_8, the rectangle must be
1208 * aligned to a 2x2 pixel block (8x4 sample block) relative to the
1209 * upper left corner of the depth buffer, and contain an integer
1210 * number of these pixel blocks, and all samples of the 2x2 pixels
1211 * must be list."
1212 *
1213 * "The following is required when performing a depth buffer resolve:
1214 *
1215 * - A rectangle primitive of the same size as the previous depth
1216 * buffer clear operation must be delivered, and depth buffer state
1217 * cannot have changed since the previous depth buffer clear
1218 * operation."
1219 *
1220 * Experiments on Haswell show that depth buffer resolves have the same
1221 * alignment requirements, and aligning the RECTLIST primitive and
1222 * 3DSTATE_DRAWING_RECTANGLE alone are not enough. The mipmap size must be
1223 * aligned.
1224 */
1225 for (lv = 0; lv <= templ->last_level; lv++) {
1226 unsigned align_w = 8, align_h = 4;
1227 unsigned flags = 0;
1228
1229 switch (templ->nr_samples) {
1230 case 0:
1231 case 1:
1232 break;
1233 case 2:
1234 align_w /= 2;
1235 break;
1236 case 4:
1237 align_w /= 2;
1238 align_h /= 2;
1239 break;
1240 case 8:
1241 default:
1242 align_w /= 4;
1243 align_h /= 2;
1244 break;
1245 }
1246
1247 if (u_minify(templ->width0, lv) % align_w == 0 &&
1248 u_minify(templ->height0, lv) % align_h == 0) {
1249 flags |= ILO_TEXTURE_HIZ;
1250
1251 /* this will trigger a HiZ resolve */
1252 if (tex->imported)
1253 flags |= ILO_TEXTURE_CPU_WRITE;
1254 }
1255
1256 if (flags) {
1257 const unsigned num_slices = (templ->target == PIPE_TEXTURE_3D) ?
1258 u_minify(templ->depth0, lv) : templ->array_size;
1259 ilo_texture_set_slice_flags(tex, lv, 0, num_slices, flags, flags);
1260 }
1261 }
1262
1263 return true;
1264 }
1265
1266 static bool
1267 tex_apply_layout(struct ilo_texture *tex,
1268 const struct tex_layout *layout,
1269 const struct winsys_handle *handle)
1270 {
1271 tex->bo_format = layout->format;
1272
1273 tex->tiling = layout->tiling;
1274 tex->bo_stride = layout->bo_stride;
1275 tex->bo_height = layout->bo_height;
1276
1277 tex->block_width = layout->block_width;
1278 tex->block_height = layout->block_height;
1279 tex->block_size = layout->block_size;
1280
1281 tex->halign_8 = (layout->align_i == 8);
1282 tex->valign_4 = (layout->align_j == 4);
1283 tex->array_spacing_full = layout->array_spacing_full;
1284 tex->interleaved = layout->interleaved;
1285
1286 if (handle) {
1287 if (!tex_import_handle(tex, layout, handle))
1288 return false;
1289 }
1290 else {
1291 if (!tex_create_bo(tex))
1292 return false;
1293 }
1294
1295 /* allocate separate stencil resource */
1296 if (layout->separate_stencil && !tex_create_separate_stencil(tex))
1297 return false;
1298
1299 if (layout->hiz && !tex_create_hiz(tex, layout)) {
1300 /* Separate Stencil Buffer requires HiZ to be enabled */
1301 if (layout->dev->gen == ILO_GEN(6) && layout->separate_stencil)
1302 return false;
1303 }
1304
1305 return true;
1306 }
1307
1308 static void
1309 tex_destroy(struct ilo_texture *tex)
1310 {
1311 if (tex->hiz.bo)
1312 intel_bo_unreference(tex->hiz.bo);
1313
1314 if (tex->separate_s8)
1315 tex_destroy(tex->separate_s8);
1316
1317 if (tex->bo)
1318 intel_bo_unreference(tex->bo);
1319
1320 tex_free_slices(tex);
1321 FREE(tex);
1322 }
1323
1324 static struct pipe_resource *
1325 tex_create(struct pipe_screen *screen,
1326 const struct pipe_resource *templ,
1327 const struct winsys_handle *handle)
1328 {
1329 struct tex_layout layout;
1330 struct ilo_texture *tex;
1331
1332 tex = CALLOC_STRUCT(ilo_texture);
1333 if (!tex)
1334 return NULL;
1335
1336 tex->base = *templ;
1337 tex->base.screen = screen;
1338 pipe_reference_init(&tex->base.reference, 1);
1339
1340 if (!tex_alloc_slices(tex)) {
1341 FREE(tex);
1342 return NULL;
1343 }
1344
1345 tex->imported = (handle != NULL);
1346
1347 tex_layout_init(&layout, screen, templ, tex->slices);
1348
1349 switch (templ->target) {
1350 case PIPE_TEXTURE_1D:
1351 case PIPE_TEXTURE_2D:
1352 case PIPE_TEXTURE_CUBE:
1353 case PIPE_TEXTURE_RECT:
1354 case PIPE_TEXTURE_1D_ARRAY:
1355 case PIPE_TEXTURE_2D_ARRAY:
1356 case PIPE_TEXTURE_CUBE_ARRAY:
1357 tex_layout_2d(&layout);
1358 break;
1359 case PIPE_TEXTURE_3D:
1360 tex_layout_3d(&layout);
1361 break;
1362 default:
1363 assert(!"unknown resource target");
1364 break;
1365 }
1366
1367 if (!tex_layout_calculate_bo_size(&layout)) {
1368 tex_destroy(tex);
1369 return NULL;
1370 }
1371
1372 tex_layout_calculate_hiz_size(&layout);
1373
1374 if (!tex_apply_layout(tex, &layout, handle)) {
1375 tex_destroy(tex);
1376 return NULL;
1377 }
1378
1379 return &tex->base;
1380 }
1381
1382 static bool
1383 tex_get_handle(struct ilo_texture *tex, struct winsys_handle *handle)
1384 {
1385 struct ilo_screen *is = ilo_screen(tex->base.screen);
1386 int err;
1387
1388 err = intel_winsys_export_handle(is->winsys, tex->bo,
1389 tex->tiling, tex->bo_stride, tex->bo_height, handle);
1390
1391 return !err;
1392 }
1393
1394 static bool
1395 buf_create_bo(struct ilo_buffer *buf)
1396 {
1397 struct ilo_screen *is = ilo_screen(buf->base.screen);
1398 const char *name = resource_get_bo_name(&buf->base);
1399 const enum intel_domain_flag initial_domain =
1400 resource_get_bo_initial_domain(&buf->base);
1401
1402 buf->bo = intel_winsys_alloc_buffer(is->winsys, name,
1403 buf->bo_size, initial_domain);
1404
1405 return (buf->bo != NULL);
1406 }
1407
1408 static void
1409 buf_destroy(struct ilo_buffer *buf)
1410 {
1411 intel_bo_unreference(buf->bo);
1412 FREE(buf);
1413 }
1414
1415 static struct pipe_resource *
1416 buf_create(struct pipe_screen *screen, const struct pipe_resource *templ)
1417 {
1418 const struct ilo_screen *is = ilo_screen(screen);
1419 struct ilo_buffer *buf;
1420
1421 buf = CALLOC_STRUCT(ilo_buffer);
1422 if (!buf)
1423 return NULL;
1424
1425 buf->base = *templ;
1426 buf->base.screen = screen;
1427 pipe_reference_init(&buf->base.reference, 1);
1428
1429 buf->bo_size = templ->width0;
1430
1431 /*
1432 * From the Sandy Bridge PRM, volume 1 part 1, page 118:
1433 *
1434 * "For buffers, which have no inherent "height," padding requirements
1435 * are different. A buffer must be padded to the next multiple of 256
1436 * array elements, with an additional 16 bytes added beyond that to
1437 * account for the L1 cache line."
1438 */
1439 if (templ->bind & PIPE_BIND_SAMPLER_VIEW)
1440 buf->bo_size = align(buf->bo_size, 256) + 16;
1441
1442 if ((templ->bind & PIPE_BIND_VERTEX_BUFFER) &&
1443 is->dev.gen < ILO_GEN(7.5)) {
1444 /*
1445 * As noted in ilo_translate_format(), we treat some 3-component formats
1446 * as 4-component formats to work around hardware limitations. Imagine
1447 * the case where the vertex buffer holds a single
1448 * PIPE_FORMAT_R16G16B16_FLOAT vertex, and buf->bo_size is 6. The
1449 * hardware would fail to fetch it at boundary check because the vertex
1450 * buffer is expected to hold a PIPE_FORMAT_R16G16B16A16_FLOAT vertex
1451 * and that takes at least 8 bytes.
1452 *
1453 * For the workaround to work, we should add 2 to the bo size. But that
1454 * would waste a page when the bo size is already page aligned. Let's
1455 * round it to page size for now and revisit this when needed.
1456 */
1457 buf->bo_size = align(buf->bo_size, 4096);
1458 }
1459
1460 if (buf->bo_size < templ->width0 ||
1461 buf->bo_size > max_resource_size ||
1462 !buf_create_bo(buf)) {
1463 FREE(buf);
1464 return NULL;
1465 }
1466
1467 return &buf->base;
1468 }
1469
1470 static boolean
1471 ilo_can_create_resource(struct pipe_screen *screen,
1472 const struct pipe_resource *templ)
1473 {
1474 struct tex_layout layout;
1475
1476 if (templ->target == PIPE_BUFFER)
1477 return (templ->width0 <= max_resource_size);
1478
1479 tex_layout_init(&layout, screen, templ, NULL);
1480
1481 switch (templ->target) {
1482 case PIPE_TEXTURE_3D:
1483 tex_layout_3d(&layout);
1484 break;
1485 default:
1486 tex_layout_2d(&layout);
1487 break;
1488 }
1489
1490 return tex_layout_calculate_bo_size(&layout);
1491 }
1492
1493 static struct pipe_resource *
1494 ilo_resource_create(struct pipe_screen *screen,
1495 const struct pipe_resource *templ)
1496 {
1497 if (templ->target == PIPE_BUFFER)
1498 return buf_create(screen, templ);
1499 else
1500 return tex_create(screen, templ, NULL);
1501 }
1502
1503 static struct pipe_resource *
1504 ilo_resource_from_handle(struct pipe_screen *screen,
1505 const struct pipe_resource *templ,
1506 struct winsys_handle *handle)
1507 {
1508 if (templ->target == PIPE_BUFFER)
1509 return NULL;
1510 else
1511 return tex_create(screen, templ, handle);
1512 }
1513
1514 static boolean
1515 ilo_resource_get_handle(struct pipe_screen *screen,
1516 struct pipe_resource *res,
1517 struct winsys_handle *handle)
1518 {
1519 if (res->target == PIPE_BUFFER)
1520 return false;
1521 else
1522 return tex_get_handle(ilo_texture(res), handle);
1523
1524 }
1525
1526 static void
1527 ilo_resource_destroy(struct pipe_screen *screen,
1528 struct pipe_resource *res)
1529 {
1530 if (res->target == PIPE_BUFFER)
1531 buf_destroy(ilo_buffer(res));
1532 else
1533 tex_destroy(ilo_texture(res));
1534 }
1535
1536 /**
1537 * Initialize resource-related functions.
1538 */
1539 void
1540 ilo_init_resource_functions(struct ilo_screen *is)
1541 {
1542 is->base.can_create_resource = ilo_can_create_resource;
1543 is->base.resource_create = ilo_resource_create;
1544 is->base.resource_from_handle = ilo_resource_from_handle;
1545 is->base.resource_get_handle = ilo_resource_get_handle;
1546 is->base.resource_destroy = ilo_resource_destroy;
1547 }
1548
1549 bool
1550 ilo_buffer_rename_bo(struct ilo_buffer *buf)
1551 {
1552 struct intel_bo *old_bo = buf->bo;
1553
1554 if (buf_create_bo(buf)) {
1555 intel_bo_unreference(old_bo);
1556 return true;
1557 }
1558 else {
1559 buf->bo = old_bo;
1560 return false;
1561 }
1562 }
1563
1564 bool
1565 ilo_texture_rename_bo(struct ilo_texture *tex)
1566 {
1567 struct intel_bo *old_bo = tex->bo;
1568
1569 /* an imported texture cannot be renamed */
1570 if (tex->imported)
1571 return false;
1572
1573 if (tex_create_bo(tex)) {
1574 intel_bo_unreference(old_bo);
1575 return true;
1576 }
1577 else {
1578 tex->bo = old_bo;
1579 return false;
1580 }
1581 }
1582
1583 /**
1584 * Return the offset (in bytes) to a slice within the bo.
1585 *
1586 * The returned offset is aligned to tile size. Since slices are not
1587 * guaranteed to start at tile boundaries, the X and Y offsets (in pixels)
1588 * from the tile origin to the slice are also returned. X offset is always a
1589 * multiple of 4 and Y offset is always a multiple of 2.
1590 */
1591 unsigned
1592 ilo_texture_get_slice_offset(const struct ilo_texture *tex,
1593 unsigned level, unsigned slice,
1594 unsigned *x_offset, unsigned *y_offset)
1595 {
1596 const struct ilo_texture_slice *s =
1597 ilo_texture_get_slice(tex, level, slice);
1598 unsigned tile_w, tile_h, tile_size, row_size;
1599 unsigned x, y, slice_offset;
1600
1601 /* see the Sandy Bridge PRM, volume 1 part 2, page 24 */
1602
1603 switch (tex->tiling) {
1604 case INTEL_TILING_NONE:
1605 /* W-tiled */
1606 if (tex->bo_format == PIPE_FORMAT_S8_UINT) {
1607 tile_w = 64;
1608 tile_h = 64;
1609 }
1610 else {
1611 tile_w = 1;
1612 tile_h = 1;
1613 }
1614 break;
1615 case INTEL_TILING_X:
1616 tile_w = 512;
1617 tile_h = 8;
1618 break;
1619 case INTEL_TILING_Y:
1620 tile_w = 128;
1621 tile_h = 32;
1622 break;
1623 default:
1624 assert(!"unknown tiling");
1625 tile_w = 1;
1626 tile_h = 1;
1627 break;
1628 }
1629
1630 tile_size = tile_w * tile_h;
1631 row_size = tex->bo_stride * tile_h;
1632
1633 /* in bytes */
1634 x = s->x / tex->block_width * tex->block_size;
1635 y = s->y / tex->block_height;
1636 slice_offset = row_size * (y / tile_h) + tile_size * (x / tile_w);
1637
1638 /*
1639 * Since tex->bo_stride is a multiple of tile_w, slice_offset should be
1640 * aligned at this point.
1641 */
1642 assert(slice_offset % tile_size == 0);
1643
1644 /*
1645 * because of the possible values of align_i and align_j in
1646 * tex_layout_init_alignments(), x_offset is guaranteed to be a multiple of
1647 * 4 and y_offset is guaranteed to be a multiple of 2.
1648 */
1649 if (x_offset) {
1650 /* in pixels */
1651 x = (x % tile_w) / tex->block_size * tex->block_width;
1652 assert(x % 4 == 0);
1653
1654 *x_offset = x;
1655 }
1656
1657 if (y_offset) {
1658 /* in pixels */
1659 y = (y % tile_h) * tex->block_height;
1660 assert(y % 2 == 0);
1661
1662 *y_offset = y;
1663 }
1664
1665 return slice_offset;
1666 }