1 /*
2  * Copyright © 2020 Google, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include <getopt.h>
25 #include <stdbool.h>
26 
27 static bool bin_debug = false;
28 #define BIN_DEBUG bin_debug
29 
30 #include "freedreno_gmem.c"
31 
32 /* NOTE, non-interesting gmem keys (ie. things that are small enough to fit
33  * in a single bin) are commented out, but retained for posterity.
34  */
35 /* clang-format off */
36 static const struct gmem_key keys[] = {
37    { .minx=0, .miny=0, .width=1536, .height=2048, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {1,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
38    /* manhattan: */
39    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
40    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
41 // { .minx=0, .miny=0, .width=64, .height=64, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
42 // { .minx=0, .miny=0, .width=32, .height=32, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
43 // { .minx=0, .miny=0, .width=16, .height=16, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
44 // { .minx=0, .miny=0, .width=8, .height=8, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
45 // { .minx=0, .miny=0, .width=4, .height=4, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
46 // { .minx=0, .miny=0, .width=2, .height=2, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
47 // { .minx=0, .miny=0, .width=1, .height=1, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
48    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=4, .cbuf_cpp = {4,4,4,4,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
49 // { .minx=0, .miny=0, .width=64, .height=64, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {2,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
50    { .minx=0, .miny=0, .width=1024, .height=1024, .gmem_page_align=1, .nr_cbufs=0, .cbuf_cpp = {0,0,0,0,0,0,0,0,}, .zsbuf_cpp = {2,0,}},
51    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=0, .cbuf_cpp = {0,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
52    { .minx=0, .miny=0, .width=960, .height=540, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
53    { .minx=0, .miny=0, .width=480, .height=270, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
54 // { .minx=0, .miny=0, .width=240, .height=135, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
55 // { .minx=0, .miny=0, .width=120, .height=67, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
56 
57    /* trex: */
58    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
59    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
60    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {2,0,}},
61    { .minx=0, .miny=0, .width=960, .height=540, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {2,0,0,0,0,0,0,0,}, .zsbuf_cpp = {2,0,}},
62    { .minx=0, .miny=0, .width=1024, .height=1024, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {2,0,}},
63 // { .minx=0, .miny=0, .width=64, .height=64, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {2,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
64 
65    /* supertuxkart: */
66    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
67    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {2,0,}},
68    { .minx=0, .miny=0, .width=810, .height=810, .gmem_page_align=1, .nr_cbufs=2, .cbuf_cpp = {4,4,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
69 // { .minx=0, .miny=0, .width=405, .height=405, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {2,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
70    { .minx=0, .miny=0, .width=405, .height=405, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {8,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
71    { .minx=0, .miny=0, .width=810, .height=810, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {8,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
72    { .minx=0, .miny=0, .width=810, .height=810, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
73    { .minx=0, .miny=0, .width=810, .height=810, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
74    { .minx=0, .miny=0, .width=960, .height=540, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {2,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
75    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {8,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
76    { .minx=0, .miny=0, .width=960, .height=540, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {8,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}},
77    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=2, .cbuf_cpp = {4,4,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
78    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {8,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
79    { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}},
80 };
81 /* clang-format on */
82 
83 struct gpu_info {
84    const char *name;
85    uint32_t gpu_id;
86    uint8_t gmem_page_align;
87    uint32_t gmemsize_bytes;
88 };
89 
90 #define SZ_128K 0x00020000
91 #define SZ_256K 0x00040000
92 #define SZ_512K 0x00080000
93 #define SZ_1M   0x00100000
94 
95 /* keep sorted by gpu name: */
96 static const struct gpu_info gpu_infos[] = {
97    {"a306", 307, 4, SZ_128K},
98    {"a405", 405, 4, SZ_256K},
99    {"a530", 530, 4, SZ_1M},
100    {"a618", 618, 1, SZ_512K},
101    {"a630", 630, 1, SZ_1M},
102    {"a650", 630, 1, SZ_1M + SZ_128K},
103 };
104 
105 static const struct option opts[] = {
106    {.name = "gpu",     .has_arg = 1, NULL, 'g'},
107    {.name = "help",    .has_arg = 0, NULL, 'h'},
108    {.name = "verbose", .has_arg = 0, NULL, 'v'},
109    {}};
110 
111 static void
usage(void)112 usage(void)
113 {
114    fprintf(stderr, "Usage:\n\n"
115                    "\tgmemtool [-hv] [-g GPU]\n\n"
116                    "Options:\n"
117                    "\t-g, --gpu=GPU   - use GMEM size/alignment/etc settings "
118                    "for the specified GPU\n"
119                    "\t-h, --help      - this usage message\n"
120                    "\t-v, --verbose   - dump more verbose output\n"
121                    "\n");
122    fprintf(stderr, "Where GPU is one of:\n");
123    for (int i = 0; i < ARRAY_SIZE(gpu_infos); i++)
124       fprintf(stderr, "\t%s\n", gpu_infos[i].name);
125    exit(2);
126 }
127 
128 int
main(int argc,char ** argv)129 main(int argc, char **argv)
130 {
131    const char *gpu_name = "a630";
132    int c;
133 
134    while ((c = getopt_long(argc, argv, "g:hv", opts, NULL)) != -1) {
135       switch (c) {
136       case 'g':
137          gpu_name = optarg;
138          break;
139       case 'v':
140          bin_debug = true;
141          break;
142       case 'h':
143       default:
144          usage();
145       }
146    }
147 
148    const struct gpu_info *gpu_info = NULL;
149 
150    for (int i = 0; i < ARRAY_SIZE(gpu_infos); i++) {
151       if (strcmp(gpu_name, gpu_infos[i].name) == 0) {
152          gpu_info = &gpu_infos[i];
153          break;
154       }
155    }
156 
157    if (!gpu_info) {
158       printf("unrecognized gpu name: %s\n", gpu_name);
159       usage();
160    }
161 
162    struct fd_dev_id dev_id = {
163          .gpu_id = gpu_info->gpu_id,
164    };
165    /* Setup a fake screen with enough GMEM related configuration
166     * to make gmem_stateobj_init() happy:
167     */
168    struct fd_screen screen = {
169       .dev_id = &dev_id,
170       .gmemsize_bytes = gpu_info->gmemsize_bytes,
171    };
172 
173    screen.info = fd_dev_info(&dev_id);
174 
175    /* And finally run thru all the GMEM keys: */
176    for (int i = 0; i < ARRAY_SIZE(keys); i++) {
177       struct gmem_key key = keys[i];
178       key.gmem_page_align = gpu_info->gmem_page_align;
179       struct fd_gmem_stateobj *gmem = gmem_stateobj_init(&screen, &key);
180       dump_gmem_state(gmem);
181 
182       assert((gmem->bin_w * gmem->nbins_x) >= key.width);
183       assert((gmem->bin_h * gmem->nbins_y) >= key.height);
184       assert(gmem->bin_w < screen.info->tile_max_w);
185       assert(gmem->bin_h < screen.info->tile_max_h);
186 
187       ralloc_free(gmem);
188    }
189 
190    return 0;
191 }
192