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