Merge branch 'wip/nir-vtn' into vulkan
[mesa.git] / src / gallium / drivers / ilo / core / ilo_state_zs.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2015 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 "intel_winsys.h"
29
30 #include "ilo_debug.h"
31 #include "ilo_image.h"
32 #include "ilo_state_zs.h"
33
34 static bool
35 zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs *zs,
36 const struct ilo_dev *dev)
37 {
38 const enum gen_depth_format format = GEN6_ZFORMAT_D32_FLOAT;
39 uint32_t dw1;
40
41 ILO_DEV_ASSERT(dev, 6, 8);
42
43 if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
44 dw1 = GEN6_SURFTYPE_NULL << GEN7_DEPTH_DW1_TYPE__SHIFT |
45 format << GEN7_DEPTH_DW1_FORMAT__SHIFT;
46 } else {
47 dw1 = GEN6_SURFTYPE_NULL << GEN6_DEPTH_DW1_TYPE__SHIFT |
48 GEN6_TILING_Y << GEN6_DEPTH_DW1_TILING__SHIFT |
49 format << GEN6_DEPTH_DW1_FORMAT__SHIFT;
50 }
51
52 STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
53 zs->depth[0] = dw1;
54 zs->depth[1] = 0;
55 zs->depth[2] = 0;
56 zs->depth[3] = 0;
57 zs->depth[4] = 0;
58
59 zs->depth_format = format;
60
61 return true;
62 }
63
64 static enum gen_surface_type
65 get_gen6_surface_type(const struct ilo_dev *dev, const struct ilo_image *img)
66 {
67 ILO_DEV_ASSERT(dev, 6, 8);
68
69 switch (img->target) {
70 case PIPE_TEXTURE_1D:
71 case PIPE_TEXTURE_1D_ARRAY:
72 return GEN6_SURFTYPE_1D;
73 case PIPE_TEXTURE_2D:
74 case PIPE_TEXTURE_CUBE:
75 case PIPE_TEXTURE_RECT:
76 case PIPE_TEXTURE_2D_ARRAY:
77 case PIPE_TEXTURE_CUBE_ARRAY:
78 return GEN6_SURFTYPE_2D;
79 case PIPE_TEXTURE_3D:
80 return GEN6_SURFTYPE_3D;
81 default:
82 assert(!"unknown texture target");
83 return GEN6_SURFTYPE_NULL;
84 }
85 }
86
87 static enum gen_depth_format
88 get_gen6_depth_format(const struct ilo_dev *dev, const struct ilo_image *img)
89 {
90 ILO_DEV_ASSERT(dev, 6, 8);
91
92 if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
93 switch (img->format) {
94 case PIPE_FORMAT_Z32_FLOAT:
95 return GEN6_ZFORMAT_D32_FLOAT;
96 case PIPE_FORMAT_Z24X8_UNORM:
97 return GEN6_ZFORMAT_D24_UNORM_X8_UINT;
98 case PIPE_FORMAT_Z16_UNORM:
99 return GEN6_ZFORMAT_D16_UNORM;
100 default:
101 assert(!"unknown depth format");
102 return GEN6_ZFORMAT_D32_FLOAT;
103 }
104 } else {
105 switch (img->format) {
106 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
107 return GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT;
108 case PIPE_FORMAT_Z32_FLOAT:
109 return GEN6_ZFORMAT_D32_FLOAT;
110 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
111 return GEN6_ZFORMAT_D24_UNORM_S8_UINT;
112 case PIPE_FORMAT_Z24X8_UNORM:
113 return GEN6_ZFORMAT_D24_UNORM_X8_UINT;
114 case PIPE_FORMAT_Z16_UNORM:
115 return GEN6_ZFORMAT_D16_UNORM;
116 default:
117 assert(!"unknown depth format");
118 return GEN6_ZFORMAT_D32_FLOAT;
119 }
120 }
121 }
122
123 static bool
124 zs_validate_gen6(const struct ilo_dev *dev,
125 const struct ilo_state_zs_info *info)
126 {
127 const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
128
129 ILO_DEV_ASSERT(dev, 6, 8);
130
131 /*
132 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
133 *
134 * The stencil buffer has a format of S8_UINT, and shares Surface
135 * Type, Height, Width, and Depth, Minimum Array Element, Render
136 * Target View Extent, Depth Coordinate Offset X/Y, LOD, and Depth
137 * Buffer Object Control State fields of the depth buffer.
138 */
139 if (info->z_img == info->s_img) {
140 assert(info->z_img->target == info->s_img->target &&
141 info->z_img->width0 == info->s_img->width0 &&
142 info->z_img->height0 == info->s_img->height0 &&
143 info->z_img->depth0 == info->s_img->depth0);
144 }
145
146 assert(info->level < img->level_count);
147 assert(img->bo_stride);
148
149 if (info->hiz_enable) {
150 assert(info->z_img &&
151 ilo_image_can_enable_aux(info->z_img, info->level));
152 }
153
154 if (info->is_cube_map) {
155 assert(get_gen6_surface_type(dev, img) == GEN6_SURFTYPE_2D);
156
157 /*
158 * From the Sandy Bridge PRM, volume 2 part 1, page 323:
159 *
160 * "For cube maps, Width must be set equal to Height."
161 */
162 assert(img->width0 == img->height0);
163 }
164
165 if (info->z_img)
166 assert(info->z_img->tiling == GEN6_TILING_Y);
167 if (info->s_img)
168 assert(info->s_img->tiling == GEN8_TILING_W);
169
170 return true;
171 }
172
173 static void
174 get_gen6_max_extent(const struct ilo_dev *dev,
175 const struct ilo_image *img,
176 uint16_t *max_w, uint16_t *max_h)
177 {
178 const uint16_t max_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 16384 : 8192;
179
180 ILO_DEV_ASSERT(dev, 6, 8);
181
182 switch (get_gen6_surface_type(dev, img)) {
183 case GEN6_SURFTYPE_1D:
184 *max_w = max_size;
185 *max_h = 1;
186 break;
187 case GEN6_SURFTYPE_2D:
188 *max_w = max_size;
189 *max_h = max_size;
190 break;
191 case GEN6_SURFTYPE_3D:
192 *max_w = 2048;
193 *max_h = 2048;
194 break;
195 default:
196 assert(!"invalid surface type");
197 *max_w = 1;
198 *max_h = 1;
199 break;
200 }
201 }
202
203 static void
204 get_gen6_hiz_alignments(const struct ilo_dev *dev,
205 const struct ilo_image *img,
206 uint16_t *align_w, uint16_t *align_h)
207 {
208 ILO_DEV_ASSERT(dev, 6, 8);
209
210 /*
211 * From the Sandy Bridge PRM, volume 2 part 1, page 313:
212 *
213 * "A rectangle primitive representing the clear area is delivered. The
214 * primitive must adhere to the following restrictions on size:
215 *
216 * - If Number of Multisamples is NUMSAMPLES_1, the rectangle must be
217 * aligned to an 8x4 pixel block relative to the upper left corner
218 * of the depth buffer, and contain an integer number of these pixel
219 * blocks, and all 8x4 pixels must be lit.
220 * - If Number of Multisamples is NUMSAMPLES_4, the rectangle must be
221 * aligned to a 4x2 pixel block (8x4 sample block) relative to the
222 * upper left corner of the depth buffer, and contain an integer
223 * number of these pixel blocks, and all samples of the 4x2 pixels
224 * must be lit
225 * - If Number of Multisamples is NUMSAMPLES_8, the rectangle must be
226 * aligned to a 2x2 pixel block (8x4 sample block) relative to the
227 * upper left corner of the depth buffer, and contain an integer
228 * number of these pixel blocks, and all samples of the 2x2 pixels
229 * must be list."
230 *
231 * Experiments on Gen7.5 show that HiZ resolve also requires the rectangle
232 * to be aligned to 8x4 sample blocks. But to be on the safe side, we
233 * always require a level to be aligned when HiZ is enabled.
234 */
235 switch (img->sample_count) {
236 case 1:
237 *align_w = 8;
238 *align_h = 4;
239 break;
240 case 2:
241 *align_w = 4;
242 *align_h = 4;
243 break;
244 case 4:
245 *align_w = 4;
246 *align_h = 2;
247 break;
248 case 8:
249 *align_w = 2;
250 *align_h = 2;
251 break;
252 case 16:
253 *align_w = 2;
254 *align_h = 1;
255 break;
256 default:
257 assert(!"unknown sample count");
258 *align_w = 1;
259 *align_h = 1;
260 break;
261 }
262 }
263
264 static bool
265 zs_get_gen6_depth_extent(const struct ilo_dev *dev,
266 const struct ilo_state_zs_info *info,
267 uint16_t *width, uint16_t *height)
268 {
269 const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
270 uint16_t w, h, max_w, max_h;
271
272 ILO_DEV_ASSERT(dev, 6, 8);
273
274 w = img->width0;
275 h = img->height0;
276
277 if (info->hiz_enable) {
278 uint16_t align_w, align_h;
279
280 get_gen6_hiz_alignments(dev, info->z_img, &align_w, &align_h);
281
282 /*
283 * We want to force 8x4 alignment, but we can do so only for level 0 and
284 * only when it is padded. ilo_image should know all these.
285 */
286 if (info->level)
287 assert(w % align_w == 0 && h % align_h == 0);
288
289 w = align(w, align_w);
290 h = align(h, align_h);
291 }
292
293 get_gen6_max_extent(dev, img, &max_w, &max_h);
294 assert(w && h && w <= max_w && h <= max_h);
295
296 *width = w - 1;
297 *height = h - 1;
298
299 return true;
300 }
301
302 static bool
303 zs_get_gen6_depth_slices(const struct ilo_dev *dev,
304 const struct ilo_state_zs_info *info,
305 uint16_t *depth, uint16_t *min_array_elem,
306 uint16_t *rt_view_extent)
307 {
308 const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
309 uint16_t max_slice, d;
310
311 ILO_DEV_ASSERT(dev, 6, 8);
312
313 /*
314 * From the Sandy Bridge PRM, volume 2 part 1, page 325:
315 *
316 * "This field (Depth) specifies the total number of levels for a
317 * volume texture or the number of array elements allowed to be
318 * accessed starting at the Minimum Array Element for arrayed
319 * surfaces. If the volume texture is MIP-mapped, this field specifies
320 * the depth of the base MIP level."
321 */
322 switch (get_gen6_surface_type(dev, img)) {
323 case GEN6_SURFTYPE_1D:
324 case GEN6_SURFTYPE_2D:
325 max_slice = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 2048 : 512;
326
327 assert(img->array_size <= max_slice);
328 max_slice = img->array_size;
329
330 d = info->slice_count;
331 if (info->is_cube_map) {
332 /*
333 * Minumum Array Element and Depth must be 0; Render Target View
334 * Extent is ignored.
335 */
336 if (info->slice_base || d != 6) {
337 ilo_warn("no cube array dpeth buffer\n");
338 return false;
339 }
340
341 d /= 6;
342 }
343 break;
344 case GEN6_SURFTYPE_3D:
345 max_slice = 2048;
346
347 assert(img->depth0 <= max_slice);
348 max_slice = u_minify(img->depth0, info->level);
349
350 d = img->depth0;
351 break;
352 default:
353 assert(!"invalid surface type");
354 return false;
355 break;
356 }
357
358 if (!info->slice_count ||
359 info->slice_base + info->slice_count > max_slice) {
360 ilo_warn("invalid slice range\n");
361 return false;
362 }
363
364 assert(d);
365 *depth = d - 1;
366
367 /*
368 * From the Sandy Bridge PRM, volume 2 part 1, page 325:
369 *
370 * "For 1D and 2D Surfaces:
371 * This field (Minimum Array Element) indicates the minimum array
372 * element that can be accessed as part of this surface. The delivered
373 * array index is added to this field before being used to address the
374 * surface.
375 *
376 * For 3D Surfaces:
377 * This field indicates the minimum `R' coordinate on the LOD
378 * currently being rendered to. This field is added to the delivered
379 * array index before it is used to address the surface.
380 *
381 * For Other Surfaces:
382 * This field is ignored."
383 */
384 *min_array_elem = info->slice_base;
385
386 /*
387 * From the Sandy Bridge PRM, volume 2 part 1, page 326:
388 *
389 * "For 3D Surfaces:
390 * This field (Render Target View Extent) indicates the extent of the
391 * accessible `R' coordinates minus 1 on the LOD currently being
392 * rendered to.
393 *
394 * For 1D and 2D Surfaces:
395 * This field must be set to the same value as the Depth field.
396 *
397 * For Other Surfaces:
398 * This field is ignored."
399 */
400 *rt_view_extent = info->slice_count - 1;
401
402 return true;
403 }
404
405 static bool
406 zs_set_gen6_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs *zs,
407 const struct ilo_dev *dev,
408 const struct ilo_state_zs_info *info)
409 {
410 uint16_t width, height, depth, array_base, view_extent;
411 enum gen_surface_type type;
412 enum gen_depth_format format;
413 uint32_t dw1, dw2, dw3, dw4;
414
415 ILO_DEV_ASSERT(dev, 6, 6);
416
417 if (!zs_validate_gen6(dev, info) ||
418 !zs_get_gen6_depth_extent(dev, info, &width, &height) ||
419 !zs_get_gen6_depth_slices(dev, info, &depth, &array_base,
420 &view_extent))
421 return false;
422
423 type = (info->is_cube_map) ? GEN6_SURFTYPE_CUBE :
424 (info->z_img) ? get_gen6_surface_type(dev, info->z_img) :
425 get_gen6_surface_type(dev, info->s_img);
426
427 format = (info->z_img) ? get_gen6_depth_format(dev, info->z_img) :
428 GEN6_ZFORMAT_D32_FLOAT;
429
430 /*
431 * From the Ironlake PRM, volume 2 part 1, page 330:
432 *
433 * "If this field (Separate Stencil Buffer Enable) is disabled, the
434 * Surface Format of the depth buffer cannot be D24_UNORM_X8_UINT."
435 *
436 * From the Sandy Bridge PRM, volume 2 part 1, page 321:
437 *
438 * "[DevSNB]: This field (Separate Stencil Buffer Enable) must be set
439 * to the same value (enabled or disabled) as Hierarchical Depth
440 * Buffer Enable."
441 */
442 if (!info->hiz_enable && format == GEN6_ZFORMAT_D24_UNORM_X8_UINT)
443 format = GEN6_ZFORMAT_D24_UNORM_S8_UINT;
444
445 /* info->z_readonly and info->s_readonly are ignored on Gen6 */
446 dw1 = type << GEN6_DEPTH_DW1_TYPE__SHIFT |
447 GEN6_TILING_Y << GEN6_DEPTH_DW1_TILING__SHIFT |
448 format << GEN6_DEPTH_DW1_FORMAT__SHIFT;
449
450 if (info->z_img)
451 dw1 |= (info->z_img->bo_stride - 1) << GEN6_DEPTH_DW1_PITCH__SHIFT;
452
453 if (info->hiz_enable || !info->z_img) {
454 dw1 |= GEN6_DEPTH_DW1_HIZ_ENABLE |
455 GEN6_DEPTH_DW1_SEPARATE_STENCIL;
456 }
457
458 dw2 = 0;
459 dw3 = height << GEN6_DEPTH_DW3_HEIGHT__SHIFT |
460 width << GEN6_DEPTH_DW3_WIDTH__SHIFT |
461 info->level << GEN6_DEPTH_DW3_LOD__SHIFT |
462 GEN6_DEPTH_DW3_MIPLAYOUT_BELOW;
463 dw4 = depth << GEN6_DEPTH_DW4_DEPTH__SHIFT |
464 array_base << GEN6_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT |
465 view_extent << GEN6_DEPTH_DW4_RT_VIEW_EXTENT__SHIFT;
466
467 STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
468 zs->depth[0] = dw1;
469 zs->depth[1] = dw2;
470 zs->depth[2] = dw3;
471 zs->depth[3] = dw4;
472 zs->depth[4] = 0;
473
474 zs->depth_format = format;
475
476 return true;
477 }
478
479 static bool
480 zs_set_gen7_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs *zs,
481 const struct ilo_dev *dev,
482 const struct ilo_state_zs_info *info)
483 {
484 enum gen_surface_type type;
485 enum gen_depth_format format;
486 uint16_t width, height, depth;
487 uint16_t array_base, view_extent;
488 uint32_t dw1, dw2, dw3, dw4, dw6;
489
490 ILO_DEV_ASSERT(dev, 7, 8);
491
492 if (!zs_validate_gen6(dev, info) ||
493 !zs_get_gen6_depth_extent(dev, info, &width, &height) ||
494 !zs_get_gen6_depth_slices(dev, info, &depth, &array_base,
495 &view_extent))
496 return false;
497
498 type = (info->is_cube_map) ? GEN6_SURFTYPE_CUBE :
499 (info->z_img) ? get_gen6_surface_type(dev, info->z_img) :
500 get_gen6_surface_type(dev, info->s_img);
501
502 format = (info->z_img) ? get_gen6_depth_format(dev, info->z_img) :
503 GEN6_ZFORMAT_D32_FLOAT;
504
505 dw1 = type << GEN7_DEPTH_DW1_TYPE__SHIFT |
506 format << GEN7_DEPTH_DW1_FORMAT__SHIFT;
507
508 if (info->z_img) {
509 if (!info->z_readonly)
510 dw1 |= GEN7_DEPTH_DW1_DEPTH_WRITE_ENABLE;
511 if (info->hiz_enable)
512 dw1 |= GEN7_DEPTH_DW1_HIZ_ENABLE;
513
514 dw1 |= (info->z_img->bo_stride - 1) << GEN7_DEPTH_DW1_PITCH__SHIFT;
515 }
516
517 if (info->s_img && !info->s_readonly)
518 dw1 |= GEN7_DEPTH_DW1_STENCIL_WRITE_ENABLE;
519
520 dw2 = 0;
521 dw3 = height << GEN7_DEPTH_DW3_HEIGHT__SHIFT |
522 width << GEN7_DEPTH_DW3_WIDTH__SHIFT |
523 info->level << GEN7_DEPTH_DW3_LOD__SHIFT;
524 dw4 = depth << GEN7_DEPTH_DW4_DEPTH__SHIFT |
525 array_base << GEN7_DEPTH_DW4_MIN_ARRAY_ELEMENT__SHIFT;
526 dw6 = view_extent << GEN7_DEPTH_DW6_RT_VIEW_EXTENT__SHIFT;
527
528 if (ilo_dev_gen(dev) >= ILO_GEN(8) && info->z_img) {
529 assert(info->z_img->walk_layer_height % 4 == 0);
530 /* note that DW is off-by-one for Gen8+ */
531 dw6 |= (info->z_img->walk_layer_height / 4) <<
532 GEN8_DEPTH_DW7_QPITCH__SHIFT;
533 }
534
535 STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
536 zs->depth[0] = dw1;
537 zs->depth[1] = dw2;
538 zs->depth[2] = dw3;
539 zs->depth[3] = dw4;
540 zs->depth[4] = dw6;
541
542 zs->depth_format = format;
543
544 return true;
545 }
546
547 static bool
548 zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs *zs,
549 const struct ilo_dev *dev)
550 {
551 ILO_DEV_ASSERT(dev, 6, 8);
552
553 STATIC_ASSERT(ARRAY_SIZE(zs->stencil) >= 3);
554 zs->stencil[0] = 0;
555 zs->stencil[1] = 0;
556 if (ilo_dev_gen(dev) >= ILO_GEN(8))
557 zs->stencil[2] = 0;
558
559 return true;
560 }
561
562 static bool
563 zs_set_gen6_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs *zs,
564 const struct ilo_dev *dev,
565 const struct ilo_state_zs_info *info)
566 {
567 const struct ilo_image *img = info->s_img;
568 uint32_t dw1, dw2;
569
570 ILO_DEV_ASSERT(dev, 6, 8);
571
572 assert(img->bo_stride);
573
574 /*
575 * From the Sandy Bridge PRM, volume 2 part 1, page 329:
576 *
577 * "The pitch must be set to 2x the value computed based on width, as
578 * the stencil buffer is stored with two rows interleaved."
579 *
580 * For Gen7+, we still dobule the stride because we did not double the
581 * slice widths when initializing ilo_image.
582 */
583 dw1 = (img->bo_stride * 2 - 1) << GEN6_STENCIL_DW1_PITCH__SHIFT;
584
585 if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
586 dw1 |= GEN75_STENCIL_DW1_STENCIL_BUFFER_ENABLE;
587
588 dw2 = 0;
589 /* offset to the level as Gen6 does not support mipmapped stencil */
590 if (ilo_dev_gen(dev) == ILO_GEN(6)) {
591 unsigned x, y;
592
593 ilo_image_get_slice_pos(img, info->level, 0, &x, &y);
594 ilo_image_pos_to_mem(img, x, y, &x, &y);
595 dw2 |= ilo_image_mem_to_raw(img, x, y);
596 }
597
598 STATIC_ASSERT(ARRAY_SIZE(zs->stencil) >= 3);
599 zs->stencil[0] = dw1;
600 zs->stencil[1] = dw2;
601
602 if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
603 uint32_t dw4;
604
605 assert(img->walk_layer_height % 4 == 0);
606 dw4 = (img->walk_layer_height / 4) << GEN8_STENCIL_DW4_QPITCH__SHIFT;
607
608 zs->stencil[2] = dw4;
609 }
610
611 return true;
612 }
613
614 static bool
615 zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs *zs,
616 const struct ilo_dev *dev)
617 {
618 ILO_DEV_ASSERT(dev, 6, 8);
619
620 STATIC_ASSERT(ARRAY_SIZE(zs->hiz) >= 3);
621 zs->hiz[0] = 0;
622 zs->hiz[1] = 0;
623 if (ilo_dev_gen(dev) >= ILO_GEN(8))
624 zs->hiz[2] = 0;
625
626 return true;
627 }
628
629 static bool
630 zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs *zs,
631 const struct ilo_dev *dev,
632 const struct ilo_state_zs_info *info)
633 {
634 const struct ilo_image *img = info->z_img;
635 uint32_t dw1, dw2;
636
637 ILO_DEV_ASSERT(dev, 6, 8);
638
639 assert(img->aux.bo_stride);
640
641 dw1 = (img->aux.bo_stride - 1) << GEN6_HIZ_DW1_PITCH__SHIFT;
642
643 dw2 = 0;
644 /* offset to the level as Gen6 does not support mipmapped HiZ */
645 if (ilo_dev_gen(dev) == ILO_GEN(6))
646 dw2 |= img->aux.walk_lod_offsets[info->level];
647
648 STATIC_ASSERT(ARRAY_SIZE(zs->hiz) >= 3);
649 zs->hiz[0] = dw1;
650 zs->hiz[1] = dw2;
651
652 if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
653 uint32_t dw4;
654
655 assert(img->aux.walk_layer_height % 4 == 0);
656 dw4 = (img->aux.walk_layer_height / 4) << GEN8_HIZ_DW4_QPITCH__SHIFT;
657
658 zs->hiz[2] = dw4;
659 }
660
661 return true;
662 }
663
664 bool
665 ilo_state_zs_init(struct ilo_state_zs *zs, const struct ilo_dev *dev,
666 const struct ilo_state_zs_info *info)
667 {
668 bool ret = true;
669
670 assert(ilo_is_zeroed(zs, sizeof(*zs)));
671
672 if (info->z_img || info->s_img) {
673 if (ilo_dev_gen(dev) >= ILO_GEN(7))
674 ret &= zs_set_gen7_3DSTATE_DEPTH_BUFFER(zs, dev, info);
675 else
676 ret &= zs_set_gen6_3DSTATE_DEPTH_BUFFER(zs, dev, info);
677 } else {
678 ret &= zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(zs, dev);
679 }
680
681 if (info->s_img)
682 ret &= zs_set_gen6_3DSTATE_STENCIL_BUFFER(zs, dev, info);
683 else
684 ret &= zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(zs, dev);
685
686 if (info->z_img && info->hiz_enable)
687 ret &= zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(zs, dev, info);
688 else
689 ret &= zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs, dev);
690
691 zs->z_readonly = info->z_readonly;
692 zs->s_readonly = info->s_readonly;
693
694 assert(ret);
695
696 return ret;
697 }
698
699 bool
700 ilo_state_zs_init_for_null(struct ilo_state_zs *zs,
701 const struct ilo_dev *dev)
702 {
703 struct ilo_state_zs_info info;
704
705 memset(&info, 0, sizeof(info));
706
707 return ilo_state_zs_init(zs, dev, &info);
708 }
709
710 bool
711 ilo_state_zs_disable_hiz(struct ilo_state_zs *zs,
712 const struct ilo_dev *dev)
713 {
714 ILO_DEV_ASSERT(dev, 6, 8);
715
716 /*
717 * Separate stencil must be disabled simultaneously on Gen6. We can make
718 * it work when there is no stencil buffer, but it is probably not worth
719 * it.
720 */
721 assert(ilo_dev_gen(dev) >= ILO_GEN(7));
722
723 zs->depth[0] &= ~GEN7_DEPTH_DW1_HIZ_ENABLE;
724 zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs, dev);
725
726 return true;
727 }