2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "ilo_screen.h"
29 #include "ilo_resource.h"
31 /* use PIPE_BIND_CUSTOM to indicate MCS */
32 #define ILO_BIND_MCS PIPE_BIND_CUSTOM
35 const struct ilo_dev_info
*dev
;
36 const struct pipe_resource
*templ
;
38 enum pipe_format format
;
39 unsigned block_width
, block_height
, block_size
;
41 bool has_depth
, has_stencil
, separate_stencil
;
43 enum intel_tiling_mode tiling
;
46 bool array_spacing_full
;
51 struct ilo_texture_slice
*slices
;
52 } levels
[PIPE_MAX_TEXTURE_LEVELS
];
61 tex_layout_init_qpitch(struct tex_layout
*layout
)
63 const struct pipe_resource
*templ
= layout
->templ
;
66 if (templ
->array_size
<= 1)
69 h0
= align(layout
->levels
[0].h
, layout
->align_j
);
71 if (!layout
->array_spacing_full
) {
76 h1
= align(layout
->levels
[1].h
, layout
->align_j
);
79 * From the Sandy Bridge PRM, volume 1 part 1, page 115:
81 * "The following equation is used for surface formats other than
82 * compressed textures:
84 * QPitch = (h0 + h1 + 11j)"
86 * "The equation for compressed textures (BC* and FXT1 surface formats)
89 * QPitch = (h0 + h1 + 11j) / 4"
91 * "[DevSNB] Errata: Sampler MSAA Qpitch will be 4 greater than the
92 * value calculated in the equation above, for every other odd Surface
93 * Height starting from 1 i.e. 1,5,9,13"
95 * From the Ivy Bridge PRM, volume 1 part 1, page 111-112:
97 * "If Surface Array Spacing is set to ARYSPC_FULL (note that the depth
98 * buffer and stencil buffer have an implied value of ARYSPC_FULL):
100 * QPitch = (h0 + h1 + 12j)
101 * QPitch = (h0 + h1 + 12j) / 4 (compressed)
103 * (There are many typos or missing words here...)"
105 * To access the N-th slice, an offset of (Stride * QPitch * N) is added to
106 * the base address. The PRM divides QPitch by 4 for compressed formats
107 * because the block height for those formats are 4, and it wants QPitch to
108 * mean the number of memory rows, as opposed to texel rows, between
109 * slices. Since we use texel rows in tex->slice_offsets, we do not need
110 * to divide QPitch by 4.
112 layout
->qpitch
= h0
+ h1
+
113 ((layout
->dev
->gen
>= ILO_GEN(7)) ? 12 : 11) * layout
->align_j
;
115 if (layout
->dev
->gen
== ILO_GEN(6) && templ
->nr_samples
> 1 &&
116 templ
->height0
% 4 == 1)
121 tex_layout_init_alignments(struct tex_layout
*layout
)
123 const struct pipe_resource
*templ
= layout
->templ
;
126 * From the Sandy Bridge PRM, volume 1 part 1, page 113:
128 * "surface format align_i align_j
129 * YUV 4:2:2 formats 4 *see below
132 * all other formats 4 *see below"
134 * "- align_j = 4 for any depth buffer
135 * - align_j = 2 for separate stencil buffer
136 * - align_j = 4 for any render target surface is multisampled (4x)
137 * - align_j = 4 for any render target surface with Surface Vertical
138 * Alignment = VALIGN_4
139 * - align_j = 2 for any render target surface with Surface Vertical
140 * Alignment = VALIGN_2
141 * - align_j = 2 for all other render target surface
142 * - align_j = 2 for any sampling engine surface with Surface Vertical
143 * Alignment = VALIGN_2
144 * - align_j = 4 for any sampling engine surface with Surface Vertical
145 * Alignment = VALIGN_4"
147 * From the Sandy Bridge PRM, volume 4 part 1, page 86:
149 * "This field (Surface Vertical Alignment) must be set to VALIGN_2 if
150 * the Surface Format is 96 bits per element (BPE)."
152 * They can be rephrased as
155 * compressed formats block width block height
156 * PIPE_FORMAT_S8_UINT 4 2
157 * other depth/stencil formats 4 4
158 * 4x multisampled 4 4
164 * From the Ivy Bridge PRM, volume 1 part 1, page 110:
166 * "surface defined by surface format align_i align_j
167 * 3DSTATE_DEPTH_BUFFER D16_UNORM 8 4
169 * 3DSTATE_STENCIL_BUFFER N/A 8 8
170 * SURFACE_STATE BC*, ETC*, EAC* 4 4
172 * all others (set by SURFACE_STATE)"
174 * From the Ivy Bridge PRM, volume 4 part 1, page 63:
176 * "- This field (Surface Vertical Aligment) is intended to be set to
177 * VALIGN_4 if the surface was rendered as a depth buffer, for a
178 * multisampled (4x) render target, or for a multisampled (8x)
179 * render target, since these surfaces support only alignment of 4.
180 * - Use of VALIGN_4 for other surfaces is supported, but uses more
182 * - This field must be set to VALIGN_4 for all tiled Y Render Target
184 * - Value of 1 is not supported for format YCRCB_NORMAL (0x182),
185 * YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY (0x190)
186 * - If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
187 * must be set to VALIGN_4."
188 * - VALIGN_4 is not supported for surface format R32G32B32_FLOAT."
190 * "- This field (Surface Horizontal Aligment) is intended to be set to
191 * HALIGN_8 only if the surface was rendered as a depth buffer with
192 * Z16 format or a stencil buffer, since these surfaces support only
194 * - Use of HALIGN_8 for other surfaces is supported, but uses more
196 * - This field must be set to HALIGN_4 if the Surface Format is BC*.
197 * - This field must be set to HALIGN_8 if the Surface Format is
200 * They can be rephrased as
203 * compressed formats block width block height
204 * PIPE_FORMAT_Z16_UNORM 8 4
205 * PIPE_FORMAT_S8_UINT 8 8
206 * other depth/stencil formats 4 or 8 4
207 * 2x or 4x multisampled 4 or 8 4
208 * tiled Y 4 or 8 4 (if rt)
209 * PIPE_FORMAT_R32G32B32_FLOAT 4 or 8 2
210 * others 4 or 8 2 or 4
213 if (layout
->compressed
) {
214 /* this happens to be the case */
215 layout
->align_i
= layout
->block_width
;
216 layout
->align_j
= layout
->block_height
;
218 else if (layout
->has_depth
|| layout
->has_stencil
) {
219 if (layout
->dev
->gen
>= ILO_GEN(7)) {
220 switch (layout
->format
) {
221 case PIPE_FORMAT_Z16_UNORM
:
225 case PIPE_FORMAT_S8_UINT
:
231 * From the Ivy Bridge PRM, volume 2 part 1, page 319:
233 * "The 3 LSBs of both offsets (Depth Coordinate Offset Y and
234 * Depth Coordinate Offset X) must be zero to ensure correct
237 * We will make use of them and setting align_i to 8 help us meet
240 layout
->align_i
= (templ
->last_level
> 0) ? 8 : 4;
246 switch (layout
->format
) {
247 case PIPE_FORMAT_S8_UINT
:
259 const bool valign_4
= (templ
->nr_samples
> 1) ||
260 (layout
->dev
->gen
>= ILO_GEN(7) &&
261 layout
->tiling
== INTEL_TILING_Y
&&
262 (templ
->bind
& PIPE_BIND_RENDER_TARGET
));
265 assert(layout
->block_size
!= 12);
268 layout
->align_j
= (valign_4
) ? 4 : 2;
272 * the fact that align i and j are multiples of block width and height
273 * respectively is what makes the size of the bo a multiple of the block
274 * size, slices start at block boundaries, and many of the computations
277 assert(layout
->align_i
% layout
->block_width
== 0);
278 assert(layout
->align_j
% layout
->block_height
== 0);
280 /* make sure align() works */
281 assert(util_is_power_of_two(layout
->align_i
) &&
282 util_is_power_of_two(layout
->align_j
));
283 assert(util_is_power_of_two(layout
->block_width
) &&
284 util_is_power_of_two(layout
->block_height
));
288 tex_layout_init_levels(struct tex_layout
*layout
)
290 const struct pipe_resource
*templ
= layout
->templ
;
293 last_level
= templ
->last_level
;
295 /* need at least 2 levels to compute full qpitch */
296 if (last_level
== 0 && templ
->array_size
> 1 && layout
->array_spacing_full
)
299 /* compute mip level sizes */
300 for (lv
= 0; lv
<= last_level
; lv
++) {
303 w
= u_minify(templ
->width0
, lv
);
304 h
= u_minify(templ
->height0
, lv
);
305 d
= u_minify(templ
->depth0
, lv
);
308 * From the Sandy Bridge PRM, volume 1 part 1, page 114:
310 * "The dimensions of the mip maps are first determined by applying
311 * the sizing algorithm presented in Non-Power-of-Two Mipmaps
312 * above. Then, if necessary, they are padded out to compression
315 w
= align(w
, layout
->block_width
);
316 h
= align(h
, layout
->block_height
);
319 * From the Sandy Bridge PRM, volume 1 part 1, page 111:
321 * "If the surface is multisampled (4x), these values must be
322 * adjusted as follows before proceeding:
324 * W_L = ceiling(W_L / 2) * 4
325 * H_L = ceiling(H_L / 2) * 4"
327 * From the Ivy Bridge PRM, volume 1 part 1, page 108:
329 * "If the surface is multisampled and it is a depth or stencil
330 * surface or Multisampled Surface StorageFormat in SURFACE_STATE
331 * is MSFMT_DEPTH_STENCIL, W_L and H_L must be adjusted as follows
334 * #samples W_L = H_L =
335 * 2 ceiling(W_L / 2) * 4 HL [no adjustment]
336 * 4 ceiling(W_L / 2) * 4 ceiling(H_L / 2) * 4
337 * 8 ceiling(W_L / 2) * 8 ceiling(H_L / 2) * 4
338 * 16 ceiling(W_L / 2) * 8 ceiling(H_L / 2) * 8"
340 * For interleaved samples (4x), where pixels
343 * (x, y+1) (x+1, y+1)
345 * would be is occupied by
347 * (x, y , si0) (x+1, y , si0) (x, y , si1) (x+1, y , si1)
348 * (x, y+1, si0) (x+1, y+1, si0) (x, y+1, si1) (x+1, y+1, si1)
349 * (x, y , si2) (x+1, y , si2) (x, y , si3) (x+1, y , si3)
350 * (x, y+1, si2) (x+1, y+1, si2) (x, y+1, si3) (x+1, y+1, si3)
354 * w = align(w, 2) * 2;
355 * y = align(y, 2) * 2;
357 if (layout
->interleaved
) {
358 switch (templ
->nr_samples
) {
378 assert(!"unsupported sample count");
383 layout
->levels
[lv
].w
= w
;
384 layout
->levels
[lv
].h
= h
;
385 layout
->levels
[lv
].d
= d
;
390 tex_layout_init_spacing(struct tex_layout
*layout
)
392 const struct pipe_resource
*templ
= layout
->templ
;
394 if (layout
->dev
->gen
>= ILO_GEN(7)) {
396 * It is not explicitly states, but render targets are expected to be
397 * UMS/CMS (samples non-interleaved) and depth/stencil buffers are
398 * expected to be IMS (samples interleaved).
400 * See "Multisampled Surface Storage Format" field of SURFACE_STATE.
402 if (layout
->has_depth
|| layout
->has_stencil
) {
403 layout
->interleaved
= true;
406 * From the Ivy Bridge PRM, volume 1 part 1, page 111:
408 * "note that the depth buffer and stencil buffer have an implied
409 * value of ARYSPC_FULL"
411 layout
->array_spacing_full
= true;
414 layout
->interleaved
= false;
417 * From the Ivy Bridge PRM, volume 4 part 1, page 66:
419 * "If Multisampled Surface Storage Format is MSFMT_MSS and
420 * Number of Multisamples is not MULTISAMPLECOUNT_1, this field
421 * (Surface Array Spacing) must be set to ARYSPC_LOD0."
423 * As multisampled resources are not mipmapped, we never use
424 * ARYSPC_FULL for them.
426 if (templ
->nr_samples
> 1)
427 assert(templ
->last_level
== 0);
428 layout
->array_spacing_full
= (templ
->last_level
> 0);
432 /* GEN6 supports only interleaved samples */
433 layout
->interleaved
= true;
436 * From the Sandy Bridge PRM, volume 1 part 1, page 115:
438 * "The separate stencil buffer does not support mip mapping, thus
439 * the storage for LODs other than LOD 0 is not needed. The
440 * following QPitch equation applies only to the separate stencil
445 * GEN6 does not support compact spacing otherwise.
447 layout
->array_spacing_full
= (layout
->format
!= PIPE_FORMAT_S8_UINT
);
452 tex_layout_init_tiling(struct tex_layout
*layout
)
454 const struct pipe_resource
*templ
= layout
->templ
;
455 const enum pipe_format format
= layout
->format
;
456 const unsigned tile_none
= 1 << INTEL_TILING_NONE
;
457 const unsigned tile_x
= 1 << INTEL_TILING_X
;
458 const unsigned tile_y
= 1 << INTEL_TILING_Y
;
459 unsigned valid_tilings
= tile_none
| tile_x
| tile_y
;
462 * From the Sandy Bridge PRM, volume 1 part 2, page 32:
464 * "Display/Overlay Y-Major not supported.
465 * X-Major required for Async Flips"
467 if (unlikely(templ
->bind
& PIPE_BIND_SCANOUT
))
468 valid_tilings
&= tile_x
;
471 * From the Sandy Bridge PRM, volume 3 part 2, page 158:
473 * "The cursor surface address must be 4K byte aligned. The cursor must
474 * be in linear memory, it cannot be tiled."
476 if (unlikely(templ
->bind
& PIPE_BIND_CURSOR
))
477 valid_tilings
&= tile_none
;
480 * From the Ivy Bridge PRM, volume 4 part 1, page 76:
482 * "The MCS surface must be stored as Tile Y."
484 if (templ
->bind
& ILO_BIND_MCS
)
485 valid_tilings
&= tile_y
;
488 * From the Sandy Bridge PRM, volume 2 part 1, page 318:
490 * "[DevSNB+]: This field (Tiled Surface) must be set to TRUE. Linear
491 * Depth Buffer is not supported."
493 * "The Depth Buffer, if tiled, must use Y-Major tiling."
495 * From the Sandy Bridge PRM, volume 1 part 2, page 22:
497 * "W-Major Tile Format is used for separate stencil."
499 * Since the HW does not support W-tiled fencing, we have to do it in the
502 if (templ
->bind
& PIPE_BIND_DEPTH_STENCIL
) {
504 case PIPE_FORMAT_S8_UINT
:
505 valid_tilings
&= tile_none
;
508 valid_tilings
&= tile_y
;
513 if (templ
->bind
& (PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
)) {
514 if (templ
->bind
& PIPE_BIND_RENDER_TARGET
) {
516 * From the Sandy Bridge PRM, volume 1 part 2, page 32:
518 * "NOTE: 128BPE Format Color buffer ( render target ) MUST be
519 * either TileX or Linear."
521 if (layout
->block_size
== 16)
522 valid_tilings
&= ~tile_y
;
525 * From the Ivy Bridge PRM, volume 4 part 1, page 63:
527 * "This field (Surface Vertical Aligment) must be set to
528 * VALIGN_4 for all tiled Y Render Target surfaces."
530 * "VALIGN_4 is not supported for surface format
533 if (layout
->dev
->gen
>= ILO_GEN(7) && layout
->block_size
== 12)
534 valid_tilings
&= ~tile_y
;
538 * Also, heuristically set a minimum width/height for enabling tiling.
540 if (templ
->width0
< 64 && (valid_tilings
& ~tile_x
))
541 valid_tilings
&= ~tile_x
;
543 if ((templ
->width0
< 32 || templ
->height0
< 16) &&
544 (templ
->width0
< 16 || templ
->height0
< 32) &&
545 (valid_tilings
& ~tile_y
))
546 valid_tilings
&= ~tile_y
;
549 /* force linear if we are not sure where the texture is bound to */
550 if (valid_tilings
& tile_none
)
551 valid_tilings
&= tile_none
;
554 /* no conflicting binding flags */
555 assert(valid_tilings
);
557 /* prefer tiled than linear */
558 if (valid_tilings
& tile_y
)
559 layout
->tiling
= INTEL_TILING_Y
;
560 else if (valid_tilings
& tile_x
)
561 layout
->tiling
= INTEL_TILING_X
;
563 layout
->tiling
= INTEL_TILING_NONE
;
565 layout
->can_be_linear
= valid_tilings
& tile_none
;
569 tex_layout_init_format(struct tex_layout
*layout
)
571 const struct pipe_resource
*templ
= layout
->templ
;
572 enum pipe_format format
;
573 const struct util_format_description
*desc
;
574 bool separate_stencil
;
576 /* GEN7+ requires separate stencil buffers */
577 separate_stencil
= (layout
->dev
->gen
>= ILO_GEN(7));
579 switch (templ
->format
) {
580 case PIPE_FORMAT_ETC1_RGB8
:
581 format
= PIPE_FORMAT_R8G8B8X8_UNORM
;
583 case PIPE_FORMAT_Z24_UNORM_S8_UINT
:
584 if (separate_stencil
) {
585 format
= PIPE_FORMAT_Z24X8_UNORM
;
586 layout
->separate_stencil
= true;
589 format
= templ
->format
;
592 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
:
593 if (separate_stencil
) {
594 format
= PIPE_FORMAT_Z32_FLOAT
;
595 layout
->separate_stencil
= true;
598 format
= templ
->format
;
602 format
= templ
->format
;
606 layout
->format
= format
;
608 layout
->block_width
= util_format_get_blockwidth(format
);
609 layout
->block_height
= util_format_get_blockheight(format
);
610 layout
->block_size
= util_format_get_blocksize(format
);
611 layout
->compressed
= util_format_is_compressed(format
);
613 desc
= util_format_description(format
);
614 layout
->has_depth
= util_format_has_depth(desc
);
615 layout
->has_stencil
= util_format_has_stencil(desc
);
619 tex_layout_init(struct tex_layout
*layout
,
620 struct pipe_screen
*screen
,
621 const struct pipe_resource
*templ
,
622 struct ilo_texture_slice
**slices
)
624 struct ilo_screen
*is
= ilo_screen(screen
);
626 memset(layout
, 0, sizeof(*layout
));
628 layout
->dev
= &is
->dev
;
629 layout
->templ
= templ
;
631 /* note that there are dependencies between these functions */
632 tex_layout_init_format(layout
);
633 tex_layout_init_tiling(layout
);
634 tex_layout_init_spacing(layout
);
635 tex_layout_init_levels(layout
);
636 tex_layout_init_alignments(layout
);
637 tex_layout_init_qpitch(layout
);
642 for (lv
= 0; lv
<= templ
->last_level
; lv
++)
643 layout
->levels
[lv
].slices
= slices
[lv
];
648 tex_layout_force_linear(struct tex_layout
*layout
)
650 if (!layout
->can_be_linear
)
654 * we may be able to switch from VALIGN_4 to VALIGN_2 when the layout was
655 * Y-tiled, but let's keep it simple
657 layout
->tiling
= INTEL_TILING_NONE
;
663 * Layout a 2D texture.
666 tex_layout_2d(struct tex_layout
*layout
)
668 const struct pipe_resource
*templ
= layout
->templ
;
669 unsigned int level_x
, level_y
, num_slices
;
674 for (lv
= 0; lv
<= templ
->last_level
; lv
++) {
675 const unsigned int level_w
= layout
->levels
[lv
].w
;
676 const unsigned int level_h
= layout
->levels
[lv
].h
;
679 /* set slice offsets */
680 if (layout
->levels
[lv
].slices
) {
681 for (slice
= 0; slice
< templ
->array_size
; slice
++) {
682 layout
->levels
[lv
].slices
[slice
].x
= level_x
;
683 /* slices are qpitch apart in Y-direction */
684 layout
->levels
[lv
].slices
[slice
].y
=
685 level_y
+ layout
->qpitch
* slice
;
689 /* extend the size of the monolithic bo to cover this mip level */
690 if (layout
->width
< level_x
+ level_w
)
691 layout
->width
= level_x
+ level_w
;
692 if (layout
->height
< level_y
+ level_h
)
693 layout
->height
= level_y
+ level_h
;
695 /* MIPLAYOUT_BELOW */
697 level_x
+= align(level_w
, layout
->align_i
);
699 level_y
+= align(level_h
, layout
->align_j
);
702 num_slices
= templ
->array_size
;
703 /* samples of the same index are stored in a slice */
704 if (templ
->nr_samples
> 1 && !layout
->interleaved
)
705 num_slices
*= templ
->nr_samples
;
707 /* we did not take slices into consideration in the computation above */
708 layout
->height
+= layout
->qpitch
* (num_slices
- 1);
712 * Layout a 3D texture.
715 tex_layout_3d(struct tex_layout
*layout
)
717 const struct pipe_resource
*templ
= layout
->templ
;
718 unsigned int level_y
;
722 for (lv
= 0; lv
<= templ
->last_level
; lv
++) {
723 const unsigned int level_w
= layout
->levels
[lv
].w
;
724 const unsigned int level_h
= layout
->levels
[lv
].h
;
725 const unsigned int level_d
= layout
->levels
[lv
].d
;
726 const unsigned int slice_pitch
= align(level_w
, layout
->align_i
);
727 const unsigned int slice_qpitch
= align(level_h
, layout
->align_j
);
728 const unsigned int num_slices_per_row
= 1 << lv
;
731 for (slice
= 0; slice
< level_d
; slice
+= num_slices_per_row
) {
734 /* set slice offsets */
735 if (layout
->levels
[lv
].slices
) {
736 for (i
= 0; i
< num_slices_per_row
&& slice
+ i
< level_d
; i
++) {
737 layout
->levels
[lv
].slices
[slice
+ i
].x
= slice_pitch
* i
;
738 layout
->levels
[lv
].slices
[slice
+ i
].y
= level_y
;
742 /* move on to the next slice row */
743 level_y
+= slice_qpitch
;
746 /* rightmost slice */
747 slice
= MIN2(num_slices_per_row
, level_d
) - 1;
749 /* extend the size of the monolithic bo to cover this slice */
750 if (layout
->width
< slice_pitch
* slice
+ level_w
)
751 layout
->width
= slice_pitch
* slice
+ level_w
;
752 if (lv
== templ
->last_level
)
753 layout
->height
= (level_y
- slice_qpitch
) + level_h
;
758 tex_layout_validate(struct tex_layout
*layout
)
761 * From the Sandy Bridge PRM, volume 1 part 2, page 22:
763 * "A 4KB tile is subdivided into 8-high by 8-wide array of Blocks for
764 * W-Major Tiles (W Tiles). Each Block is 8 rows by 8 bytes."
766 * Since we ask for INTEL_TILING_NONE instead of the non-existent
767 * INTEL_TILING_W, we need to manually align the width and height to the
770 if (layout
->templ
->format
== PIPE_FORMAT_S8_UINT
) {
771 layout
->width
= align(layout
->width
, 64);
772 layout
->height
= align(layout
->height
, 64);
775 assert(layout
->width
% layout
->block_width
== 0);
776 assert(layout
->height
% layout
->block_height
== 0);
777 assert(layout
->qpitch
% layout
->block_height
== 0);
781 tex_layout_estimate_size(const struct tex_layout
*layout
)
783 unsigned stride
, height
;
785 stride
= (layout
->width
/ layout
->block_width
) * layout
->block_size
;
786 height
= layout
->height
/ layout
->block_height
;
788 switch (layout
->tiling
) {
790 stride
= align(stride
, 512);
791 height
= align(height
, 8);
794 stride
= align(stride
, 128);
795 height
= align(height
, 32);
798 height
= align(height
, 2);
802 return stride
* height
;
806 tex_layout_apply(const struct tex_layout
*layout
, struct ilo_texture
*tex
)
808 tex
->bo_format
= layout
->format
;
811 tex
->bo_width
= layout
->width
/ layout
->block_width
;
812 tex
->bo_height
= layout
->height
/ layout
->block_height
;
813 tex
->bo_cpp
= layout
->block_size
;
814 tex
->tiling
= layout
->tiling
;
816 tex
->compressed
= layout
->compressed
;
817 tex
->block_width
= layout
->block_width
;
818 tex
->block_height
= layout
->block_height
;
820 tex
->halign_8
= (layout
->align_i
== 8);
821 tex
->valign_4
= (layout
->align_j
== 4);
822 tex
->array_spacing_full
= layout
->array_spacing_full
;
823 tex
->interleaved
= layout
->interleaved
;
827 tex_free_slices(struct ilo_texture
*tex
)
829 FREE(tex
->slice_offsets
[0]);
833 tex_alloc_slices(struct ilo_texture
*tex
)
835 const struct pipe_resource
*templ
= &tex
->base
;
836 struct ilo_texture_slice
*slices
;
839 /* sum the depths of all levels */
841 for (lv
= 0; lv
<= templ
->last_level
; lv
++)
842 depth
+= u_minify(templ
->depth0
, lv
);
845 * There are (depth * tex->base.array_size) slices in total. Either depth
846 * is one (non-3D) or templ->array_size is one (non-array), but it does
849 slices
= CALLOC(depth
* templ
->array_size
, sizeof(*slices
));
853 tex
->slice_offsets
[0] = slices
;
855 /* point to the respective positions in the buffer */
856 for (lv
= 1; lv
<= templ
->last_level
; lv
++) {
857 tex
->slice_offsets
[lv
] = tex
->slice_offsets
[lv
- 1] +
858 u_minify(templ
->depth0
, lv
- 1) * templ
->array_size
;
864 static struct intel_bo
*
865 tex_create_bo(const struct ilo_texture
*tex
,
866 const struct winsys_handle
*handle
)
868 struct ilo_screen
*is
= ilo_screen(tex
->base
.screen
);
872 switch (tex
->base
.target
) {
873 case PIPE_TEXTURE_1D
:
876 case PIPE_TEXTURE_2D
:
879 case PIPE_TEXTURE_3D
:
882 case PIPE_TEXTURE_CUBE
:
883 name
= "cube texture";
885 case PIPE_TEXTURE_RECT
:
886 name
= "rectangle texture";
888 case PIPE_TEXTURE_1D_ARRAY
:
889 name
= "1D array texture";
891 case PIPE_TEXTURE_2D_ARRAY
:
892 name
= "2D array texture";
894 case PIPE_TEXTURE_CUBE_ARRAY
:
895 name
= "cube array texture";
898 name
="unknown texture";
903 bo
= is
->winsys
->import_handle(is
->winsys
, name
,
904 tex
->bo_width
, tex
->bo_height
, tex
->bo_cpp
, handle
);
907 bo
= is
->winsys
->alloc(is
->winsys
, name
,
908 tex
->bo_width
, tex
->bo_height
, tex
->bo_cpp
,
909 tex
->tiling
, tex
->bo_flags
);
916 tex_set_bo(struct ilo_texture
*tex
, struct intel_bo
*bo
)
919 tex
->bo
->unreference(tex
->bo
);
923 /* winsys may decide to use a different tiling */
924 tex
->tiling
= tex
->bo
->get_tiling(tex
->bo
);
925 tex
->bo_stride
= tex
->bo
->get_pitch(tex
->bo
);
929 tex_destroy(struct ilo_texture
*tex
)
931 if (tex
->separate_s8
)
932 tex_destroy(tex
->separate_s8
);
934 tex
->bo
->unreference(tex
->bo
);
935 tex_free_slices(tex
);
939 static struct pipe_resource
*
940 tex_create(struct pipe_screen
*screen
,
941 const struct pipe_resource
*templ
,
942 const struct winsys_handle
*handle
)
944 struct tex_layout layout
;
945 struct ilo_texture
*tex
;
948 tex
= CALLOC_STRUCT(ilo_texture
);
953 tex
->base
.screen
= screen
;
954 pipe_reference_init(&tex
->base
.reference
, 1);
956 if (!tex_alloc_slices(tex
)) {
961 tex
->imported
= (handle
!= NULL
);
963 if (tex
->base
.bind
& (PIPE_BIND_DEPTH_STENCIL
|
964 PIPE_BIND_RENDER_TARGET
))
965 tex
->bo_flags
|= INTEL_ALLOC_FOR_RENDER
;
967 tex_layout_init(&layout
, screen
, templ
, tex
->slice_offsets
);
969 switch (templ
->target
) {
970 case PIPE_TEXTURE_1D
:
971 case PIPE_TEXTURE_2D
:
972 case PIPE_TEXTURE_CUBE
:
973 case PIPE_TEXTURE_RECT
:
974 case PIPE_TEXTURE_1D_ARRAY
:
975 case PIPE_TEXTURE_2D_ARRAY
:
976 case PIPE_TEXTURE_CUBE_ARRAY
:
977 tex_layout_2d(&layout
);
979 case PIPE_TEXTURE_3D
:
980 tex_layout_3d(&layout
);
983 assert(!"unknown resource target");
987 tex_layout_validate(&layout
);
989 /* make sure the bo can be mapped through GTT if tiled */
990 if (layout
.tiling
!= INTEL_TILING_NONE
) {
992 * Usually only the first 256MB of the GTT is mappable.
994 * See also how intel_context::max_gtt_map_object_size is calculated.
996 const size_t mappable_gtt_size
= 256 * 1024 * 1024;
997 const size_t size
= tex_layout_estimate_size(&layout
);
999 /* be conservative */
1000 if (size
> mappable_gtt_size
/ 4)
1001 tex_layout_force_linear(&layout
);
1004 tex_layout_apply(&layout
, tex
);
1006 bo
= tex_create_bo(tex
, handle
);
1008 tex_free_slices(tex
);
1013 tex_set_bo(tex
, bo
);
1015 /* allocate separate stencil resource */
1016 if (layout
.separate_stencil
) {
1017 struct pipe_resource s8_templ
= *layout
.templ
;
1018 struct pipe_resource
*s8
;
1021 * Unless PIPE_BIND_DEPTH_STENCIL is set, the resource may have other
1022 * tilings. But that should be fine since it will never be bound as the
1023 * stencil buffer, and our transfer code can handle all tilings.
1025 s8_templ
.format
= PIPE_FORMAT_S8_UINT
;
1027 s8
= screen
->resource_create(screen
, &s8_templ
);
1033 tex
->separate_s8
= ilo_texture(s8
);
1035 assert(tex
->separate_s8
->bo_format
== PIPE_FORMAT_S8_UINT
);
1042 tex_get_handle(struct ilo_texture
*tex
, struct winsys_handle
*handle
)
1046 err
= tex
->bo
->export_handle(tex
->bo
, handle
);
1052 * Estimate the texture size. For large textures, the errors should be pretty
1056 tex_estimate_size(struct pipe_screen
*screen
,
1057 const struct pipe_resource
*templ
)
1059 struct tex_layout layout
;
1061 tex_layout_init(&layout
, screen
, templ
, NULL
);
1063 switch (templ
->target
) {
1064 case PIPE_TEXTURE_3D
:
1065 tex_layout_3d(&layout
);
1068 tex_layout_2d(&layout
);
1072 tex_layout_validate(&layout
);
1074 return tex_layout_estimate_size(&layout
);
1077 static struct intel_bo
*
1078 buf_create_bo(const struct ilo_buffer
*buf
)
1080 struct ilo_screen
*is
= ilo_screen(buf
->base
.screen
);
1083 switch (buf
->base
.bind
) {
1084 case PIPE_BIND_VERTEX_BUFFER
:
1085 name
= "vertex buffer";
1087 case PIPE_BIND_INDEX_BUFFER
:
1088 name
= "index buffer";
1090 case PIPE_BIND_CONSTANT_BUFFER
:
1091 name
= "constant buffer";
1093 case PIPE_BIND_STREAM_OUTPUT
:
1094 name
= "stream output";
1097 name
= "unknown buffer";
1101 return is
->winsys
->alloc_buffer(is
->winsys
,
1102 name
, buf
->bo_size
, buf
->bo_flags
);
1106 buf_set_bo(struct ilo_buffer
*buf
, struct intel_bo
*bo
)
1109 buf
->bo
->unreference(buf
->bo
);
1115 buf_destroy(struct ilo_buffer
*buf
)
1117 buf
->bo
->unreference(buf
->bo
);
1121 static struct pipe_resource
*
1122 buf_create(struct pipe_screen
*screen
, const struct pipe_resource
*templ
)
1124 struct ilo_buffer
*buf
;
1125 struct intel_bo
*bo
;
1127 buf
= CALLOC_STRUCT(ilo_buffer
);
1132 buf
->base
.screen
= screen
;
1133 pipe_reference_init(&buf
->base
.reference
, 1);
1135 buf
->bo_size
= templ
->width0
;
1138 bo
= buf_create_bo(buf
);
1144 buf_set_bo(buf
, bo
);
1150 ilo_can_create_resource(struct pipe_screen
*screen
,
1151 const struct pipe_resource
*templ
)
1154 * We do not know if we will fail until we try to allocate the bo.
1155 * So just set a limit on the texture size.
1157 const size_t max_size
= 1 * 1024 * 1024 * 1024;
1160 if (templ
->target
== PIPE_BUFFER
)
1161 size
= templ
->width0
;
1163 size
= tex_estimate_size(screen
, templ
);
1165 return (size
<= max_size
);
1168 static struct pipe_resource
*
1169 ilo_resource_create(struct pipe_screen
*screen
,
1170 const struct pipe_resource
*templ
)
1172 if (templ
->target
== PIPE_BUFFER
)
1173 return buf_create(screen
, templ
);
1175 return tex_create(screen
, templ
, NULL
);
1178 static struct pipe_resource
*
1179 ilo_resource_from_handle(struct pipe_screen
*screen
,
1180 const struct pipe_resource
*templ
,
1181 struct winsys_handle
*handle
)
1183 if (templ
->target
== PIPE_BUFFER
)
1186 return tex_create(screen
, templ
, handle
);
1190 ilo_resource_get_handle(struct pipe_screen
*screen
,
1191 struct pipe_resource
*res
,
1192 struct winsys_handle
*handle
)
1194 if (res
->target
== PIPE_BUFFER
)
1197 return tex_get_handle(ilo_texture(res
), handle
);
1202 ilo_resource_destroy(struct pipe_screen
*screen
,
1203 struct pipe_resource
*res
)
1205 if (res
->target
== PIPE_BUFFER
)
1206 buf_destroy(ilo_buffer(res
));
1208 tex_destroy(ilo_texture(res
));
1212 * Initialize resource-related functions.
1215 ilo_init_resource_functions(struct ilo_screen
*is
)
1217 is
->base
.can_create_resource
= ilo_can_create_resource
;
1218 is
->base
.resource_create
= ilo_resource_create
;
1219 is
->base
.resource_from_handle
= ilo_resource_from_handle
;
1220 is
->base
.resource_get_handle
= ilo_resource_get_handle
;
1221 is
->base
.resource_destroy
= ilo_resource_destroy
;
1225 ilo_buffer_alloc_bo(struct ilo_buffer
*buf
)
1227 struct intel_bo
*bo
;
1229 bo
= buf_create_bo(buf
);
1233 buf_set_bo(buf
, bo
);
1239 ilo_texture_alloc_bo(struct ilo_texture
*tex
)
1241 struct intel_bo
*bo
;
1243 /* a shared bo cannot be reallocated */
1247 bo
= tex_create_bo(tex
, NULL
);
1251 tex_set_bo(tex
, bo
);
1257 * Return the offset (in bytes) to a slice within the bo.
1259 * The returned offset is aligned to tile size. Since slices are not
1260 * guaranteed to start at tile boundaries, the X and Y offsets (in pixels)
1261 * from the tile origin to the slice are also returned. X offset is always a
1262 * multiple of 4 and Y offset is always a multiple of 2.
1265 ilo_texture_get_slice_offset(const struct ilo_texture
*tex
,
1266 int level
, int slice
,
1267 unsigned *x_offset
, unsigned *y_offset
)
1269 unsigned tile_w
, tile_h
, tile_size
, row_size
;
1270 unsigned x
, y
, slice_offset
;
1272 /* see the Sandy Bridge PRM, volume 1 part 2, page 24 */
1274 switch (tex
->tiling
) {
1275 case INTEL_TILING_NONE
:
1277 if (tex
->bo_format
== PIPE_FORMAT_S8_UINT
) {
1286 case INTEL_TILING_X
:
1290 case INTEL_TILING_Y
:
1295 assert(!"unknown tiling");
1301 tile_size
= tile_w
* tile_h
;
1302 row_size
= tex
->bo_stride
* tile_h
;
1305 x
= tex
->slice_offsets
[level
][slice
].x
/ tex
->block_width
* tex
->bo_cpp
;
1306 y
= tex
->slice_offsets
[level
][slice
].y
/ tex
->block_height
;
1307 slice_offset
= row_size
* (y
/ tile_h
) + tile_size
* (x
/ tile_w
);
1310 * Since tex->bo_stride is a multiple of tile_w, slice_offset should be
1311 * aligned at this point.
1313 assert(slice_offset
% tile_size
== 0);
1316 * because of the possible values of align_i and align_j in
1317 * tex_layout_init_alignments(), x_offset is guaranteed to be a multiple of
1318 * 4 and y_offset is guaranteed to be a multiple of 2.
1322 x
= (x
% tile_w
) / tex
->bo_cpp
* tex
->block_width
;
1330 y
= (y
% tile_h
) * tex
->block_height
;
1336 return slice_offset
;