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