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