xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/freedreno/a3xx/fd3_resource.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2012 Rob Clark <[email protected]>
3  * Copyright © 2019 Khaled Emara <[email protected]>
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "fd3_resource.h"
8 #include "fd3_format.h"
9 
10 static uint32_t
setup_slices(struct fd_resource * rsc,uint32_t alignment,enum pipe_format format)11 setup_slices(struct fd_resource *rsc, uint32_t alignment,
12              enum pipe_format format)
13 {
14    struct pipe_resource *prsc = &rsc->b.b;
15    uint32_t level, size = 0;
16 
17    /* 32 pixel alignment */
18    fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5);
19 
20    for (level = 0; level <= prsc->last_level; level++) {
21       struct fdl_slice *slice = fd_resource_slice(rsc, level);
22       uint32_t pitch = fdl_pitch(&rsc->layout, level);
23       uint32_t height = u_minify(prsc->height0, level);
24       if (rsc->layout.tile_mode) {
25          height = align(height, 4);
26          if (prsc->target != PIPE_TEXTURE_CUBE)
27             height = util_next_power_of_two(height);
28       }
29 
30       uint32_t nblocksy = util_format_get_nblocksy(format, height);
31 
32       slice->offset = size;
33       /* 1d array and 2d array textures must all have the same layer size
34        * for each miplevel on a3xx. 3d textures can have different layer
35        * sizes for high levels, but the hw auto-sizer is buggy (or at least
36        * different than what this code does), so as soon as the layer size
37        * range gets into range, we stop reducing it.
38        */
39       if (prsc->target == PIPE_TEXTURE_3D &&
40           (level == 1 ||
41            (level > 1 && fd_resource_slice(rsc, level - 1)->size0 > 0xf000)))
42          slice->size0 = align(nblocksy * pitch, alignment);
43       else if (level == 0 || alignment == 1)
44          slice->size0 = align(nblocksy * pitch, alignment);
45       else
46          slice->size0 = fd_resource_slice(rsc, level - 1)->size0;
47 
48       size += slice->size0 * u_minify(prsc->depth0, level) * prsc->array_size;
49    }
50 
51    return size;
52 }
53 
54 uint32_t
fd3_setup_slices(struct fd_resource * rsc)55 fd3_setup_slices(struct fd_resource *rsc)
56 {
57    uint32_t alignment;
58 
59    switch (rsc->b.b.target) {
60    case PIPE_TEXTURE_3D:
61    case PIPE_TEXTURE_1D_ARRAY:
62    case PIPE_TEXTURE_2D_ARRAY:
63       alignment = 4096;
64       break;
65    default:
66       alignment = 1;
67       break;
68    }
69 
70    return setup_slices(rsc, alignment, rsc->b.b.format);
71 }
72 
73 static bool
ok_format(enum pipe_format pfmt)74 ok_format(enum pipe_format pfmt)
75 {
76    enum a3xx_color_fmt fmt = fd3_pipe2color(pfmt);
77 
78    if (fmt == RB_NONE)
79       return false;
80 
81    switch (pfmt) {
82    case PIPE_FORMAT_R8_UINT:
83    case PIPE_FORMAT_R8_SINT:
84    case PIPE_FORMAT_Z32_FLOAT:
85       return false;
86    default:
87       break;
88    }
89 
90    return true;
91 }
92 
93 unsigned
fd3_tile_mode(const struct pipe_resource * tmpl)94 fd3_tile_mode(const struct pipe_resource *tmpl)
95 {
96    if (ok_format(tmpl->format))
97       return TILE_4X4;
98    return LINEAR;
99 }
100