1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #include "tu_util.h"
7*61046927SAndroid Build Coastguard Worker
8*61046927SAndroid Build Coastguard Worker #include <errno.h>
9*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "common/freedreno_rd_output.h"
12*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
13*61046927SAndroid Build Coastguard Worker #include "util/timespec.h"
14*61046927SAndroid Build Coastguard Worker #include "vk_enum_to_str.h"
15*61046927SAndroid Build Coastguard Worker
16*61046927SAndroid Build Coastguard Worker #include "tu_device.h"
17*61046927SAndroid Build Coastguard Worker #include "tu_pass.h"
18*61046927SAndroid Build Coastguard Worker
19*61046927SAndroid Build Coastguard Worker static const struct debug_control tu_debug_options[] = {
20*61046927SAndroid Build Coastguard Worker { "startup", TU_DEBUG_STARTUP },
21*61046927SAndroid Build Coastguard Worker { "nir", TU_DEBUG_NIR },
22*61046927SAndroid Build Coastguard Worker { "nobin", TU_DEBUG_NOBIN },
23*61046927SAndroid Build Coastguard Worker { "sysmem", TU_DEBUG_SYSMEM },
24*61046927SAndroid Build Coastguard Worker { "gmem", TU_DEBUG_GMEM },
25*61046927SAndroid Build Coastguard Worker { "forcebin", TU_DEBUG_FORCEBIN },
26*61046927SAndroid Build Coastguard Worker { "layout", TU_DEBUG_LAYOUT },
27*61046927SAndroid Build Coastguard Worker { "noubwc", TU_DEBUG_NOUBWC },
28*61046927SAndroid Build Coastguard Worker { "nomultipos", TU_DEBUG_NOMULTIPOS },
29*61046927SAndroid Build Coastguard Worker { "nolrz", TU_DEBUG_NOLRZ },
30*61046927SAndroid Build Coastguard Worker { "nolrzfc", TU_DEBUG_NOLRZFC },
31*61046927SAndroid Build Coastguard Worker { "perf", TU_DEBUG_PERF },
32*61046927SAndroid Build Coastguard Worker { "perfc", TU_DEBUG_PERFC },
33*61046927SAndroid Build Coastguard Worker { "flushall", TU_DEBUG_FLUSHALL },
34*61046927SAndroid Build Coastguard Worker { "syncdraw", TU_DEBUG_SYNCDRAW },
35*61046927SAndroid Build Coastguard Worker { "push_consts_per_stage", TU_DEBUG_PUSH_CONSTS_PER_STAGE },
36*61046927SAndroid Build Coastguard Worker { "rast_order", TU_DEBUG_RAST_ORDER },
37*61046927SAndroid Build Coastguard Worker { "unaligned_store", TU_DEBUG_UNALIGNED_STORE },
38*61046927SAndroid Build Coastguard Worker { "log_skip_gmem_ops", TU_DEBUG_LOG_SKIP_GMEM_OPS },
39*61046927SAndroid Build Coastguard Worker { "dynamic", TU_DEBUG_DYNAMIC },
40*61046927SAndroid Build Coastguard Worker { "bos", TU_DEBUG_BOS },
41*61046927SAndroid Build Coastguard Worker { "3d_load", TU_DEBUG_3D_LOAD },
42*61046927SAndroid Build Coastguard Worker { "fdm", TU_DEBUG_FDM },
43*61046927SAndroid Build Coastguard Worker { "noconform", TU_DEBUG_NOCONFORM },
44*61046927SAndroid Build Coastguard Worker { "rd", TU_DEBUG_RD },
45*61046927SAndroid Build Coastguard Worker { NULL, 0 }
46*61046927SAndroid Build Coastguard Worker };
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker struct tu_env tu_env;
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker static void
tu_env_init_once(void)51*61046927SAndroid Build Coastguard Worker tu_env_init_once(void)
52*61046927SAndroid Build Coastguard Worker {
53*61046927SAndroid Build Coastguard Worker tu_env.debug = parse_debug_string(os_get_option("TU_DEBUG"),
54*61046927SAndroid Build Coastguard Worker tu_debug_options);
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(STARTUP))
57*61046927SAndroid Build Coastguard Worker mesa_logi("TU_DEBUG=0x%x", tu_env.debug);
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker /* TU_DEBUG=rd functionality was moved to fd_rd_output. This debug option
60*61046927SAndroid Build Coastguard Worker * should translate to the basic-level FD_RD_DUMP_ENABLE option.
61*61046927SAndroid Build Coastguard Worker */
62*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(RD))
63*61046927SAndroid Build Coastguard Worker fd_rd_dump_env.flags |= FD_RD_DUMP_ENABLE;
64*61046927SAndroid Build Coastguard Worker }
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker void
tu_env_init(void)67*61046927SAndroid Build Coastguard Worker tu_env_init(void)
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker fd_rd_dump_env_init();
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker static once_flag once = ONCE_FLAG_INIT;
72*61046927SAndroid Build Coastguard Worker call_once(&once, tu_env_init_once);
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker
75*61046927SAndroid Build Coastguard Worker void PRINTFLIKE(3, 4)
__tu_finishme(const char * file,int line,const char * format,...)76*61046927SAndroid Build Coastguard Worker __tu_finishme(const char *file, int line, const char *format, ...)
77*61046927SAndroid Build Coastguard Worker {
78*61046927SAndroid Build Coastguard Worker va_list ap;
79*61046927SAndroid Build Coastguard Worker char buffer[256];
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker va_start(ap, format);
82*61046927SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), format, ap);
83*61046927SAndroid Build Coastguard Worker va_end(ap);
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker mesa_loge("%s:%d: FINISHME: %s\n", file, line, buffer);
86*61046927SAndroid Build Coastguard Worker }
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker VkResult
__vk_startup_errorf(struct tu_instance * instance,VkResult error,const char * file,int line,const char * format,...)89*61046927SAndroid Build Coastguard Worker __vk_startup_errorf(struct tu_instance *instance,
90*61046927SAndroid Build Coastguard Worker VkResult error,
91*61046927SAndroid Build Coastguard Worker const char *file,
92*61046927SAndroid Build Coastguard Worker int line,
93*61046927SAndroid Build Coastguard Worker const char *format,
94*61046927SAndroid Build Coastguard Worker ...)
95*61046927SAndroid Build Coastguard Worker {
96*61046927SAndroid Build Coastguard Worker va_list ap;
97*61046927SAndroid Build Coastguard Worker char buffer[256];
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker const char *error_str = vk_Result_to_str(error);
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker if (format) {
102*61046927SAndroid Build Coastguard Worker va_start(ap, format);
103*61046927SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), format, ap);
104*61046927SAndroid Build Coastguard Worker va_end(ap);
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker mesa_loge("%s:%d: %s (%s)\n", file, line, buffer, error_str);
107*61046927SAndroid Build Coastguard Worker } else {
108*61046927SAndroid Build Coastguard Worker mesa_loge("%s:%d: %s\n", file, line, error_str);
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker return error;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker static void
tu_tiling_config_update_tile_layout(struct tu_framebuffer * fb,const struct tu_device * dev,const struct tu_render_pass * pass,enum tu_gmem_layout gmem_layout)115*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_tile_layout(struct tu_framebuffer *fb,
116*61046927SAndroid Build Coastguard Worker const struct tu_device *dev,
117*61046927SAndroid Build Coastguard Worker const struct tu_render_pass *pass,
118*61046927SAndroid Build Coastguard Worker enum tu_gmem_layout gmem_layout)
119*61046927SAndroid Build Coastguard Worker {
120*61046927SAndroid Build Coastguard Worker const uint32_t tile_align_w = pass->tile_align_w;
121*61046927SAndroid Build Coastguard Worker uint32_t tile_align_h = dev->physical_device->info->tile_align_h;
122*61046927SAndroid Build Coastguard Worker struct tu_tiling_config *tiling = &fb->tiling[gmem_layout];
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.3.232 spec, under VkFramebufferCreateInfo:
125*61046927SAndroid Build Coastguard Worker *
126*61046927SAndroid Build Coastguard Worker * If the render pass uses multiview, then layers must be one and each
127*61046927SAndroid Build Coastguard Worker * attachment requires a number of layers that is greater than the
128*61046927SAndroid Build Coastguard Worker * maximum bit index set in the view mask in the subpasses in which it is
129*61046927SAndroid Build Coastguard Worker * used.
130*61046927SAndroid Build Coastguard Worker */
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker uint32_t layers = MAX2(fb->layers, pass->num_views);
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker /* If there is more than one layer, we need to make sure that the layer
135*61046927SAndroid Build Coastguard Worker * stride is expressible as an offset in RB_BLIT_BASE_GMEM which ignores
136*61046927SAndroid Build Coastguard Worker * the low 12 bits. The layer stride seems to be implicitly calculated from
137*61046927SAndroid Build Coastguard Worker * the tile width and height so we need to adjust one of them.
138*61046927SAndroid Build Coastguard Worker */
139*61046927SAndroid Build Coastguard Worker const uint32_t gmem_align_log2 = 12;
140*61046927SAndroid Build Coastguard Worker const uint32_t gmem_align = 1 << gmem_align_log2;
141*61046927SAndroid Build Coastguard Worker uint32_t min_layer_stride = tile_align_h * tile_align_w * pass->min_cpp;
142*61046927SAndroid Build Coastguard Worker if (layers > 1 && align(min_layer_stride, gmem_align) != min_layer_stride) {
143*61046927SAndroid Build Coastguard Worker /* Make sure that min_layer_stride is a multiple of gmem_align. Because
144*61046927SAndroid Build Coastguard Worker * gmem_align is a power of two and min_layer_stride isn't already a
145*61046927SAndroid Build Coastguard Worker * multiple of gmem_align, this is equivalent to shifting tile_align_h
146*61046927SAndroid Build Coastguard Worker * until the number of 0 bits at the bottom of min_layer_stride is at
147*61046927SAndroid Build Coastguard Worker * least gmem_align_log2.
148*61046927SAndroid Build Coastguard Worker */
149*61046927SAndroid Build Coastguard Worker tile_align_h <<= gmem_align_log2 - (ffs(min_layer_stride) - 1);
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker /* Check that we did the math right. */
152*61046927SAndroid Build Coastguard Worker min_layer_stride = tile_align_h * tile_align_w * pass->min_cpp;
153*61046927SAndroid Build Coastguard Worker assert(align(min_layer_stride, gmem_align) == min_layer_stride);
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker /* will force to sysmem, don't bother trying to have a valid tile config
157*61046927SAndroid Build Coastguard Worker * TODO: just skip all GMEM stuff when sysmem is forced?
158*61046927SAndroid Build Coastguard Worker */
159*61046927SAndroid Build Coastguard Worker if (!pass->gmem_pixels[gmem_layout]) {
160*61046927SAndroid Build Coastguard Worker tiling->possible = false;
161*61046927SAndroid Build Coastguard Worker /* Put in dummy values that will assertion fail in register setup using
162*61046927SAndroid Build Coastguard Worker * them, since you shouldn't be doing gmem work if gmem is not possible.
163*61046927SAndroid Build Coastguard Worker */
164*61046927SAndroid Build Coastguard Worker tiling->tile_count = (VkExtent2D) { 1, 1 };
165*61046927SAndroid Build Coastguard Worker tiling->tile0 = (VkExtent2D) { ~0, ~0 };
166*61046927SAndroid Build Coastguard Worker return;
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker tiling->possible = false;
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker uint32_t best_tile_count = ~0;
172*61046927SAndroid Build Coastguard Worker VkExtent2D tile_count;
173*61046927SAndroid Build Coastguard Worker VkExtent2D tile_size;
174*61046927SAndroid Build Coastguard Worker /* There aren't that many different tile widths possible, so just walk all
175*61046927SAndroid Build Coastguard Worker * of them finding which produces the lowest number of bins.
176*61046927SAndroid Build Coastguard Worker */
177*61046927SAndroid Build Coastguard Worker const uint32_t max_tile_width = MIN2(
178*61046927SAndroid Build Coastguard Worker dev->physical_device->info->tile_max_w, util_align_npot(fb->width, tile_align_w));
179*61046927SAndroid Build Coastguard Worker const uint32_t max_tile_height =
180*61046927SAndroid Build Coastguard Worker MIN2(dev->physical_device->info->tile_max_h,
181*61046927SAndroid Build Coastguard Worker align(fb->height, tile_align_h));
182*61046927SAndroid Build Coastguard Worker for (tile_size.width = tile_align_w; tile_size.width <= max_tile_width;
183*61046927SAndroid Build Coastguard Worker tile_size.width += tile_align_w) {
184*61046927SAndroid Build Coastguard Worker tile_size.height = pass->gmem_pixels[gmem_layout] / (tile_size.width * layers);
185*61046927SAndroid Build Coastguard Worker tile_size.height = MIN2(tile_size.height, max_tile_height);
186*61046927SAndroid Build Coastguard Worker tile_size.height = ROUND_DOWN_TO(tile_size.height, tile_align_h);
187*61046927SAndroid Build Coastguard Worker if (!tile_size.height)
188*61046927SAndroid Build Coastguard Worker continue;
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker tile_count.width = DIV_ROUND_UP(fb->width, tile_size.width);
191*61046927SAndroid Build Coastguard Worker tile_count.height = DIV_ROUND_UP(fb->height, tile_size.height);
192*61046927SAndroid Build Coastguard Worker
193*61046927SAndroid Build Coastguard Worker /* Drop the height of the tile down to split tiles more evenly across the
194*61046927SAndroid Build Coastguard Worker * screen for a given tile count.
195*61046927SAndroid Build Coastguard Worker */
196*61046927SAndroid Build Coastguard Worker tile_size.height =
197*61046927SAndroid Build Coastguard Worker align(DIV_ROUND_UP(fb->height, tile_count.height), tile_align_h);
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker /* Pick the layout with the minimum number of bins (lowest CP overhead
200*61046927SAndroid Build Coastguard Worker * and amount of cache flushing), but the most square tiles in the case
201*61046927SAndroid Build Coastguard Worker * of a tie (likely highest cache locality).
202*61046927SAndroid Build Coastguard Worker */
203*61046927SAndroid Build Coastguard Worker if (tile_count.width * tile_count.height < best_tile_count ||
204*61046927SAndroid Build Coastguard Worker (tile_count.width * tile_count.height == best_tile_count &&
205*61046927SAndroid Build Coastguard Worker abs((int)(tile_size.width - tile_size.height)) <
206*61046927SAndroid Build Coastguard Worker abs((int)(tiling->tile0.width - tiling->tile0.height)))) {
207*61046927SAndroid Build Coastguard Worker tiling->possible = true;
208*61046927SAndroid Build Coastguard Worker tiling->tile0 = tile_size;
209*61046927SAndroid Build Coastguard Worker tiling->tile_count = tile_count;
210*61046927SAndroid Build Coastguard Worker best_tile_count = tile_count.width * tile_count.height;
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker /* If forcing binning, try to get at least 2 tiles in each direction. */
215*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(FORCEBIN) && tiling->possible) {
216*61046927SAndroid Build Coastguard Worker if (tiling->tile_count.width == 1 && tiling->tile0.width != tile_align_w) {
217*61046927SAndroid Build Coastguard Worker tiling->tile0.width = util_align_npot(DIV_ROUND_UP(tiling->tile0.width, 2), tile_align_w);
218*61046927SAndroid Build Coastguard Worker tiling->tile_count.width = 2;
219*61046927SAndroid Build Coastguard Worker }
220*61046927SAndroid Build Coastguard Worker if (tiling->tile_count.height == 1 && tiling->tile0.height != tile_align_h) {
221*61046927SAndroid Build Coastguard Worker tiling->tile0.height = align(DIV_ROUND_UP(tiling->tile0.height, 2), tile_align_h);
222*61046927SAndroid Build Coastguard Worker tiling->tile_count.height = 2;
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker }
225*61046927SAndroid Build Coastguard Worker }
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker static void
tu_tiling_config_update_pipe_layout(struct tu_tiling_config * tiling,const struct tu_device * dev)228*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_pipe_layout(struct tu_tiling_config *tiling,
229*61046927SAndroid Build Coastguard Worker const struct tu_device *dev)
230*61046927SAndroid Build Coastguard Worker {
231*61046927SAndroid Build Coastguard Worker const uint32_t max_pipe_count =
232*61046927SAndroid Build Coastguard Worker dev->physical_device->info->num_vsc_pipes;
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker /* start from 1 tile per pipe */
235*61046927SAndroid Build Coastguard Worker tiling->pipe0 = (VkExtent2D) {
236*61046927SAndroid Build Coastguard Worker .width = 1,
237*61046927SAndroid Build Coastguard Worker .height = 1,
238*61046927SAndroid Build Coastguard Worker };
239*61046927SAndroid Build Coastguard Worker tiling->pipe_count = tiling->tile_count;
240*61046927SAndroid Build Coastguard Worker
241*61046927SAndroid Build Coastguard Worker while (tiling->pipe_count.width * tiling->pipe_count.height > max_pipe_count) {
242*61046927SAndroid Build Coastguard Worker if (tiling->pipe0.width < tiling->pipe0.height) {
243*61046927SAndroid Build Coastguard Worker tiling->pipe0.width += 1;
244*61046927SAndroid Build Coastguard Worker tiling->pipe_count.width =
245*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(tiling->tile_count.width, tiling->pipe0.width);
246*61046927SAndroid Build Coastguard Worker } else {
247*61046927SAndroid Build Coastguard Worker tiling->pipe0.height += 1;
248*61046927SAndroid Build Coastguard Worker tiling->pipe_count.height =
249*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(tiling->tile_count.height, tiling->pipe0.height);
250*61046927SAndroid Build Coastguard Worker }
251*61046927SAndroid Build Coastguard Worker }
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker static void
tu_tiling_config_update_pipes(struct tu_tiling_config * tiling,const struct tu_device * dev)255*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_pipes(struct tu_tiling_config *tiling,
256*61046927SAndroid Build Coastguard Worker const struct tu_device *dev)
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker const uint32_t max_pipe_count =
259*61046927SAndroid Build Coastguard Worker dev->physical_device->info->num_vsc_pipes;
260*61046927SAndroid Build Coastguard Worker const uint32_t used_pipe_count =
261*61046927SAndroid Build Coastguard Worker tiling->pipe_count.width * tiling->pipe_count.height;
262*61046927SAndroid Build Coastguard Worker const VkExtent2D last_pipe = {
263*61046927SAndroid Build Coastguard Worker .width = (tiling->tile_count.width - 1) % tiling->pipe0.width + 1,
264*61046927SAndroid Build Coastguard Worker .height = (tiling->tile_count.height - 1) % tiling->pipe0.height + 1,
265*61046927SAndroid Build Coastguard Worker };
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker assert(used_pipe_count <= max_pipe_count);
268*61046927SAndroid Build Coastguard Worker assert(max_pipe_count <= ARRAY_SIZE(tiling->pipe_config));
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker for (uint32_t y = 0; y < tiling->pipe_count.height; y++) {
271*61046927SAndroid Build Coastguard Worker for (uint32_t x = 0; x < tiling->pipe_count.width; x++) {
272*61046927SAndroid Build Coastguard Worker const uint32_t pipe_x = tiling->pipe0.width * x;
273*61046927SAndroid Build Coastguard Worker const uint32_t pipe_y = tiling->pipe0.height * y;
274*61046927SAndroid Build Coastguard Worker const uint32_t pipe_w = (x == tiling->pipe_count.width - 1)
275*61046927SAndroid Build Coastguard Worker ? last_pipe.width
276*61046927SAndroid Build Coastguard Worker : tiling->pipe0.width;
277*61046927SAndroid Build Coastguard Worker const uint32_t pipe_h = (y == tiling->pipe_count.height - 1)
278*61046927SAndroid Build Coastguard Worker ? last_pipe.height
279*61046927SAndroid Build Coastguard Worker : tiling->pipe0.height;
280*61046927SAndroid Build Coastguard Worker const uint32_t n = tiling->pipe_count.width * y + x;
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker tiling->pipe_config[n] = A6XX_VSC_PIPE_CONFIG_REG_X(pipe_x) |
283*61046927SAndroid Build Coastguard Worker A6XX_VSC_PIPE_CONFIG_REG_Y(pipe_y) |
284*61046927SAndroid Build Coastguard Worker A6XX_VSC_PIPE_CONFIG_REG_W(pipe_w) |
285*61046927SAndroid Build Coastguard Worker A6XX_VSC_PIPE_CONFIG_REG_H(pipe_h);
286*61046927SAndroid Build Coastguard Worker tiling->pipe_sizes[n] = CP_SET_BIN_DATA5_0_VSC_SIZE(pipe_w * pipe_h);
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker memset(tiling->pipe_config + used_pipe_count, 0,
291*61046927SAndroid Build Coastguard Worker sizeof(uint32_t) * (max_pipe_count - used_pipe_count));
292*61046927SAndroid Build Coastguard Worker }
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker static bool
is_hw_binning_possible(const struct tu_tiling_config * tiling)295*61046927SAndroid Build Coastguard Worker is_hw_binning_possible(const struct tu_tiling_config *tiling)
296*61046927SAndroid Build Coastguard Worker {
297*61046927SAndroid Build Coastguard Worker /* Similar to older gens, # of tiles per pipe cannot be more than 32.
298*61046927SAndroid Build Coastguard Worker * But there are no hangs with 16 or more tiles per pipe in either
299*61046927SAndroid Build Coastguard Worker * X or Y direction, so that limit does not seem to apply.
300*61046927SAndroid Build Coastguard Worker */
301*61046927SAndroid Build Coastguard Worker uint32_t tiles_per_pipe = tiling->pipe0.width * tiling->pipe0.height;
302*61046927SAndroid Build Coastguard Worker return tiles_per_pipe <= 32;
303*61046927SAndroid Build Coastguard Worker }
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker static void
tu_tiling_config_update_binning(struct tu_tiling_config * tiling,const struct tu_device * device)306*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_binning(struct tu_tiling_config *tiling, const struct tu_device *device)
307*61046927SAndroid Build Coastguard Worker {
308*61046927SAndroid Build Coastguard Worker tiling->binning_possible = is_hw_binning_possible(tiling);
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker if (tiling->binning_possible) {
311*61046927SAndroid Build Coastguard Worker tiling->binning = (tiling->tile_count.width * tiling->tile_count.height) > 2;
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(FORCEBIN))
314*61046927SAndroid Build Coastguard Worker tiling->binning = true;
315*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(NOBIN))
316*61046927SAndroid Build Coastguard Worker tiling->binning = false;
317*61046927SAndroid Build Coastguard Worker } else {
318*61046927SAndroid Build Coastguard Worker tiling->binning = false;
319*61046927SAndroid Build Coastguard Worker }
320*61046927SAndroid Build Coastguard Worker }
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker void
tu_framebuffer_tiling_config(struct tu_framebuffer * fb,const struct tu_device * device,const struct tu_render_pass * pass)323*61046927SAndroid Build Coastguard Worker tu_framebuffer_tiling_config(struct tu_framebuffer *fb,
324*61046927SAndroid Build Coastguard Worker const struct tu_device *device,
325*61046927SAndroid Build Coastguard Worker const struct tu_render_pass *pass)
326*61046927SAndroid Build Coastguard Worker {
327*61046927SAndroid Build Coastguard Worker for (int gmem_layout = 0; gmem_layout < TU_GMEM_LAYOUT_COUNT; gmem_layout++) {
328*61046927SAndroid Build Coastguard Worker struct tu_tiling_config *tiling = &fb->tiling[gmem_layout];
329*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_tile_layout(fb, device, pass,
330*61046927SAndroid Build Coastguard Worker (enum tu_gmem_layout) gmem_layout);
331*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_pipe_layout(tiling, device);
332*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_pipes(tiling, device);
333*61046927SAndroid Build Coastguard Worker tu_tiling_config_update_binning(tiling, device);
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker }
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker void
tu_dbg_log_gmem_load_store_skips(struct tu_device * device)338*61046927SAndroid Build Coastguard Worker tu_dbg_log_gmem_load_store_skips(struct tu_device *device)
339*61046927SAndroid Build Coastguard Worker {
340*61046927SAndroid Build Coastguard Worker static uint32_t last_skipped_loads = 0;
341*61046927SAndroid Build Coastguard Worker static uint32_t last_skipped_stores = 0;
342*61046927SAndroid Build Coastguard Worker static uint32_t last_total_loads = 0;
343*61046927SAndroid Build Coastguard Worker static uint32_t last_total_stores = 0;
344*61046927SAndroid Build Coastguard Worker static struct timespec last_time = {};
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker pthread_mutex_lock(&device->submit_mutex);
347*61046927SAndroid Build Coastguard Worker
348*61046927SAndroid Build Coastguard Worker struct timespec current_time;
349*61046927SAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, ¤t_time);
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker if (timespec_sub_to_nsec(¤t_time, &last_time) > 1000 * 1000 * 1000) {
352*61046927SAndroid Build Coastguard Worker last_time = current_time;
353*61046927SAndroid Build Coastguard Worker } else {
354*61046927SAndroid Build Coastguard Worker pthread_mutex_unlock(&device->submit_mutex);
355*61046927SAndroid Build Coastguard Worker return;
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker struct tu6_global *global = device->global_bo_map;
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker uint32_t current_taken_loads = global->dbg_gmem_taken_loads;
361*61046927SAndroid Build Coastguard Worker uint32_t current_taken_stores = global->dbg_gmem_taken_stores;
362*61046927SAndroid Build Coastguard Worker uint32_t current_total_loads = global->dbg_gmem_total_loads;
363*61046927SAndroid Build Coastguard Worker uint32_t current_total_stores = global->dbg_gmem_total_stores;
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker uint32_t skipped_loads = current_total_loads - current_taken_loads;
366*61046927SAndroid Build Coastguard Worker uint32_t skipped_stores = current_total_stores - current_taken_stores;
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker uint32_t current_time_frame_skipped_loads = skipped_loads - last_skipped_loads;
369*61046927SAndroid Build Coastguard Worker uint32_t current_time_frame_skipped_stores = skipped_stores - last_skipped_stores;
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker uint32_t current_time_frame_total_loads = current_total_loads - last_total_loads;
372*61046927SAndroid Build Coastguard Worker uint32_t current_time_frame_total_stores = current_total_stores - last_total_stores;
373*61046927SAndroid Build Coastguard Worker
374*61046927SAndroid Build Coastguard Worker mesa_logi("[GMEM] loads total: %u skipped: %.1f%%\n",
375*61046927SAndroid Build Coastguard Worker current_time_frame_total_loads,
376*61046927SAndroid Build Coastguard Worker current_time_frame_skipped_loads / (float) current_time_frame_total_loads * 100.f);
377*61046927SAndroid Build Coastguard Worker mesa_logi("[GMEM] stores total: %u skipped: %.1f%%\n",
378*61046927SAndroid Build Coastguard Worker current_time_frame_total_stores,
379*61046927SAndroid Build Coastguard Worker current_time_frame_skipped_stores / (float) current_time_frame_total_stores * 100.f);
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker last_skipped_loads = skipped_loads;
382*61046927SAndroid Build Coastguard Worker last_skipped_stores = skipped_stores;
383*61046927SAndroid Build Coastguard Worker last_total_loads = current_total_loads;
384*61046927SAndroid Build Coastguard Worker last_total_stores = current_total_stores;
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker pthread_mutex_unlock(&device->submit_mutex);
387*61046927SAndroid Build Coastguard Worker }
388