• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ilo_debug.h"
29 #include "ilo_image.h"
30 #include "ilo_vma.h"
31 #include "ilo_state_zs.h"
32 
33 static bool
zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs * zs,const struct ilo_dev * dev)34 zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs *zs,
35                                       const struct ilo_dev *dev)
36 {
37    const enum gen_depth_format format = GEN6_ZFORMAT_D32_FLOAT;
38    uint32_t dw1;
39 
40    ILO_DEV_ASSERT(dev, 6, 8);
41 
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;
45    } else {
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;
49    }
50 
51    STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
52    zs->depth[0] = dw1;
53    zs->depth[1] = 0;
54    zs->depth[2] = 0;
55    zs->depth[3] = 0;
56    zs->depth[4] = 0;
57 
58    return true;
59 }
60 
61 static bool
zs_validate_gen6(const struct ilo_dev * dev,const struct ilo_state_zs_info * info)62 zs_validate_gen6(const struct ilo_dev *dev,
63                  const struct ilo_state_zs_info *info)
64 {
65    const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
66 
67    ILO_DEV_ASSERT(dev, 6, 8);
68 
69    assert(!info->z_img == !info->z_vma);
70    assert(!info->s_img == !info->s_vma);
71 
72    /* all tiled */
73    if (info->z_img) {
74       assert(info->z_img->tiling == GEN6_TILING_Y);
75       assert(info->z_vma->vm_alignment % 4096 == 0);
76    }
77    if (info->s_img) {
78       assert(info->s_img->tiling == GEN8_TILING_W);
79       assert(info->s_vma->vm_alignment % 4096 == 0);
80    }
81    if (info->hiz_vma) {
82       assert(info->z_img &&
83              ilo_image_can_enable_aux(info->z_img, info->level));
84       assert(info->z_vma->vm_alignment % 4096 == 0);
85    }
86 
87    /*
88     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
89     *
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."
94     */
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);
99    }
100 
101    if (info->type != img->type) {
102       assert(info->type == GEN6_SURFTYPE_2D &&
103              img->type == GEN6_SURFTYPE_CUBE);
104    }
105 
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:
111          break;
112       default:
113          assert(!"unknown depth format");
114          break;
115       }
116    } else {
117       /*
118        * From the Ironlake PRM, volume 2 part 1, page 330:
119        *
120        *     "If this field (Separate Stencil Buffer Enable) is disabled, the
121        *      Surface Format of the depth buffer cannot be D24_UNORM_X8_UINT."
122        *
123        * From the Sandy Bridge PRM, volume 2 part 1, page 321:
124        *
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."
128        */
129       if (info->hiz_vma)
130          assert(info->format != GEN6_ZFORMAT_D24_UNORM_S8_UINT);
131       else
132          assert(info->format != GEN6_ZFORMAT_D24_UNORM_X8_UINT);
133    }
134 
135    assert(info->level < img->level_count);
136    assert(img->bo_stride);
137 
138    /*
139     * From the Sandy Bridge PRM, volume 2 part 1, page 323:
140     *
141     *     "For cube maps, Width must be set equal to Height."
142     */
143    if (info->type == GEN6_SURFTYPE_CUBE)
144       assert(img->width0 == img->height0);
145 
146    return true;
147 }
148 
149 static void
zs_get_gen6_max_extent(const struct ilo_dev * dev,const struct ilo_state_zs_info * info,uint16_t * max_w,uint16_t * max_h)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)
153 {
154    const uint16_t max_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 16384 : 8192;
155 
156    ILO_DEV_ASSERT(dev, 6, 8);
157 
158    switch (info->type) {
159    case GEN6_SURFTYPE_1D:
160       *max_w = max_size;
161       *max_h = 1;
162       break;
163    case GEN6_SURFTYPE_2D:
164    case GEN6_SURFTYPE_CUBE:
165       *max_w = max_size;
166       *max_h = max_size;
167       break;
168    case GEN6_SURFTYPE_3D:
169       *max_w = 2048;
170       *max_h = 2048;
171       break;
172    default:
173       assert(!"invalid surface type");
174       *max_w = 1;
175       *max_h = 1;
176       break;
177    }
178 }
179 
180 static void
get_gen6_hiz_alignments(const struct ilo_dev * dev,const struct ilo_image * img,uint16_t * align_w,uint16_t * align_h)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)
184 {
185    ILO_DEV_ASSERT(dev, 6, 8);
186 
187    /*
188     * From the Sandy Bridge PRM, volume 2 part 1, page 313:
189     *
190     *     "A rectangle primitive representing the clear area is delivered. The
191     *      primitive must adhere to the following restrictions on size:
192     *
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
201     *        must be lit
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
206     *        must be list."
207     *
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.
211     */
212    switch (img->sample_count) {
213    case 1:
214       *align_w = 8;
215       *align_h = 4;
216       break;
217    case 2:
218       *align_w = 4;
219       *align_h = 4;
220       break;
221    case 4:
222       *align_w = 4;
223       *align_h = 2;
224       break;
225    case 8:
226       *align_w = 2;
227       *align_h = 2;
228       break;
229    case 16:
230       *align_w = 2;
231       *align_h = 1;
232       break;
233    default:
234       assert(!"unknown sample count");
235       *align_w = 1;
236       *align_h = 1;
237       break;
238    }
239 }
240 
241 static bool
zs_get_gen6_depth_extent(const struct ilo_dev * dev,const struct ilo_state_zs_info * info,uint16_t * width,uint16_t * height)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)
245 {
246    const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
247    uint16_t w, h, max_w, max_h;
248 
249    ILO_DEV_ASSERT(dev, 6, 8);
250 
251    w = img->width0;
252    h = img->height0;
253 
254    if (info->hiz_vma) {
255       uint16_t align_w, align_h;
256 
257       get_gen6_hiz_alignments(dev, info->z_img, &align_w, &align_h);
258 
259       /*
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.
262        */
263       if (info->level)
264          assert(w % align_w == 0 && h % align_h == 0);
265 
266       w = align(w, align_w);
267       h = align(h, align_h);
268    }
269 
270    zs_get_gen6_max_extent(dev, info, &max_w, &max_h);
271    assert(w && h && w <= max_w && h <= max_h);
272 
273    *width = w - 1;
274    *height = h - 1;
275 
276    return true;
277 }
278 
279 static bool
zs_get_gen6_depth_slices(const struct ilo_dev * dev,const struct ilo_state_zs_info * info,uint16_t * depth,uint16_t * min_array_elem,uint16_t * rt_view_extent)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)
284 {
285    const struct ilo_image *img = (info->z_img) ? info->z_img : info->s_img;
286    uint16_t max_slice, d;
287 
288    ILO_DEV_ASSERT(dev, 6, 8);
289 
290    /*
291     * From the Sandy Bridge PRM, volume 2 part 1, page 325:
292     *
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."
298     */
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;
304 
305       assert(img->array_size <= max_slice);
306       max_slice = img->array_size;
307 
308       d = info->slice_count;
309       if (info->type == GEN6_SURFTYPE_CUBE) {
310          /*
311           * Minumum Array Element and Depth must be 0; Render Target View
312           * Extent is ignored.
313           */
314          if (info->slice_base || d != 6) {
315             ilo_warn("no cube array dpeth buffer\n");
316             return false;
317          }
318 
319          d /= 6;
320       }
321       break;
322    case GEN6_SURFTYPE_3D:
323       max_slice = 2048;
324 
325       assert(img->depth0 <= max_slice);
326       max_slice = u_minify(img->depth0, info->level);
327 
328       d = img->depth0;
329       break;
330    default:
331       assert(!"invalid surface type");
332       return false;
333       break;
334    }
335 
336    if (!info->slice_count ||
337        info->slice_base + info->slice_count > max_slice) {
338       ilo_warn("invalid slice range\n");
339       return false;
340    }
341 
342    assert(d);
343    *depth = d - 1;
344 
345    /*
346     * From the Sandy Bridge PRM, volume 2 part 1, page 325:
347     *
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
352     *      surface.
353     *
354     *      For 3D Surfaces:
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.
358     *
359     *      For Other Surfaces:
360     *      This field is ignored."
361     */
362    *min_array_elem = info->slice_base;
363 
364    /*
365     * From the Sandy Bridge PRM, volume 2 part 1, page 326:
366     *
367     *     "For 3D Surfaces:
368     *      This field (Render Target View Extent) indicates the extent of the
369     *      accessible `R' coordinates minus 1 on the LOD currently being
370     *      rendered to.
371     *
372     *      For 1D and 2D Surfaces:
373     *      This field must be set to the same value as the Depth field.
374     *
375     *      For Other Surfaces:
376     *      This field is ignored."
377     */
378    *rt_view_extent = info->slice_count - 1;
379 
380    return true;
381 }
382 
383 static bool
zs_set_gen6_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs * zs,const struct ilo_dev * dev,const struct ilo_state_zs_info * info)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)
387 {
388    uint16_t width, height, depth, array_base, view_extent;
389    uint32_t dw1, dw2, dw3, dw4;
390 
391    ILO_DEV_ASSERT(dev, 6, 6);
392 
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,
396                                  &view_extent))
397       return false;
398 
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;
403 
404    if (info->z_img)
405       dw1 |= (info->z_img->bo_stride - 1) << GEN6_DEPTH_DW1_PITCH__SHIFT;
406 
407    if (info->hiz_vma || !info->z_img) {
408       dw1 |= GEN6_DEPTH_DW1_HIZ_ENABLE |
409              GEN6_DEPTH_DW1_SEPARATE_STENCIL;
410    }
411 
412    dw2 = 0;
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;
420 
421    STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
422    zs->depth[0] = dw1;
423    zs->depth[1] = dw2;
424    zs->depth[2] = dw3;
425    zs->depth[3] = dw4;
426    zs->depth[4] = 0;
427 
428    return true;
429 }
430 
431 static bool
zs_set_gen7_3DSTATE_DEPTH_BUFFER(struct ilo_state_zs * zs,const struct ilo_dev * dev,const struct ilo_state_zs_info * info)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)
435 {
436    uint16_t width, height, depth;
437    uint16_t array_base, view_extent;
438    uint32_t dw1, dw2, dw3, dw4, dw6;
439 
440    ILO_DEV_ASSERT(dev, 7, 8);
441 
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,
445                                  &view_extent))
446       return false;
447 
448    dw1 = info->type << GEN7_DEPTH_DW1_TYPE__SHIFT |
449          info->format << GEN7_DEPTH_DW1_FORMAT__SHIFT;
450 
451    if (info->z_img) {
452       if (!info->z_readonly)
453          dw1 |= GEN7_DEPTH_DW1_DEPTH_WRITE_ENABLE;
454       if (info->hiz_vma)
455          dw1 |= GEN7_DEPTH_DW1_HIZ_ENABLE;
456 
457       dw1 |= (info->z_img->bo_stride - 1) << GEN7_DEPTH_DW1_PITCH__SHIFT;
458    }
459 
460    if (info->s_img && !info->s_readonly)
461       dw1 |= GEN7_DEPTH_DW1_STENCIL_WRITE_ENABLE;
462 
463    dw2 = 0;
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;
470 
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;
476    }
477 
478    STATIC_ASSERT(ARRAY_SIZE(zs->depth) >= 5);
479    zs->depth[0] = dw1;
480    zs->depth[1] = dw2;
481    zs->depth[2] = dw3;
482    zs->depth[3] = dw4;
483    zs->depth[4] = dw6;
484 
485    return true;
486 }
487 
488 static bool
zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs * zs,const struct ilo_dev * dev)489 zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs *zs,
490                                         const struct ilo_dev *dev)
491 {
492    ILO_DEV_ASSERT(dev, 6, 8);
493 
494    STATIC_ASSERT(ARRAY_SIZE(zs->stencil) >= 3);
495    zs->stencil[0] = 0;
496    zs->stencil[1] = 0;
497    if (ilo_dev_gen(dev) >= ILO_GEN(8))
498       zs->stencil[2] = 0;
499 
500    return true;
501 }
502 
503 static bool
zs_set_gen6_3DSTATE_STENCIL_BUFFER(struct ilo_state_zs * zs,const struct ilo_dev * dev,const struct ilo_state_zs_info * info)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)
507 {
508    const struct ilo_image *img = info->s_img;
509    uint32_t dw1, dw2;
510 
511    ILO_DEV_ASSERT(dev, 6, 8);
512 
513    assert(img->bo_stride);
514 
515    /*
516     * From the Sandy Bridge PRM, volume 2 part 1, page 329:
517     *
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."
520     *
521     * For Gen7+, we still dobule the stride because we did not double the
522     * slice widths when initializing ilo_image.
523     */
524    dw1 = (img->bo_stride * 2 - 1) << GEN6_STENCIL_DW1_PITCH__SHIFT;
525 
526    if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
527       dw1 |= GEN75_STENCIL_DW1_STENCIL_BUFFER_ENABLE;
528 
529    dw2 = 0;
530    /* offset to the level as Gen6 does not support mipmapped stencil */
531    if (ilo_dev_gen(dev) == ILO_GEN(6)) {
532       unsigned x, y;
533 
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);
537    }
538 
539    STATIC_ASSERT(ARRAY_SIZE(zs->stencil) >= 3);
540    zs->stencil[0] = dw1;
541    zs->stencil[1] = dw2;
542 
543    if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
544       uint32_t dw4;
545 
546       assert(img->walk_layer_height % 4 == 0);
547       dw4 = (img->walk_layer_height / 4) << GEN8_STENCIL_DW4_QPITCH__SHIFT;
548 
549       zs->stencil[2] = dw4;
550    }
551 
552    return true;
553 }
554 
555 static bool
zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs * zs,const struct ilo_dev * dev)556 zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs *zs,
557                                            const struct ilo_dev *dev)
558 {
559    ILO_DEV_ASSERT(dev, 6, 8);
560 
561    STATIC_ASSERT(ARRAY_SIZE(zs->hiz) >= 3);
562    zs->hiz[0] = 0;
563    zs->hiz[1] = 0;
564    if (ilo_dev_gen(dev) >= ILO_GEN(8))
565       zs->hiz[2] = 0;
566 
567    return true;
568 }
569 
570 static bool
zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(struct ilo_state_zs * zs,const struct ilo_dev * dev,const struct ilo_state_zs_info * info)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)
574 {
575    const struct ilo_image *img = info->z_img;
576    uint32_t dw1, dw2;
577 
578    ILO_DEV_ASSERT(dev, 6, 8);
579 
580    assert(img->aux.bo_stride);
581 
582    dw1 = (img->aux.bo_stride - 1) << GEN6_HIZ_DW1_PITCH__SHIFT;
583 
584    dw2 = 0;
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];
588 
589    STATIC_ASSERT(ARRAY_SIZE(zs->hiz) >= 3);
590    zs->hiz[0] = dw1;
591    zs->hiz[1] = dw2;
592 
593    if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
594       uint32_t dw4;
595 
596       assert(img->aux.walk_layer_height % 4 == 0);
597       dw4 = (img->aux.walk_layer_height / 4) << GEN8_HIZ_DW4_QPITCH__SHIFT;
598 
599       zs->hiz[2] = dw4;
600    }
601 
602    return true;
603 }
604 
605 bool
ilo_state_zs_init(struct ilo_state_zs * zs,const struct ilo_dev * dev,const struct ilo_state_zs_info * info)606 ilo_state_zs_init(struct ilo_state_zs *zs, const struct ilo_dev *dev,
607                   const struct ilo_state_zs_info *info)
608 {
609    bool ret = true;
610 
611    assert(ilo_is_zeroed(zs, sizeof(*zs)));
612 
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);
616       else
617          ret &= zs_set_gen6_3DSTATE_DEPTH_BUFFER(zs, dev, info);
618    } else {
619       ret &= zs_set_gen6_null_3DSTATE_DEPTH_BUFFER(zs, dev);
620    }
621 
622    if (info->s_img)
623       ret &= zs_set_gen6_3DSTATE_STENCIL_BUFFER(zs, dev, info);
624    else
625       ret &= zs_set_gen6_null_3DSTATE_STENCIL_BUFFER(zs, dev);
626 
627    if (info->z_img && info->hiz_vma)
628       ret &= zs_set_gen6_3DSTATE_HIER_DEPTH_BUFFER(zs, dev, info);
629    else
630       ret &= zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs, dev);
631 
632    zs->z_vma = info->z_vma;
633    zs->s_vma = info->s_vma;
634    zs->hiz_vma = info->hiz_vma;
635 
636    zs->z_readonly = info->z_readonly;
637    zs->s_readonly = info->s_readonly;
638 
639    assert(ret);
640 
641    return ret;
642 }
643 
644 bool
ilo_state_zs_init_for_null(struct ilo_state_zs * zs,const struct ilo_dev * dev)645 ilo_state_zs_init_for_null(struct ilo_state_zs *zs,
646                            const struct ilo_dev *dev)
647 {
648    struct ilo_state_zs_info info;
649 
650    memset(&info, 0, sizeof(info));
651    info.type = GEN6_SURFTYPE_NULL;
652    info.format = GEN6_ZFORMAT_D32_FLOAT;
653 
654    return ilo_state_zs_init(zs, dev, &info);
655 }
656 
657 bool
ilo_state_zs_disable_hiz(struct ilo_state_zs * zs,const struct ilo_dev * dev)658 ilo_state_zs_disable_hiz(struct ilo_state_zs *zs,
659                          const struct ilo_dev *dev)
660 {
661    ILO_DEV_ASSERT(dev, 6, 8);
662 
663    /*
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
666     * it.
667     */
668    assert(ilo_dev_gen(dev) >= ILO_GEN(7));
669 
670    if (zs->hiz_vma) {
671       zs->depth[0] &= ~GEN7_DEPTH_DW1_HIZ_ENABLE;
672       zs_set_gen6_null_3DSTATE_HIER_DEPTH_BUFFER(zs, dev);
673       zs->hiz_vma = NULL;
674    }
675 
676    return true;
677 }
678