2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2015 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_debug.h"
29 #include "ilo_image.h"
31 #include "ilo_state_zs.h"
34 zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs
*zs
,
35 const struct ilo_dev
*dev
)
37 const enum gen_depth_format format
= GEN6_ZFORMAT_D32_FLOAT
;
40 ILO_DEV_ASSERT(dev
, 6, 8);
42 if (ilo_dev_gen(dev
) >= ILO_GEN(7)) {
43 dw1
= GEN6_SURFTYPE_NULL
<< GEN7_DEPTH_DW1_TYPE__SHIFT
|
44 format
<< GEN7_DEPTH_DW1_FORMAT__SHIFT
;
46 dw1
= GEN6_SURFTYPE_NULL
<< GEN6_DEPTH_DW1_TYPE__SHIFT
|
47 GEN6_TILING_Y
<< GEN6_DEPTH_DW1_TILING__SHIFT
|
48 format
<< GEN6_DEPTH_DW1_FORMAT__SHIFT
;
51 STATIC_ASSERT(ARRAY_SIZE(zs
->depth
) >= 5);
62 zs_validate_gen6(const struct ilo_dev
*dev
,
63 const struct ilo_state_zs_info
*info
)
65 const struct ilo_image
*img
= (info
->z_img
) ? info
->z_img
: info
->s_img
;
67 ILO_DEV_ASSERT(dev
, 6, 8);
69 assert(!info
->z_img
== !info
->z_vma
);
70 assert(!info
->s_img
== !info
->s_vma
);
74 assert(info
->z_img
->tiling
== GEN6_TILING_Y
);
75 assert(info
->z_vma
->vm_alignment
% 4096 == 0);
78 assert(info
->s_img
->tiling
== GEN8_TILING_W
);
79 assert(info
->s_vma
->vm_alignment
% 4096 == 0);
83 ilo_image_can_enable_aux(info
->z_img
, info
->level
));
84 assert(info
->z_vma
->vm_alignment
% 4096 == 0);
88 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
90 * "The stencil buffer has a format of S8_UINT, and shares Surface
91 * Type, Height, Width, and Depth, Minimum Array Element, Render
92 * Target View Extent, Depth Coordinate Offset X/Y, LOD, and Depth
93 * Buffer Object Control State fields of the depth buffer."
95 if (info
->z_img
&& info
->s_img
&& info
->z_img
!= info
->s_img
) {
96 assert(info
->z_img
->type
== info
->s_img
->type
&&
97 info
->z_img
->height0
== info
->s_img
->height0
&&
98 info
->z_img
->depth0
== info
->s_img
->depth0
);
101 if (info
->type
!= img
->type
) {
102 assert(info
->type
== GEN6_SURFTYPE_2D
&&
103 img
->type
== GEN6_SURFTYPE_CUBE
);
106 if (ilo_dev_gen(dev
) >= ILO_GEN(7)) {
107 switch (info
->format
) {
108 case GEN6_ZFORMAT_D32_FLOAT
:
109 case GEN6_ZFORMAT_D24_UNORM_X8_UINT
:
110 case GEN6_ZFORMAT_D16_UNORM
:
113 assert(!"unknown depth format");
118 * From the Ironlake PRM, volume 2 part 1, page 330:
120 * "If this field (Separate Stencil Buffer Enable) is disabled, the
121 * Surface Format of the depth buffer cannot be D24_UNORM_X8_UINT."
123 * From the Sandy Bridge PRM, volume 2 part 1, page 321:
125 * "[DevSNB]: This field (Separate Stencil Buffer Enable) must be
126 * set to the same value (enabled or disabled) as Hierarchical
127 * Depth Buffer Enable."
130 assert(info
->format
!= GEN6_ZFORMAT_D24_UNORM_S8_UINT
);
132 assert(info
->format
!= GEN6_ZFORMAT_D24_UNORM_X8_UINT
);
135 assert(info
->level
< img
->level_count
);
136 assert(img
->bo_stride
);
139 * From the Sandy Bridge PRM, volume 2 part 1, page 323:
141 * "For cube maps, Width must be set equal to Height."
143 if (info
->type
== GEN6_SURFTYPE_CUBE
)
144 assert(img
->width0
== img
->height0
);
150 zs_get_gen6_max_extent(const struct ilo_dev
*dev
,
151 const struct ilo_state_zs_info
*info
,
152 uint16_t *max_w
, uint16_t *max_h
)
154 const uint16_t max_size
= (ilo_dev_gen(dev
) >= ILO_GEN(7)) ? 16384 : 8192;
156 ILO_DEV_ASSERT(dev
, 6, 8);
158 switch (info
->type
) {
159 case GEN6_SURFTYPE_1D
:
163 case GEN6_SURFTYPE_2D
:
164 case GEN6_SURFTYPE_CUBE
:
168 case GEN6_SURFTYPE_3D
:
173 assert(!"invalid surface type");
181 get_gen6_hiz_alignments(const struct ilo_dev
*dev
,
182 const struct ilo_image
*img
,
183 uint16_t *align_w
, uint16_t *align_h
)
185 ILO_DEV_ASSERT(dev
, 6, 8);
188 * From the Sandy Bridge PRM, volume 2 part 1, page 313:
190 * "A rectangle primitive representing the clear area is delivered. The
191 * primitive must adhere to the following restrictions on size:
193 * - If Number of Multisamples is NUMSAMPLES_1, the rectangle must be
194 * aligned to an 8x4 pixel block relative to the upper left corner
195 * of the depth buffer, and contain an integer number of these pixel
196 * blocks, and all 8x4 pixels must be lit.
197 * - If Number of Multisamples is NUMSAMPLES_4, the rectangle must be
198 * aligned to a 4x2 pixel block (8x4 sample block) relative to the
199 * upper left corner of the depth buffer, and contain an integer
200 * number of these pixel blocks, and all samples of the 4x2 pixels
202 * - If Number of Multisamples is NUMSAMPLES_8, the rectangle must be
203 * aligned to a 2x2 pixel block (8x4 sample block) relative to the
204 * upper left corner of the depth buffer, and contain an integer
205 * number of these pixel blocks, and all samples of the 2x2 pixels
208 * Experiments on Gen7.5 show that HiZ resolve also requires the rectangle
209 * to be aligned to 8x4 sample blocks. But to be on the safe side, we
210 * always require a level to be aligned when HiZ is enabled.
212 switch (img
->sample_count
) {
234 assert(!"unknown sample count");
242 zs_get_gen6_depth_extent(const struct ilo_dev
*dev
,
243 const struct ilo_state_zs_info
*info
,
244 uint16_t *width
, uint16_t *height
)
246 const struct ilo_image
*img
= (info
->z_img
) ? info
->z_img
: info
->s_img
;
247 uint16_t w
, h
, max_w
, max_h
;
249 ILO_DEV_ASSERT(dev
, 6, 8);
255 uint16_t align_w
, align_h
;
257 get_gen6_hiz_alignments(dev
, info
->z_img
, &align_w
, &align_h
);
260 * We want to force 8x4 alignment, but we can do so only for level 0 and
261 * only when it is padded. ilo_image should know all these.
264 assert(w
% align_w
== 0 && h
% align_h
== 0);
266 w
= align(w
, align_w
);
267 h
= align(h
, align_h
);
270 zs_get_gen6_max_extent(dev
, info
, &max_w
, &max_h
);
271 assert(w
&& h
&& w
<= max_w
&& h
<= max_h
);
280 zs_get_gen6_depth_slices(const struct ilo_dev
*dev
,
281 const struct ilo_state_zs_info
*info
,
282 uint16_t *depth
, uint16_t *min_array_elem
,
283 uint16_t *rt_view_extent
)
285 const struct ilo_image
*img
= (info
->z_img
) ? info
->z_img
: info
->s_img
;
286 uint16_t max_slice
, d
;
288 ILO_DEV_ASSERT(dev
, 6, 8);
291 * From the Sandy Bridge PRM, volume 2 part 1, page 325:
293 * "This field (Depth) specifies the total number of levels for a
294 * volume texture or the number of array elements allowed to be
295 * accessed starting at the Minimum Array Element for arrayed
296 * surfaces. If the volume texture is MIP-mapped, this field specifies
297 * the depth of the base MIP level."
299 switch (info
->type
) {
300 case GEN6_SURFTYPE_1D
:
301 case GEN6_SURFTYPE_2D
:
302 case GEN6_SURFTYPE_CUBE
:
303 max_slice
= (ilo_dev_gen(dev
) >= ILO_GEN(7)) ? 2048 : 512;
305 assert(img
->array_size
<= max_slice
);
306 max_slice
= img
->array_size
;
308 d
= info
->slice_count
;
309 if (info
->type
== GEN6_SURFTYPE_CUBE
) {
311 * Minumum Array Element and Depth must be 0; Render Target View
314 if (info
->slice_base
|| d
!= 6) {
315 ilo_warn("no cube array dpeth buffer\n");
322 case GEN6_SURFTYPE_3D
:
325 assert(img
->depth0
<= max_slice
);
326 max_slice
= u_minify(img
->depth0
, info
->level
);
331 assert(!"invalid surface type");
336 if (!info
->slice_count
||
337 info
->slice_base
+ info
->slice_count
> max_slice
) {
338 ilo_warn("invalid slice range\n");
346 * From the Sandy Bridge PRM, volume 2 part 1, page 325:
348 * "For 1D and 2D Surfaces:
349 * This field (Minimum Array Element) indicates the minimum array
350 * element that can be accessed as part of this surface. The delivered
351 * array index is added to this field before being used to address the
355 * This field indicates the minimum `R' coordinate on the LOD
356 * currently being rendered to. This field is added to the delivered
357 * array index before it is used to address the surface.
359 * For Other Surfaces:
360 * This field is ignored."
362 *min_array_elem
= info
->slice_base
;
365 * From the Sandy Bridge PRM, volume 2 part 1, page 326:
368 * This field (Render Target View Extent) indicates the extent of the
369 * accessible `R' coordinates minus 1 on the LOD currently being
372 * For 1D and 2D Surfaces:
373 * This field must be set to the same value as the Depth field.
375 * For Other Surfaces:
376 * This field is ignored."
378 *rt_view_extent
= info
->slice_count
- 1;
384 zs_set_gen6_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs
*zs
,
385 const struct ilo_dev
*dev
,
386 const struct ilo_state_zs_info
*info
)
388 uint16_t width
, height
, depth
, array_base
, view_extent
;
389 uint32_t dw1
, dw2
, dw3
, dw4
;
391 ILO_DEV_ASSERT(dev
, 6, 6);
393 if (!zs_validate_gen6(dev
, info
) ||
394 !zs_get_gen6_depth_extent(dev
, info
, &width
, &height
) ||
395 !zs_get_gen6_depth_slices(dev
, info
, &depth
, &array_base
,
399 /* info->z_readonly and info->s_readonly are ignored on Gen6 */
400 dw1
= info
->type
<< GEN6_DEPTH_DW1_TYPE__SHIFT
|
401 GEN6_TILING_Y
<< GEN6_DEPTH_DW1_TILING__SHIFT
|
402 info
->format
<< GEN6_DEPTH_DW1_FORMAT__SHIFT
;
405 dw1
|= (info
->z_img
->bo_stride
- 1) << GEN6_DEPTH_DW1_PITCH__SHIFT
;
407 if (info
->hiz_vma
|| !info
->z_img
) {
408 dw1
|= GEN6_DEPTH_DW1_HIZ_ENABLE
|
409 GEN6_DEPTH_DW1_SEPARATE_STENCIL
;
413 dw3
= height
<< GEN6_DEPTH_DW3_HEIGHT__SHIFT
|
414 width
<< GEN6_DEPTH_DW3_WIDTH__SHIFT
|
415 info
->level
<< GEN6_DEPTH_DW3_LOD__SHIFT
|
416 GEN6_DEPTH_DW3_MIPLAYOUT_BELOW
;
417 dw4
= depth
<< GEN6_DEPTH_DW4_DEPTH__SHIFT
|
418 array_base
<< GEN6_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT
|
419 view_extent
<< GEN6_DEPTH_DW4_RT_VIEW_EXTENT__SHIFT
;
421 STATIC_ASSERT(ARRAY_SIZE(zs
->depth
) >= 5);
432 zs_set_gen7_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs
*zs
,
433 const struct ilo_dev
*dev
,
434 const struct ilo_state_zs_info
*info
)
436 uint16_t width
, height
, depth
;
437 uint16_t array_base
, view_extent
;
438 uint32_t dw1
, dw2
, dw3
, dw4
, dw6
;
440 ILO_DEV_ASSERT(dev
, 7, 8);
442 if (!zs_validate_gen6(dev
, info
) ||
443 !zs_get_gen6_depth_extent(dev
, info
, &width
, &height
) ||
444 !zs_get_gen6_depth_slices(dev
, info
, &depth
, &array_base
,
448 dw1
= info
->type
<< GEN7_DEPTH_DW1_TYPE__SHIFT
|
449 info
->format
<< GEN7_DEPTH_DW1_FORMAT__SHIFT
;
452 if (!info
->z_readonly
)
453 dw1
|= GEN7_DEPTH_DW1_DEPTH_WRITE_ENABLE
;
455 dw1
|= GEN7_DEPTH_DW1_HIZ_ENABLE
;
457 dw1
|= (info
->z_img
->bo_stride
- 1) << GEN7_DEPTH_DW1_PITCH__SHIFT
;
460 if (info
->s_img
&& !info
->s_readonly
)
461 dw1
|= GEN7_DEPTH_DW1_STENCIL_WRITE_ENABLE
;
464 dw3
= height
<< GEN7_DEPTH_DW3_HEIGHT__SHIFT
|
465 width
<< GEN7_DEPTH_DW3_WIDTH__SHIFT
|
466 info
->level
<< GEN7_DEPTH_DW3_LOD__SHIFT
;
467 dw4
= depth
<< GEN7_DEPTH_DW4_DEPTH__SHIFT
|
468 array_base
<< GEN7_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT
;
469 dw6
= view_extent
<< GEN7_DEPTH_DW6_RT_VIEW_EXTENT__SHIFT
;
471 if (ilo_dev_gen(dev
) >= ILO_GEN(8) && info
->z_img
) {
472 assert(info
->z_img
->walk_layer_height
% 4 == 0);
473 /* note that DW is off-by-one for Gen8+ */
474 dw6
|= (info
->z_img
->walk_layer_height
/ 4) <<
475 GEN8_DEPTH_DW7_QPITCH__SHIFT
;
478 STATIC_ASSERT(ARRAY_SIZE(zs
->depth
) >= 5);
489 zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs
*zs
,
490 const struct ilo_dev
*dev
)
492 ILO_DEV_ASSERT(dev
, 6, 8);
494 STATIC_ASSERT(ARRAY_SIZE(zs
->stencil
) >= 3);
497 if (ilo_dev_gen(dev
) >= ILO_GEN(8))
504 zs_set_gen6_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs
*zs
,
505 const struct ilo_dev
*dev
,
506 const struct ilo_state_zs_info
*info
)
508 const struct ilo_image
*img
= info
->s_img
;
511 ILO_DEV_ASSERT(dev
, 6, 8);
513 assert(img
->bo_stride
);
516 * From the Sandy Bridge PRM, volume 2 part 1, page 329:
518 * "The pitch must be set to 2x the value computed based on width, as
519 * the stencil buffer is stored with two rows interleaved."
521 * For Gen7+, we still dobule the stride because we did not double the
522 * slice widths when initializing ilo_image.
524 dw1
= (img
->bo_stride
* 2 - 1) << GEN6_STENCIL_DW1_PITCH__SHIFT
;
526 if (ilo_dev_gen(dev
) >= ILO_GEN(7.5))
527 dw1
|= GEN75_STENCIL_DW1_STENCIL_BUFFER_ENABLE
;
530 /* offset to the level as Gen6 does not support mipmapped stencil */
531 if (ilo_dev_gen(dev
) == ILO_GEN(6)) {
534 ilo_image_get_slice_pos(img
, info
->level
, 0, &x
, &y
);
535 ilo_image_pos_to_mem(img
, x
, y
, &x
, &y
);
536 dw2
|= ilo_image_mem_to_raw(img
, x
, y
);
539 STATIC_ASSERT(ARRAY_SIZE(zs
->stencil
) >= 3);
540 zs
->stencil
[0] = dw1
;
541 zs
->stencil
[1] = dw2
;
543 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
546 assert(img
->walk_layer_height
% 4 == 0);
547 dw4
= (img
->walk_layer_height
/ 4) << GEN8_STENCIL_DW4_QPITCH__SHIFT
;
549 zs
->stencil
[2] = dw4
;
556 zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs
*zs
,
557 const struct ilo_dev
*dev
)
559 ILO_DEV_ASSERT(dev
, 6, 8);
561 STATIC_ASSERT(ARRAY_SIZE(zs
->hiz
) >= 3);
564 if (ilo_dev_gen(dev
) >= ILO_GEN(8))
571 zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs
*zs
,
572 const struct ilo_dev
*dev
,
573 const struct ilo_state_zs_info
*info
)
575 const struct ilo_image
*img
= info
->z_img
;
578 ILO_DEV_ASSERT(dev
, 6, 8);
580 assert(img
->aux
.bo_stride
);
582 dw1
= (img
->aux
.bo_stride
- 1) << GEN6_HIZ_DW1_PITCH__SHIFT
;
585 /* offset to the level as Gen6 does not support mipmapped HiZ */
586 if (ilo_dev_gen(dev
) == ILO_GEN(6))
587 dw2
|= img
->aux
.walk_lod_offsets
[info
->level
];
589 STATIC_ASSERT(ARRAY_SIZE(zs
->hiz
) >= 3);
593 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
596 assert(img
->aux
.walk_layer_height
% 4 == 0);
597 dw4
= (img
->aux
.walk_layer_height
/ 4) << GEN8_HIZ_DW4_QPITCH__SHIFT
;
606 ilo_state_zs_init(struct ilo_state_zs
*zs
, const struct ilo_dev
*dev
,
607 const struct ilo_state_zs_info
*info
)
611 assert(ilo_is_zeroed(zs
, sizeof(*zs
)));
613 if (info
->z_img
|| info
->s_img
) {
614 if (ilo_dev_gen(dev
) >= ILO_GEN(7))
615 ret
&= zs_set_gen7_3DSTATE_DEPTH_BUFFER(zs
, dev
, info
);
617 ret
&= zs_set_gen6_3DSTATE_DEPTH_BUFFER(zs
, dev
, info
);
619 ret
&= zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(zs
, dev
);
623 ret
&= zs_set_gen6_3DSTATE_STENCIL_BUFFER(zs
, dev
, info
);
625 ret
&= zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(zs
, dev
);
627 if (info
->z_img
&& info
->hiz_vma
)
628 ret
&= zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(zs
, dev
, info
);
630 ret
&= zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs
, dev
);
632 zs
->z_vma
= info
->z_vma
;
633 zs
->s_vma
= info
->s_vma
;
634 zs
->hiz_vma
= info
->hiz_vma
;
636 zs
->z_readonly
= info
->z_readonly
;
637 zs
->s_readonly
= info
->s_readonly
;
645 ilo_state_zs_init_for_null(struct ilo_state_zs
*zs
,
646 const struct ilo_dev
*dev
)
648 struct ilo_state_zs_info info
;
650 memset(&info
, 0, sizeof(info
));
651 info
.type
= GEN6_SURFTYPE_NULL
;
652 info
.format
= GEN6_ZFORMAT_D32_FLOAT
;
654 return ilo_state_zs_init(zs
, dev
, &info
);
658 ilo_state_zs_disable_hiz(struct ilo_state_zs
*zs
,
659 const struct ilo_dev
*dev
)
661 ILO_DEV_ASSERT(dev
, 6, 8);
664 * Separate stencil must be disabled simultaneously on Gen6. We can make
665 * it work when there is no stencil buffer, but it is probably not worth
668 assert(ilo_dev_gen(dev
) >= ILO_GEN(7));
671 zs
->depth
[0] &= ~GEN7_DEPTH_DW1_HIZ_ENABLE
;
672 zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs
, dev
);