• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2025 Igalia S.L.
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef FREEDRENO_LRZ_LAYOUT_H_
7 #define FREEDRENO_LRZ_LAYOUT_H_
8 
9 #include <stdint.h>
10 
11 #include "freedreno_layout.h"
12 
13 BEGINC;
14 
15 struct fdl_lrz_layout {
16    uint32_t lrz_offset;
17    uint32_t lrz_pitch;
18    uint32_t lrz_height;
19    uint32_t lrz_layer_size;
20    uint32_t lrz_fc_offset;
21    uint32_t lrz_fc_size;
22    uint32_t lrz_total_size;
23 };
24 
25 void
26 fdl5_lrz_layout_init(struct fdl_lrz_layout *lrz_layout, uint32_t width,
27                      uint32_t height, uint32_t nr_samples);
28 ENDC;
29 
30 #ifdef __cplusplus
31 #include "common/freedreno_lrz.h"
32 
33 template <chip CHIP>
34 static void
fdl6_lrz_layout_init(struct fdl_lrz_layout * lrz_layout,struct fdl_layout * layout,const struct fd_dev_info * dev_info,uint32_t lrz_offset,uint32_t array_layers)35 fdl6_lrz_layout_init(struct fdl_lrz_layout *lrz_layout,
36                      struct fdl_layout *layout,
37                      const struct fd_dev_info *dev_info, uint32_t lrz_offset,
38                      uint32_t array_layers)
39 {
40    unsigned width = layout->width0;
41    unsigned height = layout->height0;
42 
43    /* LRZ buffer is super-sampled */
44    switch (layout->nr_samples) {
45    case 8:
46       height *= 2;
47       FALLTHROUGH;
48    case 4:
49       width *= 2;
50       FALLTHROUGH;
51    case 2:
52       height *= 2;
53       break;
54    default:
55       break;
56    }
57 
58    unsigned lrz_pitch = align(DIV_ROUND_UP(width, 8), 32);
59    unsigned lrz_height = align(DIV_ROUND_UP(height, 8), 32);
60 
61    lrz_layout->lrz_offset = lrz_offset;
62    lrz_layout->lrz_height = lrz_height;
63    lrz_layout->lrz_pitch = lrz_pitch;
64    lrz_layout->lrz_layer_size = lrz_pitch * lrz_height * sizeof(uint16_t);
65 
66    unsigned nblocksx = DIV_ROUND_UP(DIV_ROUND_UP(width, 8), 16);
67    unsigned nblocksy = DIV_ROUND_UP(DIV_ROUND_UP(height, 8), 4);
68 
69    /* Fast-clear buffer is 1bit/block */
70    lrz_layout->lrz_fc_size =
71       DIV_ROUND_UP(nblocksx * nblocksy, 8) * array_layers;
72 
73    /* Fast-clear buffer cannot be larger than 512 bytes on A6XX and 1024 bytes
74     * on A7XX (HW limitation) */
75    if (!dev_info->a6xx.enable_lrz_fast_clear ||
76        lrz_layout->lrz_fc_size > fd_lrzfc_layout<CHIP>::FC_SIZE) {
77       lrz_layout->lrz_fc_size = 0;
78    }
79 
80    uint32_t lrz_size = lrz_layout->lrz_layer_size * array_layers;
81    if (dev_info->a6xx.enable_lrz_fast_clear ||
82        dev_info->a6xx.has_lrz_dir_tracking) {
83       lrz_layout->lrz_fc_offset =
84          lrz_layout->lrz_offset + lrz_size;
85       lrz_size += sizeof(fd_lrzfc_layout<CHIP>);
86    }
87 
88    lrz_layout->lrz_total_size = lrz_size;
89 
90    uint32_t lrz_clear_height = lrz_layout->lrz_height * array_layers;
91    if (((lrz_clear_height - 1) >> 14) > 0) {
92       /* For simplicity bail out if LRZ cannot be cleared in one go. */
93       lrz_layout->lrz_height = 0;
94       lrz_layout->lrz_total_size = 0;
95    }
96 }
97 #endif
98 
99 #endif
100