2 * Copyright © 2015 Intel Corporation
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:
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
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 #include "tu_private.h"
33 #include "util/u_math.h"
34 #include "vk_enum_to_str.h"
36 /* TODO: Add Android support to tu_log funcs */
40 tu_loge_v(const char *format
, va_list va
)
42 fprintf(stderr
, "vk: error: ");
43 vfprintf(stderr
, format
, va
);
44 fprintf(stderr
, "\n");
48 /** Log an error message. */
49 void tu_printflike(1, 2) tu_loge(const char *format
, ...)
54 tu_loge_v(format
, va
);
60 tu_logi_v(const char *format
, va_list va
)
62 fprintf(stderr
, "tu: info: ");
63 vfprintf(stderr
, format
, va
);
64 fprintf(stderr
, "\n");
67 /** Log an error message. */
68 void tu_printflike(1, 2) tu_logi(const char *format
, ...)
73 tu_logi_v(format
, va
);
77 void tu_printflike(3, 4)
78 __tu_finishme(const char *file
, int line
, const char *format
, ...)
84 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
87 fprintf(stderr
, "%s:%d: FINISHME: %s\n", file
, line
, buffer
);
91 __vk_errorf(struct tu_instance
*instance
,
101 const char *error_str
= vk_Result_to_str(error
);
108 va_start(ap
, format
);
109 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
112 fprintf(stderr
, "%s:%d: %s (%s)\n", file
, line
, buffer
, error_str
);
114 fprintf(stderr
, "%s:%d: %s\n", file
, line
, error_str
);
121 tu_tiling_config_update_tile_layout(struct tu_framebuffer
*fb
,
122 const struct tu_device
*dev
,
123 const struct tu_render_pass
*pass
)
125 const uint32_t tile_align_w
= pass
->tile_align_w
;
126 const uint32_t max_tile_width
= 1024;
128 /* start from 1 tile */
129 fb
->tile_count
= (VkExtent2D
) {
133 fb
->tile0
= (VkExtent2D
) {
134 .width
= util_align_npot(fb
->width
, tile_align_w
),
135 .height
= align(fb
->height
, TILE_ALIGN_H
),
138 if (unlikely(dev
->physical_device
->instance
->debug_flags
& TU_DEBUG_FORCEBIN
)) {
139 /* start with 2x2 tiles */
140 fb
->tile_count
.width
= 2;
141 fb
->tile_count
.height
= 2;
142 fb
->tile0
.width
= util_align_npot(DIV_ROUND_UP(fb
->width
, 2), tile_align_w
);
143 fb
->tile0
.height
= align(DIV_ROUND_UP(fb
->height
, 2), TILE_ALIGN_H
);
146 /* do not exceed max tile width */
147 while (fb
->tile0
.width
> max_tile_width
) {
148 fb
->tile_count
.width
++;
150 util_align_npot(DIV_ROUND_UP(fb
->width
, fb
->tile_count
.width
), tile_align_w
);
153 /* will force to sysmem, don't bother trying to have a valid tile config
154 * TODO: just skip all GMEM stuff when sysmem is forced?
156 if (!pass
->gmem_pixels
)
159 /* do not exceed gmem size */
160 while (fb
->tile0
.width
* fb
->tile0
.height
> pass
->gmem_pixels
) {
161 if (fb
->tile0
.width
> MAX2(tile_align_w
, fb
->tile0
.height
)) {
162 fb
->tile_count
.width
++;
164 util_align_npot(DIV_ROUND_UP(fb
->width
, fb
->tile_count
.width
), tile_align_w
);
166 /* if this assert fails then layout is impossible.. */
167 assert(fb
->tile0
.height
> TILE_ALIGN_H
);
168 fb
->tile_count
.height
++;
170 align(DIV_ROUND_UP(fb
->height
, fb
->tile_count
.height
), TILE_ALIGN_H
);
176 tu_tiling_config_update_pipe_layout(struct tu_framebuffer
*fb
,
177 const struct tu_device
*dev
)
179 const uint32_t max_pipe_count
= 32; /* A6xx */
181 /* start from 1 tile per pipe */
182 fb
->pipe0
= (VkExtent2D
) {
186 fb
->pipe_count
= fb
->tile_count
;
188 while (fb
->pipe_count
.width
* fb
->pipe_count
.height
> max_pipe_count
) {
189 if (fb
->pipe0
.width
< fb
->pipe0
.height
) {
190 fb
->pipe0
.width
+= 1;
191 fb
->pipe_count
.width
=
192 DIV_ROUND_UP(fb
->tile_count
.width
, fb
->pipe0
.width
);
194 fb
->pipe0
.height
+= 1;
195 fb
->pipe_count
.height
=
196 DIV_ROUND_UP(fb
->tile_count
.height
, fb
->pipe0
.height
);
202 tu_tiling_config_update_pipes(struct tu_framebuffer
*fb
,
203 const struct tu_device
*dev
)
205 const uint32_t max_pipe_count
= 32; /* A6xx */
206 const uint32_t used_pipe_count
=
207 fb
->pipe_count
.width
* fb
->pipe_count
.height
;
208 const VkExtent2D last_pipe
= {
209 .width
= (fb
->tile_count
.width
- 1) % fb
->pipe0
.width
+ 1,
210 .height
= (fb
->tile_count
.height
- 1) % fb
->pipe0
.height
+ 1,
213 assert(used_pipe_count
<= max_pipe_count
);
214 assert(max_pipe_count
<= ARRAY_SIZE(fb
->pipe_config
));
216 for (uint32_t y
= 0; y
< fb
->pipe_count
.height
; y
++) {
217 for (uint32_t x
= 0; x
< fb
->pipe_count
.width
; x
++) {
218 const uint32_t pipe_x
= fb
->pipe0
.width
* x
;
219 const uint32_t pipe_y
= fb
->pipe0
.height
* y
;
220 const uint32_t pipe_w
= (x
== fb
->pipe_count
.width
- 1)
223 const uint32_t pipe_h
= (y
== fb
->pipe_count
.height
- 1)
226 const uint32_t n
= fb
->pipe_count
.width
* y
+ x
;
228 fb
->pipe_config
[n
] = A6XX_VSC_PIPE_CONFIG_REG_X(pipe_x
) |
229 A6XX_VSC_PIPE_CONFIG_REG_Y(pipe_y
) |
230 A6XX_VSC_PIPE_CONFIG_REG_W(pipe_w
) |
231 A6XX_VSC_PIPE_CONFIG_REG_H(pipe_h
);
232 fb
->pipe_sizes
[n
] = CP_SET_BIN_DATA5_0_VSC_SIZE(pipe_w
* pipe_h
);
236 memset(fb
->pipe_config
+ used_pipe_count
, 0,
237 sizeof(uint32_t) * (max_pipe_count
- used_pipe_count
));
241 tu_framebuffer_tiling_config(struct tu_framebuffer
*fb
,
242 const struct tu_device
*device
,
243 const struct tu_render_pass
*pass
)
245 tu_tiling_config_update_tile_layout(fb
, device
, pass
);
246 tu_tiling_config_update_pipe_layout(fb
, device
);
247 tu_tiling_config_update_pipes(fb
, device
);