• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static const struct gmem_key keys[] = {
36 	{ .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,}},
37 	/* manhattan: */
38 	{ .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,}},
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 = {4,0,}},
40 //	{ .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,}},
41 //	{ .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,}},
42 //	{ .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,}},
43 //	{ .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,}},
44 //	{ .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,}},
45 //	{ .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,}},
46 //	{ .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,}},
47 	{ .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,}},
48 //	{ .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,}},
49 	{ .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,}},
50 	{ .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,}},
51 	{ .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,}},
52 	{ .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,}},
53 //	{ .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,}},
54 //	{ .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,}},
55 
56 	/* trex: */
57 	{ .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,}},
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 = {4,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 = {2,0,}},
60 	{ .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,}},
61 	{ .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,}},
62 //	{ .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,}},
63 
64 	/* supertuxkart: */
65 	{ .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,}},
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 = {2,0,}},
67 	{ .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,}},
68 //	{ .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,}},
69 	{ .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,}},
70 	{ .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,}},
71 	{ .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,}},
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 = {0,0,}},
73 	{ .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,}},
74 	{ .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,}},
75 	{ .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,}},
76 	{ .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,}},
77 	{ .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,}},
78 	{ .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,}},
79 };
80 
81 struct gpu_info {
82 	const char *name;
83 	uint32_t gpu_id;
84 	uint8_t  gmem_page_align;
85 	uint32_t gmemsize_bytes;
86 };
87 
88 #define SZ_128K  0x00020000
89 #define SZ_256K  0x00040000
90 #define SZ_512K  0x00080000
91 #define SZ_1M    0x00100000
92 
93 /* keep sorted by gpu name: */
94 static const struct gpu_info gpu_infos[] = {
95 	{ "a306", 307, 4, SZ_128K },
96 	{ "a405", 405, 4, SZ_256K },
97 	{ "a530", 530, 4, SZ_1M   },
98 	{ "a618", 618, 1, SZ_512K },
99 	{ "a630", 630, 1, SZ_1M   },
100 	{ "a650", 630, 1, SZ_1M + SZ_128K },
101 };
102 
103 
104 static const struct option opts[] = {
105 	{ .name = "gpu",     .has_arg = 1, NULL, 'g' },
106 	{ .name = "help",    .has_arg = 0, NULL, 'h' },
107 	{ .name = "verbose", .has_arg = 0, NULL, 'v' },
108 	{}
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 for the specified GPU\n"
118 			"\t-h, --help      - this usage message\n"
119 			"\t-v, --verbose   - dump more verbose output\n"
120 			"\n"
121 		);
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 	/* Setup a fake screen with enough GMEM related configuration
163 	 * to make gmem_stateobj_init() happy:
164 	 */
165 	struct fd_screen screen = {
166 		.gpu_id         = gpu_info->gpu_id,
167 		.gmemsize_bytes = gpu_info->gmemsize_bytes,
168 	};
169 
170 	freedreno_dev_info_init(&screen.info, gpu_info->gpu_id);
171 
172 	/* And finally run thru all the GMEM keys: */
173 	for (int i = 0; i < ARRAY_SIZE(keys); i++) {
174 		struct gmem_key key = keys[i];
175 		key.gmem_page_align = gpu_info->gmem_page_align;
176 		struct fd_gmem_stateobj *gmem = gmem_stateobj_init(&screen, &key);
177 		dump_gmem_state(gmem);
178 
179 		assert((gmem->bin_w * gmem->nbins_x) >= key.width);
180 		assert((gmem->bin_h * gmem->nbins_y) >= key.height);
181 		assert(gmem->bin_w < screen.info.tile_max_w);
182 		assert(gmem->bin_h < screen.info.tile_max_h);
183 
184 		ralloc_free(gmem);
185 	}
186 
187 	return 0;
188 }
189