e5a3eac30e4475e1f2adb2facbda8cc832ff95c2
[mesa.git] / src / freedreno / vulkan / tu_cmd_buffer.c
1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28 #include "tu_private.h"
29
30 #include "registers/adreno_pm4.xml.h"
31 #include "registers/adreno_common.xml.h"
32 #include "registers/a6xx.xml.h"
33
34 #include "vk_format.h"
35
36 #include "tu_cs.h"
37
38 void
39 tu_bo_list_init(struct tu_bo_list *list)
40 {
41 list->count = list->capacity = 0;
42 list->bo_infos = NULL;
43 }
44
45 void
46 tu_bo_list_destroy(struct tu_bo_list *list)
47 {
48 free(list->bo_infos);
49 }
50
51 void
52 tu_bo_list_reset(struct tu_bo_list *list)
53 {
54 list->count = 0;
55 }
56
57 /**
58 * \a flags consists of MSM_SUBMIT_BO_FLAGS.
59 */
60 static uint32_t
61 tu_bo_list_add_info(struct tu_bo_list *list,
62 const struct drm_msm_gem_submit_bo *bo_info)
63 {
64 for (uint32_t i = 0; i < list->count; ++i) {
65 if (list->bo_infos[i].handle == bo_info->handle) {
66 assert(list->bo_infos[i].presumed == bo_info->presumed);
67 list->bo_infos[i].flags |= bo_info->flags;
68 return i;
69 }
70 }
71
72 /* grow list->bo_infos if needed */
73 if (list->count == list->capacity) {
74 uint32_t new_capacity = MAX2(2 * list->count, 16);
75 struct drm_msm_gem_submit_bo *new_bo_infos = realloc(
76 list->bo_infos, new_capacity * sizeof(struct drm_msm_gem_submit_bo));
77 if (!new_bo_infos)
78 return TU_BO_LIST_FAILED;
79 list->bo_infos = new_bo_infos;
80 list->capacity = new_capacity;
81 }
82
83 list->bo_infos[list->count] = *bo_info;
84 return list->count++;
85 }
86
87 uint32_t
88 tu_bo_list_add(struct tu_bo_list *list,
89 const struct tu_bo *bo,
90 uint32_t flags)
91 {
92 return tu_bo_list_add_info(list, &(struct drm_msm_gem_submit_bo) {
93 .flags = flags,
94 .handle = bo->gem_handle,
95 .presumed = bo->iova,
96 });
97 }
98
99 VkResult
100 tu_bo_list_merge(struct tu_bo_list *list, const struct tu_bo_list *other)
101 {
102 for (uint32_t i = 0; i < other->count; i++) {
103 if (tu_bo_list_add_info(list, other->bo_infos + i) == TU_BO_LIST_FAILED)
104 return VK_ERROR_OUT_OF_HOST_MEMORY;
105 }
106
107 return VK_SUCCESS;
108 }
109
110 static VkResult
111 tu_tiling_config_update_gmem_layout(struct tu_tiling_config *tiling,
112 const struct tu_device *dev)
113 {
114 const uint32_t gmem_size = dev->physical_device->gmem_size;
115 uint32_t offset = 0;
116
117 for (uint32_t i = 0; i < tiling->buffer_count; i++) {
118 /* 16KB-aligned */
119 offset = align(offset, 0x4000);
120
121 tiling->gmem_offsets[i] = offset;
122 offset += tiling->tile0.extent.width * tiling->tile0.extent.height *
123 tiling->buffer_cpp[i];
124 }
125
126 return offset <= gmem_size ? VK_SUCCESS : VK_ERROR_OUT_OF_DEVICE_MEMORY;
127 }
128
129 static void
130 tu_tiling_config_update_tile_layout(struct tu_tiling_config *tiling,
131 const struct tu_device *dev)
132 {
133 const uint32_t tile_align_w = dev->physical_device->tile_align_w;
134 const uint32_t tile_align_h = dev->physical_device->tile_align_h;
135 const uint32_t max_tile_width = 1024; /* A6xx */
136
137 tiling->tile0.offset = (VkOffset2D) {
138 .x = tiling->render_area.offset.x & ~(tile_align_w - 1),
139 .y = tiling->render_area.offset.y & ~(tile_align_h - 1),
140 };
141
142 const uint32_t ra_width =
143 tiling->render_area.extent.width +
144 (tiling->render_area.offset.x - tiling->tile0.offset.x);
145 const uint32_t ra_height =
146 tiling->render_area.extent.height +
147 (tiling->render_area.offset.y - tiling->tile0.offset.y);
148
149 /* start from 1 tile */
150 tiling->tile_count = (VkExtent2D) {
151 .width = 1,
152 .height = 1,
153 };
154 tiling->tile0.extent = (VkExtent2D) {
155 .width = align(ra_width, tile_align_w),
156 .height = align(ra_height, tile_align_h),
157 };
158
159 /* do not exceed max tile width */
160 while (tiling->tile0.extent.width > max_tile_width) {
161 tiling->tile_count.width++;
162 tiling->tile0.extent.width =
163 align(ra_width / tiling->tile_count.width, tile_align_w);
164 }
165
166 /* do not exceed gmem size */
167 while (tu_tiling_config_update_gmem_layout(tiling, dev) != VK_SUCCESS) {
168 if (tiling->tile0.extent.width > tiling->tile0.extent.height) {
169 tiling->tile_count.width++;
170 tiling->tile0.extent.width =
171 align(ra_width / tiling->tile_count.width, tile_align_w);
172 } else {
173 tiling->tile_count.height++;
174 tiling->tile0.extent.height =
175 align(ra_height / tiling->tile_count.height, tile_align_h);
176 }
177 }
178 }
179
180 static void
181 tu_tiling_config_update_pipe_layout(struct tu_tiling_config *tiling,
182 const struct tu_device *dev)
183 {
184 const uint32_t max_pipe_count = 32; /* A6xx */
185
186 /* start from 1 tile per pipe */
187 tiling->pipe0 = (VkExtent2D) {
188 .width = 1,
189 .height = 1,
190 };
191 tiling->pipe_count = tiling->tile_count;
192
193 /* do not exceed max pipe count vertically */
194 while (tiling->pipe_count.height > max_pipe_count) {
195 tiling->pipe0.height += 2;
196 tiling->pipe_count.height =
197 (tiling->tile_count.height + tiling->pipe0.height - 1) /
198 tiling->pipe0.height;
199 }
200
201 /* do not exceed max pipe count */
202 while (tiling->pipe_count.width * tiling->pipe_count.height >
203 max_pipe_count) {
204 tiling->pipe0.width += 1;
205 tiling->pipe_count.width =
206 (tiling->tile_count.width + tiling->pipe0.width - 1) /
207 tiling->pipe0.width;
208 }
209 }
210
211 static void
212 tu_tiling_config_update_pipes(struct tu_tiling_config *tiling,
213 const struct tu_device *dev)
214 {
215 const uint32_t max_pipe_count = 32; /* A6xx */
216 const uint32_t used_pipe_count =
217 tiling->pipe_count.width * tiling->pipe_count.height;
218 const VkExtent2D last_pipe = {
219 .width = tiling->tile_count.width % tiling->pipe0.width,
220 .height = tiling->tile_count.height % tiling->pipe0.height,
221 };
222
223 assert(used_pipe_count <= max_pipe_count);
224 assert(max_pipe_count <= ARRAY_SIZE(tiling->pipe_config));
225
226 for (uint32_t y = 0; y < tiling->pipe_count.height; y++) {
227 for (uint32_t x = 0; x < tiling->pipe_count.width; x++) {
228 const uint32_t pipe_x = tiling->pipe0.width * x;
229 const uint32_t pipe_y = tiling->pipe0.height * y;
230 const uint32_t pipe_w = (x == tiling->pipe_count.width - 1)
231 ? last_pipe.width
232 : tiling->pipe0.width;
233 const uint32_t pipe_h = (y == tiling->pipe_count.height - 1)
234 ? last_pipe.height
235 : tiling->pipe0.height;
236 const uint32_t n = tiling->pipe_count.width * y + x;
237
238 tiling->pipe_config[n] = A6XX_VSC_PIPE_CONFIG_REG_X(pipe_x) |
239 A6XX_VSC_PIPE_CONFIG_REG_Y(pipe_y) |
240 A6XX_VSC_PIPE_CONFIG_REG_W(pipe_w) |
241 A6XX_VSC_PIPE_CONFIG_REG_H(pipe_h);
242 tiling->pipe_sizes[n] = CP_SET_BIN_DATA5_0_VSC_SIZE(pipe_w * pipe_h);
243 }
244 }
245
246 memset(tiling->pipe_config + used_pipe_count, 0,
247 sizeof(uint32_t) * (max_pipe_count - used_pipe_count));
248 }
249
250 static void
251 tu_tiling_config_update(struct tu_tiling_config *tiling,
252 const struct tu_device *dev,
253 const uint32_t *buffer_cpp,
254 uint32_t buffer_count,
255 const VkRect2D *render_area)
256 {
257 /* see if there is any real change */
258 const bool ra_changed =
259 render_area &&
260 memcmp(&tiling->render_area, render_area, sizeof(*render_area));
261 const bool buf_changed = tiling->buffer_count != buffer_count ||
262 memcmp(tiling->buffer_cpp, buffer_cpp,
263 sizeof(*buffer_cpp) * buffer_count);
264 if (!ra_changed && !buf_changed)
265 return;
266
267 if (ra_changed)
268 tiling->render_area = *render_area;
269
270 if (buf_changed) {
271 memcpy(tiling->buffer_cpp, buffer_cpp,
272 sizeof(*buffer_cpp) * buffer_count);
273 tiling->buffer_count = buffer_count;
274 }
275
276 tu_tiling_config_update_tile_layout(tiling, dev);
277 tu_tiling_config_update_pipe_layout(tiling, dev);
278 tu_tiling_config_update_pipes(tiling, dev);
279 }
280
281 static void
282 tu_tiling_config_get_tile(const struct tu_tiling_config *tiling,
283 const struct tu_device *dev,
284 uint32_t tx,
285 uint32_t ty,
286 struct tu_tile *tile)
287 {
288 /* find the pipe and the slot for tile (tx, ty) */
289 const uint32_t px = tx / tiling->pipe0.width;
290 const uint32_t py = ty / tiling->pipe0.height;
291 const uint32_t sx = tx - tiling->pipe0.width * px;
292 const uint32_t sy = ty - tiling->pipe0.height * py;
293
294 assert(tx < tiling->tile_count.width && ty < tiling->tile_count.height);
295 assert(px < tiling->pipe_count.width && py < tiling->pipe_count.height);
296 assert(sx < tiling->pipe0.width && sy < tiling->pipe0.height);
297
298 /* convert to 1D indices */
299 tile->pipe = tiling->pipe_count.width * py + px;
300 tile->slot = tiling->pipe0.width * sy + sx;
301
302 /* get the blit area for the tile */
303 tile->begin = (VkOffset2D) {
304 .x = tiling->tile0.offset.x + tiling->tile0.extent.width * tx,
305 .y = tiling->tile0.offset.y + tiling->tile0.extent.height * ty,
306 };
307 tile->end.x =
308 (tx == tiling->tile_count.width - 1)
309 ? tiling->render_area.offset.x + tiling->render_area.extent.width
310 : tile->begin.x + tiling->tile0.extent.width;
311 tile->end.y =
312 (ty == tiling->tile_count.height - 1)
313 ? tiling->render_area.offset.y + tiling->render_area.extent.height
314 : tile->begin.y + tiling->tile0.extent.height;
315 }
316
317 static enum a3xx_msaa_samples
318 tu6_msaa_samples(uint32_t samples)
319 {
320 switch (samples) {
321 case 1:
322 return MSAA_ONE;
323 case 2:
324 return MSAA_TWO;
325 case 4:
326 return MSAA_FOUR;
327 case 8:
328 return MSAA_EIGHT;
329 default:
330 assert(!"invalid sample count");
331 return MSAA_ONE;
332 }
333 }
334
335 static void
336 tu6_emit_marker(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
337 {
338 tu_cs_emit_write_reg(cs, cmd->marker_reg, ++cmd->marker_seqno);
339 }
340
341 void
342 tu6_emit_event_write(struct tu_cmd_buffer *cmd,
343 struct tu_cs *cs,
344 enum vgt_event_type event,
345 bool need_seqno)
346 {
347 tu_cs_emit_pkt7(cs, CP_EVENT_WRITE, need_seqno ? 4 : 1);
348 tu_cs_emit(cs, CP_EVENT_WRITE_0_EVENT(event));
349 if (need_seqno) {
350 tu_cs_emit_qw(cs, cmd->scratch_bo.iova);
351 tu_cs_emit(cs, ++cmd->scratch_seqno);
352 }
353 }
354
355 static void
356 tu6_emit_cache_flush(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
357 {
358 tu6_emit_event_write(cmd, cs, 0x31, false);
359 }
360
361 static void
362 tu6_emit_lrz_flush(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
363 {
364 tu6_emit_event_write(cmd, cs, LRZ_FLUSH, false);
365 }
366
367 static void
368 tu6_emit_wfi(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
369 {
370 if (cmd->wait_for_idle) {
371 tu_cs_emit_wfi(cs);
372 cmd->wait_for_idle = false;
373 }
374 }
375
376 static void
377 tu6_emit_zs(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
378 {
379 const struct tu_subpass *subpass = cmd->state.subpass;
380
381 const uint32_t a = subpass->depth_stencil_attachment.attachment;
382 if (a == VK_ATTACHMENT_UNUSED) {
383 tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6);
384 tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(DEPTH6_NONE));
385 tu_cs_emit(cs, 0x00000000); /* RB_DEPTH_BUFFER_PITCH */
386 tu_cs_emit(cs, 0x00000000); /* RB_DEPTH_BUFFER_ARRAY_PITCH */
387 tu_cs_emit(cs, 0x00000000); /* RB_DEPTH_BUFFER_BASE_LO */
388 tu_cs_emit(cs, 0x00000000); /* RB_DEPTH_BUFFER_BASE_HI */
389 tu_cs_emit(cs, 0x00000000); /* RB_DEPTH_BUFFER_BASE_GMEM */
390
391 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO, 1);
392 tu_cs_emit(cs,
393 A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(DEPTH6_NONE));
394
395 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO, 5);
396 tu_cs_emit(cs, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_LO */
397 tu_cs_emit(cs, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_HI */
398 tu_cs_emit(cs, 0x00000000); /* GRAS_LRZ_BUFFER_PITCH */
399 tu_cs_emit(cs, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO */
400 tu_cs_emit(cs, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_HI */
401
402 tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCIL_INFO, 1);
403 tu_cs_emit(cs, 0x00000000); /* RB_STENCIL_INFO */
404
405 return;
406 }
407
408 /* enable zs? */
409 }
410
411 static void
412 tu6_emit_mrt(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
413 {
414 const struct tu_framebuffer *fb = cmd->state.framebuffer;
415 const struct tu_subpass *subpass = cmd->state.subpass;
416 const struct tu_tiling_config *tiling = &cmd->state.tiling_config;
417 unsigned char mrt_comp[MAX_RTS] = { 0 };
418 unsigned srgb_cntl = 0;
419
420 uint32_t gmem_index = 0;
421 for (uint32_t i = 0; i < subpass->color_count; ++i) {
422 uint32_t a = subpass->color_attachments[i].attachment;
423 if (a == VK_ATTACHMENT_UNUSED)
424 continue;
425
426 const struct tu_image_view *iview = fb->attachments[a].attachment;
427 const struct tu_image_level *slice =
428 &iview->image->levels[iview->base_mip];
429 const enum a6xx_tile_mode tile_mode = TILE6_LINEAR;
430 uint32_t stride = 0;
431 uint32_t offset = 0;
432
433 mrt_comp[i] = 0xf;
434
435 if (vk_format_is_srgb(iview->vk_format))
436 srgb_cntl |= (1 << i);
437
438 const struct tu_native_format *format =
439 tu6_get_native_format(iview->vk_format);
440 assert(format && format->rb >= 0);
441
442 offset = slice->offset + slice->size * iview->base_layer;
443 stride = slice->pitch * vk_format_get_blocksize(iview->vk_format);
444
445 tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(i), 6);
446 tu_cs_emit(cs, A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format->rb) |
447 A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
448 A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(format->swap));
449 tu_cs_emit(cs, A6XX_RB_MRT_PITCH(stride));
450 tu_cs_emit(cs, A6XX_RB_MRT_ARRAY_PITCH(slice->size));
451 tu_cs_emit_qw(cs, iview->image->bo->iova + iview->image->bo_offset +
452 offset); /* BASE_LO/HI */
453 tu_cs_emit(
454 cs, tiling->gmem_offsets[gmem_index++]); /* RB_MRT[i].BASE_GMEM */
455
456 tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_MRT_REG(i), 1);
457 tu_cs_emit(cs, A6XX_SP_FS_MRT_REG_COLOR_FORMAT(format->rb));
458
459 #if 0
460 /* when we support UBWC, these would be the system memory
461 * addr/pitch/etc:
462 */
463 tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER(i), 4);
464 tu_cs_emit(cs, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */
465 tu_cs_emit(cs, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */
466 tu_cs_emit(cs, A6XX_RB_MRT_FLAG_BUFFER_PITCH(0));
467 tu_cs_emit(cs, A6XX_RB_MRT_FLAG_BUFFER_ARRAY_PITCH(0));
468 #endif
469 }
470
471 tu_cs_emit_pkt4(cs, REG_A6XX_RB_SRGB_CNTL, 1);
472 tu_cs_emit(cs, srgb_cntl);
473
474 tu_cs_emit_pkt4(cs, REG_A6XX_SP_SRGB_CNTL, 1);
475 tu_cs_emit(cs, srgb_cntl);
476
477 tu_cs_emit_pkt4(cs, REG_A6XX_RB_RENDER_COMPONENTS, 1);
478 tu_cs_emit(cs, A6XX_RB_RENDER_COMPONENTS_RT0(mrt_comp[0]) |
479 A6XX_RB_RENDER_COMPONENTS_RT1(mrt_comp[1]) |
480 A6XX_RB_RENDER_COMPONENTS_RT2(mrt_comp[2]) |
481 A6XX_RB_RENDER_COMPONENTS_RT3(mrt_comp[3]) |
482 A6XX_RB_RENDER_COMPONENTS_RT4(mrt_comp[4]) |
483 A6XX_RB_RENDER_COMPONENTS_RT5(mrt_comp[5]) |
484 A6XX_RB_RENDER_COMPONENTS_RT6(mrt_comp[6]) |
485 A6XX_RB_RENDER_COMPONENTS_RT7(mrt_comp[7]));
486
487 tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_RENDER_COMPONENTS, 1);
488 tu_cs_emit(cs, A6XX_SP_FS_RENDER_COMPONENTS_RT0(mrt_comp[0]) |
489 A6XX_SP_FS_RENDER_COMPONENTS_RT1(mrt_comp[1]) |
490 A6XX_SP_FS_RENDER_COMPONENTS_RT2(mrt_comp[2]) |
491 A6XX_SP_FS_RENDER_COMPONENTS_RT3(mrt_comp[3]) |
492 A6XX_SP_FS_RENDER_COMPONENTS_RT4(mrt_comp[4]) |
493 A6XX_SP_FS_RENDER_COMPONENTS_RT5(mrt_comp[5]) |
494 A6XX_SP_FS_RENDER_COMPONENTS_RT6(mrt_comp[6]) |
495 A6XX_SP_FS_RENDER_COMPONENTS_RT7(mrt_comp[7]));
496 }
497
498 static void
499 tu6_emit_msaa(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
500 {
501 const struct tu_subpass *subpass = cmd->state.subpass;
502 const enum a3xx_msaa_samples samples =
503 tu6_msaa_samples(subpass->max_sample_count);
504
505 tu_cs_emit_pkt4(cs, REG_A6XX_SP_TP_RAS_MSAA_CNTL, 2);
506 tu_cs_emit(cs, A6XX_SP_TP_RAS_MSAA_CNTL_SAMPLES(samples));
507 tu_cs_emit(
508 cs, A6XX_SP_TP_DEST_MSAA_CNTL_SAMPLES(samples) |
509 ((samples == MSAA_ONE) ? A6XX_SP_TP_DEST_MSAA_CNTL_MSAA_DISABLE
510 : 0));
511
512 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_RAS_MSAA_CNTL, 2);
513 tu_cs_emit(cs, A6XX_GRAS_RAS_MSAA_CNTL_SAMPLES(samples));
514 tu_cs_emit(
515 cs,
516 A6XX_GRAS_DEST_MSAA_CNTL_SAMPLES(samples) |
517 ((samples == MSAA_ONE) ? A6XX_GRAS_DEST_MSAA_CNTL_MSAA_DISABLE : 0));
518
519 tu_cs_emit_pkt4(cs, REG_A6XX_RB_RAS_MSAA_CNTL, 2);
520 tu_cs_emit(cs, A6XX_RB_RAS_MSAA_CNTL_SAMPLES(samples));
521 tu_cs_emit(
522 cs,
523 A6XX_RB_DEST_MSAA_CNTL_SAMPLES(samples) |
524 ((samples == MSAA_ONE) ? A6XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE : 0));
525
526 tu_cs_emit_pkt4(cs, REG_A6XX_RB_MSAA_CNTL, 1);
527 tu_cs_emit(cs, A6XX_RB_MSAA_CNTL_SAMPLES(samples));
528 }
529
530 static void
531 tu6_emit_bin_size(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t flags)
532 {
533 const struct tu_tiling_config *tiling = &cmd->state.tiling_config;
534 const uint32_t bin_w = tiling->tile0.extent.width;
535 const uint32_t bin_h = tiling->tile0.extent.height;
536
537 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_BIN_CONTROL, 1);
538 tu_cs_emit(cs, A6XX_GRAS_BIN_CONTROL_BINW(bin_w) |
539 A6XX_GRAS_BIN_CONTROL_BINH(bin_h) | flags);
540
541 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BIN_CONTROL, 1);
542 tu_cs_emit(cs, A6XX_RB_BIN_CONTROL_BINW(bin_w) |
543 A6XX_RB_BIN_CONTROL_BINH(bin_h) | flags);
544
545 /* no flag for RB_BIN_CONTROL2... */
546 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BIN_CONTROL2, 1);
547 tu_cs_emit(cs, A6XX_RB_BIN_CONTROL2_BINW(bin_w) |
548 A6XX_RB_BIN_CONTROL2_BINH(bin_h));
549 }
550
551 static void
552 tu6_emit_render_cntl(struct tu_cmd_buffer *cmd,
553 struct tu_cs *cs,
554 bool binning)
555 {
556 uint32_t cntl = 0;
557 cntl |= A6XX_RB_RENDER_CNTL_UNK4;
558 if (binning)
559 cntl |= A6XX_RB_RENDER_CNTL_BINNING;
560
561 tu_cs_emit_pkt7(cs, CP_REG_WRITE, 3);
562 tu_cs_emit(cs, 0x2);
563 tu_cs_emit(cs, REG_A6XX_RB_RENDER_CNTL);
564 tu_cs_emit(cs, cntl);
565 }
566
567 static void
568 tu6_emit_blit_scissor(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
569 {
570 const VkRect2D *render_area = &cmd->state.tiling_config.render_area;
571 const uint32_t x1 = render_area->offset.x;
572 const uint32_t y1 = render_area->offset.y;
573 const uint32_t x2 = x1 + render_area->extent.width - 1;
574 const uint32_t y2 = y1 + render_area->extent.height - 1;
575
576 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_SCISSOR_TL, 2);
577 tu_cs_emit(cs,
578 A6XX_RB_BLIT_SCISSOR_TL_X(x1) | A6XX_RB_BLIT_SCISSOR_TL_Y(y1));
579 tu_cs_emit(cs,
580 A6XX_RB_BLIT_SCISSOR_BR_X(x2) | A6XX_RB_BLIT_SCISSOR_BR_Y(y2));
581 }
582
583 static void
584 tu6_emit_blit_info(struct tu_cmd_buffer *cmd,
585 struct tu_cs *cs,
586 const struct tu_image_view *iview,
587 uint32_t gmem_offset,
588 uint32_t blit_info)
589 {
590 const struct tu_image_level *slice =
591 &iview->image->levels[iview->base_mip];
592 const uint32_t offset = slice->offset + slice->size * iview->base_layer;
593 const uint32_t stride =
594 slice->pitch * vk_format_get_blocksize(iview->vk_format);
595 const enum a6xx_tile_mode tile_mode = TILE6_LINEAR;
596 const enum a3xx_msaa_samples samples = tu6_msaa_samples(1);
597
598 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1);
599 tu_cs_emit(cs, blit_info);
600
601 /* tile mode? */
602 const struct tu_native_format *format =
603 tu6_get_native_format(iview->vk_format);
604 assert(format && format->rb >= 0);
605
606 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 5);
607 tu_cs_emit(cs, A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode) |
608 A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
609 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format->rb) |
610 A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(format->swap));
611 tu_cs_emit_qw(cs,
612 iview->image->bo->iova + iview->image->bo_offset + offset);
613 tu_cs_emit(cs, A6XX_RB_BLIT_DST_PITCH(stride));
614 tu_cs_emit(cs, A6XX_RB_BLIT_DST_ARRAY_PITCH(slice->size));
615
616 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_BASE_GMEM, 1);
617 tu_cs_emit(cs, gmem_offset);
618 }
619
620 static void
621 tu6_emit_blit_clear(struct tu_cmd_buffer *cmd,
622 struct tu_cs *cs,
623 const struct tu_image_view *iview,
624 uint32_t gmem_offset,
625 const VkClearValue *clear_value)
626 {
627 const enum a6xx_tile_mode tile_mode = TILE6_LINEAR;
628 const enum a3xx_msaa_samples samples = tu6_msaa_samples(1);
629
630 const struct tu_native_format *format =
631 tu6_get_native_format(iview->vk_format);
632 assert(format && format->rb >= 0);
633 /* must be WZYX; other values are ignored */
634 const enum a3xx_color_swap swap = WZYX;
635
636 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 1);
637 tu_cs_emit(cs, A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode) |
638 A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
639 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format->rb) |
640 A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap));
641
642 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1);
643 tu_cs_emit(cs, A6XX_RB_BLIT_INFO_GMEM | A6XX_RB_BLIT_INFO_CLEAR_MASK(0xf));
644
645 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_BASE_GMEM, 1);
646 tu_cs_emit(cs, gmem_offset);
647
648 tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_88D0, 1);
649 tu_cs_emit(cs, 0);
650
651 /* pack clear_value into WZYX order */
652 uint32_t clear_vals[4] = { 0 };
653 tu_pack_clear_value(clear_value, iview->vk_format, clear_vals);
654
655 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 4);
656 tu_cs_emit(cs, clear_vals[0]);
657 tu_cs_emit(cs, clear_vals[1]);
658 tu_cs_emit(cs, clear_vals[2]);
659 tu_cs_emit(cs, clear_vals[3]);
660 }
661
662 static void
663 tu6_emit_blit(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
664 {
665 tu6_emit_marker(cmd, cs);
666 tu6_emit_event_write(cmd, cs, BLIT, false);
667 tu6_emit_marker(cmd, cs);
668 }
669
670 static void
671 tu6_emit_window_scissor(struct tu_cmd_buffer *cmd,
672 struct tu_cs *cs,
673 uint32_t x1,
674 uint32_t y1,
675 uint32_t x2,
676 uint32_t y2)
677 {
678 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
679 tu_cs_emit(cs, A6XX_GRAS_SC_WINDOW_SCISSOR_TL_X(x1) |
680 A6XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(y1));
681 tu_cs_emit(cs, A6XX_GRAS_SC_WINDOW_SCISSOR_BR_X(x2) |
682 A6XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(y2));
683
684 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_RESOLVE_CNTL_1, 2);
685 tu_cs_emit(
686 cs, A6XX_GRAS_RESOLVE_CNTL_1_X(x1) | A6XX_GRAS_RESOLVE_CNTL_1_Y(y1));
687 tu_cs_emit(
688 cs, A6XX_GRAS_RESOLVE_CNTL_2_X(x2) | A6XX_GRAS_RESOLVE_CNTL_2_Y(y2));
689 }
690
691 static void
692 tu6_emit_window_offset(struct tu_cmd_buffer *cmd,
693 struct tu_cs *cs,
694 uint32_t x1,
695 uint32_t y1)
696 {
697 tu_cs_emit_pkt4(cs, REG_A6XX_RB_WINDOW_OFFSET, 1);
698 tu_cs_emit(cs, A6XX_RB_WINDOW_OFFSET_X(x1) | A6XX_RB_WINDOW_OFFSET_Y(y1));
699
700 tu_cs_emit_pkt4(cs, REG_A6XX_RB_WINDOW_OFFSET2, 1);
701 tu_cs_emit(cs,
702 A6XX_RB_WINDOW_OFFSET2_X(x1) | A6XX_RB_WINDOW_OFFSET2_Y(y1));
703
704 tu_cs_emit_pkt4(cs, REG_A6XX_SP_WINDOW_OFFSET, 1);
705 tu_cs_emit(cs, A6XX_SP_WINDOW_OFFSET_X(x1) | A6XX_SP_WINDOW_OFFSET_Y(y1));
706
707 tu_cs_emit_pkt4(cs, REG_A6XX_SP_TP_WINDOW_OFFSET, 1);
708 tu_cs_emit(
709 cs, A6XX_SP_TP_WINDOW_OFFSET_X(x1) | A6XX_SP_TP_WINDOW_OFFSET_Y(y1));
710 }
711
712 static void
713 tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
714 struct tu_cs *cs,
715 const struct tu_tile *tile)
716 {
717 tu_cs_emit_pkt7(cs, CP_SET_MARKER, 1);
718 tu_cs_emit(cs, A2XX_CP_SET_MARKER_0_MODE(0x7));
719
720 tu6_emit_marker(cmd, cs);
721 tu_cs_emit_pkt7(cs, CP_SET_MARKER, 1);
722 tu_cs_emit(cs, A2XX_CP_SET_MARKER_0_MODE(RM6_GMEM) | 0x10);
723 tu6_emit_marker(cmd, cs);
724
725 const uint32_t x1 = tile->begin.x;
726 const uint32_t y1 = tile->begin.y;
727 const uint32_t x2 = tile->end.x - 1;
728 const uint32_t y2 = tile->end.y - 1;
729 tu6_emit_window_scissor(cmd, cs, x1, y1, x2, y2);
730 tu6_emit_window_offset(cmd, cs, x1, y1);
731
732 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_OVERRIDE, 1);
733 tu_cs_emit(cs, A6XX_VPC_SO_OVERRIDE_SO_DISABLE);
734
735 if (false) {
736 /* hw binning? */
737 } else {
738 tu_cs_emit_pkt7(cs, CP_SET_VISIBILITY_OVERRIDE, 1);
739 tu_cs_emit(cs, 0x1);
740
741 tu_cs_emit_pkt7(cs, CP_SET_MODE, 1);
742 tu_cs_emit(cs, 0x0);
743 }
744 }
745
746 static void
747 tu6_emit_tile_load(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
748 {
749 const struct tu_framebuffer *fb = cmd->state.framebuffer;
750 const struct tu_subpass *subpass = cmd->state.subpass;
751 const struct tu_tiling_config *tiling = &cmd->state.tiling_config;
752 const struct tu_attachment_state *attachments = cmd->state.attachments;
753
754 tu6_emit_blit_scissor(cmd, cs);
755
756 uint32_t gmem_index = 0;
757 for (uint32_t i = 0; i < subpass->color_count; ++i) {
758 const uint32_t a = subpass->color_attachments[i].attachment;
759 if (a == VK_ATTACHMENT_UNUSED)
760 continue;
761
762 const struct tu_image_view *iview = fb->attachments[a].attachment;
763 const struct tu_attachment_state *att = attachments + a;
764 if (att->pending_clear_aspects) {
765 assert(att->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT);
766 tu6_emit_blit_clear(cmd, cs, iview,
767 tiling->gmem_offsets[gmem_index++],
768 &att->clear_value);
769 } else {
770 tu6_emit_blit_info(cmd, cs, iview,
771 tiling->gmem_offsets[gmem_index++],
772 A6XX_RB_BLIT_INFO_UNK0 | A6XX_RB_BLIT_INFO_GMEM);
773 }
774
775 tu6_emit_blit(cmd, cs);
776 }
777
778 /* load/clear zs? */
779 }
780
781 static void
782 tu6_emit_tile_store(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
783 {
784 const struct tu_framebuffer *fb = cmd->state.framebuffer;
785 const struct tu_tiling_config *tiling = &cmd->state.tiling_config;
786
787 if (false) {
788 /* hw binning? */
789 }
790
791 tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3);
792 tu_cs_emit(cs, CP_SET_DRAW_STATE__0_COUNT(0) |
793 CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS |
794 CP_SET_DRAW_STATE__0_GROUP_ID(0));
795 tu_cs_emit(cs, CP_SET_DRAW_STATE__1_ADDR_LO(0));
796 tu_cs_emit(cs, CP_SET_DRAW_STATE__2_ADDR_HI(0));
797
798 tu_cs_emit_pkt7(cs, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
799 tu_cs_emit(cs, 0x0);
800
801 tu6_emit_marker(cmd, cs);
802 tu_cs_emit_pkt7(cs, CP_SET_MARKER, 1);
803 tu_cs_emit(cs, A2XX_CP_SET_MARKER_0_MODE(RM6_RESOLVE) | 0x10);
804 tu6_emit_marker(cmd, cs);
805
806 tu6_emit_blit_scissor(cmd, cs);
807
808 uint32_t gmem_index = 0;
809 for (uint32_t i = 0; i < cmd->state.subpass->color_count; ++i) {
810 uint32_t a = cmd->state.subpass->color_attachments[i].attachment;
811 if (a == VK_ATTACHMENT_UNUSED)
812 continue;
813
814 const struct tu_image_view *iview = fb->attachments[a].attachment;
815 tu6_emit_blit_info(cmd, cs, iview, tiling->gmem_offsets[gmem_index++],
816 0);
817 tu6_emit_blit(cmd, cs);
818 }
819 }
820
821 static void
822 tu6_init_hw(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
823 {
824 VkResult result = tu_cs_reserve_space(cmd->device, cs, 256);
825 if (result != VK_SUCCESS) {
826 cmd->record_result = result;
827 return;
828 }
829
830 tu6_emit_cache_flush(cmd, cs);
831
832 tu_cs_emit_write_reg(cs, REG_A6XX_HLSQ_UPDATE_CNTL, 0xfffff);
833
834 tu_cs_emit_write_reg(cs, REG_A6XX_RB_CCU_CNTL, 0x7c400004);
835 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8E04, 0x00100000);
836 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_AE04, 0x8);
837 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_AE00, 0);
838 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_AE0F, 0x3f);
839 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_B605, 0x44);
840 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_B600, 0x100000);
841 tu_cs_emit_write_reg(cs, REG_A6XX_HLSQ_UNKNOWN_BE00, 0x80);
842 tu_cs_emit_write_reg(cs, REG_A6XX_HLSQ_UNKNOWN_BE01, 0);
843
844 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9600, 0);
845 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_8600, 0x880);
846 tu_cs_emit_write_reg(cs, REG_A6XX_HLSQ_UNKNOWN_BE04, 0);
847 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_AE03, 0x00000410);
848 tu_cs_emit_write_reg(cs, REG_A6XX_SP_IBO_COUNT, 0);
849 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_B182, 0);
850 tu_cs_emit_write_reg(cs, REG_A6XX_HLSQ_UNKNOWN_BB11, 0);
851 tu_cs_emit_write_reg(cs, REG_A6XX_UCHE_UNKNOWN_0E12, 0x3200000);
852 tu_cs_emit_write_reg(cs, REG_A6XX_UCHE_CLIENT_PF, 4);
853 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8E01, 0x0);
854 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_AB00, 0x5);
855 tu_cs_emit_write_reg(cs, REG_A6XX_VFD_UNKNOWN_A009, 0x00000001);
856 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8811, 0x00000010);
857 tu_cs_emit_write_reg(cs, REG_A6XX_PC_MODE_CNTL, 0x1f);
858
859 tu_cs_emit_write_reg(cs, REG_A6XX_RB_SRGB_CNTL, 0);
860
861 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_8101, 0);
862 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_8109, 0);
863 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_8110, 0);
864
865 tu_cs_emit_write_reg(cs, REG_A6XX_RB_RENDER_CONTROL0, 0x401);
866 tu_cs_emit_write_reg(cs, REG_A6XX_RB_RENDER_CONTROL1, 0);
867 tu_cs_emit_write_reg(cs, REG_A6XX_RB_FS_OUTPUT_CNTL0, 0);
868 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8810, 0);
869 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8818, 0);
870 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8819, 0);
871 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_881A, 0);
872 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_881B, 0);
873 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_881C, 0);
874 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_881D, 0);
875 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_881E, 0);
876 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_88F0, 0);
877
878 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9101, 0xffff00);
879 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9107, 0);
880
881 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9236, 1);
882 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9300, 0);
883
884 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_SO_OVERRIDE,
885 A6XX_VPC_SO_OVERRIDE_SO_DISABLE);
886
887 tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9801, 0);
888 tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9806, 0);
889 tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9980, 0);
890
891 tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9B06, 0);
892 tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9B06, 0);
893
894 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_A81B, 0);
895
896 tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_B183, 0);
897
898 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_8099, 0);
899 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_809B, 0);
900 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_80A0, 2);
901 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_80AF, 0);
902 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9210, 0);
903 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9211, 0);
904 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9602, 0);
905 tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9981, 0x3);
906 tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9E72, 0);
907 tu_cs_emit_write_reg(cs, REG_A6XX_VPC_UNKNOWN_9108, 0x3);
908 tu_cs_emit_write_reg(cs, REG_A6XX_SP_TP_UNKNOWN_B304, 0);
909 tu_cs_emit_write_reg(cs, REG_A6XX_SP_TP_UNKNOWN_B309, 0x000000a2);
910 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8804, 0);
911 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_80A4, 0);
912 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_80A5, 0);
913 tu_cs_emit_write_reg(cs, REG_A6XX_GRAS_UNKNOWN_80A6, 0);
914 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8805, 0);
915 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8806, 0);
916 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8878, 0);
917 tu_cs_emit_write_reg(cs, REG_A6XX_RB_UNKNOWN_8879, 0);
918 tu_cs_emit_write_reg(cs, REG_A6XX_HLSQ_CONTROL_5_REG, 0xfc);
919
920 tu6_emit_marker(cmd, cs);
921
922 tu_cs_emit_write_reg(cs, REG_A6XX_VFD_MODE_CNTL, 0x00000000);
923
924 tu_cs_emit_write_reg(cs, REG_A6XX_VFD_UNKNOWN_A008, 0);
925
926 tu_cs_emit_write_reg(cs, REG_A6XX_PC_MODE_CNTL, 0x0000001f);
927
928 /* we don't use this yet.. probably best to disable.. */
929 tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3);
930 tu_cs_emit(cs, CP_SET_DRAW_STATE__0_COUNT(0) |
931 CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS |
932 CP_SET_DRAW_STATE__0_GROUP_ID(0));
933 tu_cs_emit(cs, CP_SET_DRAW_STATE__1_ADDR_LO(0));
934 tu_cs_emit(cs, CP_SET_DRAW_STATE__2_ADDR_HI(0));
935
936 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_BUFFER_BASE_LO(0), 3);
937 tu_cs_emit(cs, 0x00000000); /* VPC_SO_BUFFER_BASE_LO_0 */
938 tu_cs_emit(cs, 0x00000000); /* VPC_SO_BUFFER_BASE_HI_0 */
939 tu_cs_emit(cs, 0x00000000); /* VPC_SO_BUFFER_SIZE_0 */
940
941 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_FLUSH_BASE_LO(0), 2);
942 tu_cs_emit(cs, 0x00000000); /* VPC_SO_FLUSH_BASE_LO_0 */
943 tu_cs_emit(cs, 0x00000000); /* VPC_SO_FLUSH_BASE_HI_0 */
944
945 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_BUF_CNTL, 1);
946 tu_cs_emit(cs, 0x00000000); /* VPC_SO_BUF_CNTL */
947
948 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_BUFFER_OFFSET(0), 1);
949 tu_cs_emit(cs, 0x00000000); /* UNKNOWN_E2AB */
950
951 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_BUFFER_BASE_LO(1), 3);
952 tu_cs_emit(cs, 0x00000000);
953 tu_cs_emit(cs, 0x00000000);
954 tu_cs_emit(cs, 0x00000000);
955
956 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_BUFFER_OFFSET(1), 6);
957 tu_cs_emit(cs, 0x00000000);
958 tu_cs_emit(cs, 0x00000000);
959 tu_cs_emit(cs, 0x00000000);
960 tu_cs_emit(cs, 0x00000000);
961 tu_cs_emit(cs, 0x00000000);
962 tu_cs_emit(cs, 0x00000000);
963
964 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_BUFFER_OFFSET(2), 6);
965 tu_cs_emit(cs, 0x00000000);
966 tu_cs_emit(cs, 0x00000000);
967 tu_cs_emit(cs, 0x00000000);
968 tu_cs_emit(cs, 0x00000000);
969 tu_cs_emit(cs, 0x00000000);
970 tu_cs_emit(cs, 0x00000000);
971
972 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_SO_BUFFER_OFFSET(3), 3);
973 tu_cs_emit(cs, 0x00000000);
974 tu_cs_emit(cs, 0x00000000);
975 tu_cs_emit(cs, 0x00000000);
976
977 tu_cs_emit_pkt4(cs, REG_A6XX_SP_HS_CTRL_REG0, 1);
978 tu_cs_emit(cs, 0x00000000);
979
980 tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_CTRL_REG0, 1);
981 tu_cs_emit(cs, 0x00000000);
982
983 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_LRZ_CNTL, 1);
984 tu_cs_emit(cs, 0x00000000);
985
986 tu_cs_emit_pkt4(cs, REG_A6XX_RB_LRZ_CNTL, 1);
987 tu_cs_emit(cs, 0x00000000);
988
989 tu_cs_sanity_check(cs);
990 }
991
992 static void
993 tu6_render_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
994 {
995 VkResult result = tu_cs_reserve_space(cmd->device, cs, 256);
996 if (result != VK_SUCCESS) {
997 cmd->record_result = result;
998 return;
999 }
1000
1001 tu6_emit_lrz_flush(cmd, cs);
1002
1003 /* lrz clear? */
1004
1005 tu6_emit_cache_flush(cmd, cs);
1006
1007 tu_cs_emit_pkt7(cs, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
1008 tu_cs_emit(cs, 0x0);
1009
1010 /* 0x10000000 for BYPASS.. 0x7c13c080 for GMEM: */
1011 tu6_emit_wfi(cmd, cs);
1012 tu_cs_emit_pkt4(cs, REG_A6XX_RB_CCU_CNTL, 1);
1013 tu_cs_emit(cs, 0x7c400004); /* RB_CCU_CNTL */
1014
1015 tu6_emit_zs(cmd, cs);
1016 tu6_emit_mrt(cmd, cs);
1017 tu6_emit_msaa(cmd, cs);
1018
1019 if (false) {
1020 /* hw binning? */
1021 } else {
1022 tu6_emit_bin_size(cmd, cs, 0x6000000);
1023 /* no draws */
1024 }
1025
1026 tu6_emit_render_cntl(cmd, cs, false);
1027
1028 tu_cs_sanity_check(cs);
1029 }
1030
1031 static void
1032 tu6_render_tile(struct tu_cmd_buffer *cmd,
1033 struct tu_cs *cs,
1034 const struct tu_tile *tile)
1035 {
1036 const uint32_t render_tile_space = 64 + tu_cs_get_call_size(&cmd->draw_cs);
1037 VkResult result = tu_cs_reserve_space(cmd->device, cs, render_tile_space);
1038 if (result != VK_SUCCESS) {
1039 cmd->record_result = result;
1040 return;
1041 }
1042
1043 tu6_emit_tile_select(cmd, cs, tile);
1044 tu_cs_emit_ib(cs, &cmd->state.tile_load_ib);
1045
1046 tu_cs_emit_call(cs, &cmd->draw_cs);
1047 cmd->wait_for_idle = true;
1048
1049 tu_cs_emit_ib(cs, &cmd->state.tile_store_ib);
1050
1051 tu_cs_sanity_check(cs);
1052 }
1053
1054 static void
1055 tu6_render_end(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
1056 {
1057 VkResult result = tu_cs_reserve_space(cmd->device, cs, 16);
1058 if (result != VK_SUCCESS) {
1059 cmd->record_result = result;
1060 return;
1061 }
1062
1063 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_LRZ_CNTL, 1);
1064 tu_cs_emit(cs, A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_UNK3);
1065
1066 tu6_emit_lrz_flush(cmd, cs);
1067
1068 tu6_emit_event_write(cmd, cs, CACHE_FLUSH_TS, true);
1069
1070 tu_cs_sanity_check(cs);
1071 }
1072
1073 static void
1074 tu_cmd_render_tiles(struct tu_cmd_buffer *cmd)
1075 {
1076 const struct tu_tiling_config *tiling = &cmd->state.tiling_config;
1077
1078 tu6_render_begin(cmd, &cmd->cs);
1079
1080 for (uint32_t y = 0; y < tiling->tile_count.height; y++) {
1081 for (uint32_t x = 0; x < tiling->tile_count.width; x++) {
1082 struct tu_tile tile;
1083 tu_tiling_config_get_tile(tiling, cmd->device, x, y, &tile);
1084 tu6_render_tile(cmd, &cmd->cs, &tile);
1085 }
1086 }
1087
1088 tu6_render_end(cmd, &cmd->cs);
1089 }
1090
1091 static void
1092 tu_cmd_prepare_tile_load_ib(struct tu_cmd_buffer *cmd)
1093 {
1094 const uint32_t tile_load_space = 16 + 32 * MAX_RTS;
1095 const struct tu_subpass *subpass = cmd->state.subpass;
1096 struct tu_attachment_state *attachments = cmd->state.attachments;
1097 struct tu_cs sub_cs;
1098
1099 VkResult result = tu_cs_begin_sub_stream(cmd->device, &cmd->tile_cs,
1100 tile_load_space, &sub_cs);
1101 if (result != VK_SUCCESS) {
1102 cmd->record_result = result;
1103 return;
1104 }
1105
1106 /* emit to tile-load sub_cs */
1107 tu6_emit_tile_load(cmd, &sub_cs);
1108
1109 cmd->state.tile_load_ib = tu_cs_end_sub_stream(&cmd->tile_cs, &sub_cs);
1110
1111 for (uint32_t i = 0; i < subpass->color_count; ++i) {
1112 const uint32_t a = subpass->color_attachments[i].attachment;
1113 if (a != VK_ATTACHMENT_UNUSED)
1114 attachments[a].pending_clear_aspects = 0;
1115 }
1116 }
1117
1118 static void
1119 tu_cmd_prepare_tile_store_ib(struct tu_cmd_buffer *cmd)
1120 {
1121 const uint32_t tile_store_space = 32 + 32 * MAX_RTS;
1122 struct tu_cs sub_cs;
1123
1124 VkResult result = tu_cs_begin_sub_stream(cmd->device, &cmd->tile_cs,
1125 tile_store_space, &sub_cs);
1126 if (result != VK_SUCCESS) {
1127 cmd->record_result = result;
1128 return;
1129 }
1130
1131 /* emit to tile-store sub_cs */
1132 tu6_emit_tile_store(cmd, &sub_cs);
1133
1134 cmd->state.tile_store_ib = tu_cs_end_sub_stream(&cmd->tile_cs, &sub_cs);
1135 }
1136
1137 static void
1138 tu_cmd_update_tiling_config(struct tu_cmd_buffer *cmd,
1139 const VkRect2D *render_area)
1140 {
1141 const struct tu_device *dev = cmd->device;
1142 const struct tu_render_pass *pass = cmd->state.pass;
1143 const struct tu_subpass *subpass = cmd->state.subpass;
1144 struct tu_tiling_config *tiling = &cmd->state.tiling_config;
1145
1146 uint32_t buffer_cpp[MAX_RTS + 2];
1147 uint32_t buffer_count = 0;
1148
1149 for (uint32_t i = 0; i < subpass->color_count; ++i) {
1150 const uint32_t a = subpass->color_attachments[i].attachment;
1151 if (a == VK_ATTACHMENT_UNUSED)
1152 continue;
1153
1154 const struct tu_render_pass_attachment *att = &pass->attachments[a];
1155 buffer_cpp[buffer_count++] =
1156 vk_format_get_blocksize(att->format) * att->samples;
1157 }
1158
1159 if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
1160 const uint32_t a = subpass->depth_stencil_attachment.attachment;
1161 const struct tu_render_pass_attachment *att = &pass->attachments[a];
1162
1163 /* TODO */
1164 assert(att->format != VK_FORMAT_D32_SFLOAT_S8_UINT);
1165
1166 buffer_cpp[buffer_count++] =
1167 vk_format_get_blocksize(att->format) * att->samples;
1168 }
1169
1170 tu_tiling_config_update(tiling, dev, buffer_cpp, buffer_count,
1171 render_area);
1172 }
1173
1174 const struct tu_dynamic_state default_dynamic_state = {
1175 .viewport =
1176 {
1177 .count = 0,
1178 },
1179 .scissor =
1180 {
1181 .count = 0,
1182 },
1183 .line_width = 1.0f,
1184 .depth_bias =
1185 {
1186 .bias = 0.0f,
1187 .clamp = 0.0f,
1188 .slope = 0.0f,
1189 },
1190 .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
1191 .depth_bounds =
1192 {
1193 .min = 0.0f,
1194 .max = 1.0f,
1195 },
1196 .stencil_compare_mask =
1197 {
1198 .front = ~0u,
1199 .back = ~0u,
1200 },
1201 .stencil_write_mask =
1202 {
1203 .front = ~0u,
1204 .back = ~0u,
1205 },
1206 .stencil_reference =
1207 {
1208 .front = 0u,
1209 .back = 0u,
1210 },
1211 };
1212
1213 static void UNUSED /* FINISHME */
1214 tu_bind_dynamic_state(struct tu_cmd_buffer *cmd_buffer,
1215 const struct tu_dynamic_state *src)
1216 {
1217 struct tu_dynamic_state *dest = &cmd_buffer->state.dynamic;
1218 uint32_t copy_mask = src->mask;
1219 uint32_t dest_mask = 0;
1220
1221 tu_use_args(cmd_buffer); /* FINISHME */
1222
1223 /* Make sure to copy the number of viewports/scissors because they can
1224 * only be specified at pipeline creation time.
1225 */
1226 dest->viewport.count = src->viewport.count;
1227 dest->scissor.count = src->scissor.count;
1228 dest->discard_rectangle.count = src->discard_rectangle.count;
1229
1230 if (copy_mask & TU_DYNAMIC_VIEWPORT) {
1231 if (memcmp(&dest->viewport.viewports, &src->viewport.viewports,
1232 src->viewport.count * sizeof(VkViewport))) {
1233 typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
1234 src->viewport.count);
1235 dest_mask |= TU_DYNAMIC_VIEWPORT;
1236 }
1237 }
1238
1239 if (copy_mask & TU_DYNAMIC_SCISSOR) {
1240 if (memcmp(&dest->scissor.scissors, &src->scissor.scissors,
1241 src->scissor.count * sizeof(VkRect2D))) {
1242 typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
1243 src->scissor.count);
1244 dest_mask |= TU_DYNAMIC_SCISSOR;
1245 }
1246 }
1247
1248 if (copy_mask & TU_DYNAMIC_LINE_WIDTH) {
1249 if (dest->line_width != src->line_width) {
1250 dest->line_width = src->line_width;
1251 dest_mask |= TU_DYNAMIC_LINE_WIDTH;
1252 }
1253 }
1254
1255 if (copy_mask & TU_DYNAMIC_DEPTH_BIAS) {
1256 if (memcmp(&dest->depth_bias, &src->depth_bias,
1257 sizeof(src->depth_bias))) {
1258 dest->depth_bias = src->depth_bias;
1259 dest_mask |= TU_DYNAMIC_DEPTH_BIAS;
1260 }
1261 }
1262
1263 if (copy_mask & TU_DYNAMIC_BLEND_CONSTANTS) {
1264 if (memcmp(&dest->blend_constants, &src->blend_constants,
1265 sizeof(src->blend_constants))) {
1266 typed_memcpy(dest->blend_constants, src->blend_constants, 4);
1267 dest_mask |= TU_DYNAMIC_BLEND_CONSTANTS;
1268 }
1269 }
1270
1271 if (copy_mask & TU_DYNAMIC_DEPTH_BOUNDS) {
1272 if (memcmp(&dest->depth_bounds, &src->depth_bounds,
1273 sizeof(src->depth_bounds))) {
1274 dest->depth_bounds = src->depth_bounds;
1275 dest_mask |= TU_DYNAMIC_DEPTH_BOUNDS;
1276 }
1277 }
1278
1279 if (copy_mask & TU_DYNAMIC_STENCIL_COMPARE_MASK) {
1280 if (memcmp(&dest->stencil_compare_mask, &src->stencil_compare_mask,
1281 sizeof(src->stencil_compare_mask))) {
1282 dest->stencil_compare_mask = src->stencil_compare_mask;
1283 dest_mask |= TU_DYNAMIC_STENCIL_COMPARE_MASK;
1284 }
1285 }
1286
1287 if (copy_mask & TU_DYNAMIC_STENCIL_WRITE_MASK) {
1288 if (memcmp(&dest->stencil_write_mask, &src->stencil_write_mask,
1289 sizeof(src->stencil_write_mask))) {
1290 dest->stencil_write_mask = src->stencil_write_mask;
1291 dest_mask |= TU_DYNAMIC_STENCIL_WRITE_MASK;
1292 }
1293 }
1294
1295 if (copy_mask & TU_DYNAMIC_STENCIL_REFERENCE) {
1296 if (memcmp(&dest->stencil_reference, &src->stencil_reference,
1297 sizeof(src->stencil_reference))) {
1298 dest->stencil_reference = src->stencil_reference;
1299 dest_mask |= TU_DYNAMIC_STENCIL_REFERENCE;
1300 }
1301 }
1302
1303 if (copy_mask & TU_DYNAMIC_DISCARD_RECTANGLE) {
1304 if (memcmp(&dest->discard_rectangle.rectangles,
1305 &src->discard_rectangle.rectangles,
1306 src->discard_rectangle.count * sizeof(VkRect2D))) {
1307 typed_memcpy(dest->discard_rectangle.rectangles,
1308 src->discard_rectangle.rectangles,
1309 src->discard_rectangle.count);
1310 dest_mask |= TU_DYNAMIC_DISCARD_RECTANGLE;
1311 }
1312 }
1313 }
1314
1315 static VkResult
1316 tu_create_cmd_buffer(struct tu_device *device,
1317 struct tu_cmd_pool *pool,
1318 VkCommandBufferLevel level,
1319 VkCommandBuffer *pCommandBuffer)
1320 {
1321 struct tu_cmd_buffer *cmd_buffer;
1322 cmd_buffer = vk_zalloc(&pool->alloc, sizeof(*cmd_buffer), 8,
1323 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1324 if (cmd_buffer == NULL)
1325 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1326
1327 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
1328 cmd_buffer->device = device;
1329 cmd_buffer->pool = pool;
1330 cmd_buffer->level = level;
1331
1332 if (pool) {
1333 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
1334 cmd_buffer->queue_family_index = pool->queue_family_index;
1335
1336 } else {
1337 /* Init the pool_link so we can safely call list_del when we destroy
1338 * the command buffer
1339 */
1340 list_inithead(&cmd_buffer->pool_link);
1341 cmd_buffer->queue_family_index = TU_QUEUE_GENERAL;
1342 }
1343
1344 tu_bo_list_init(&cmd_buffer->bo_list);
1345 tu_cs_init(&cmd_buffer->cs, TU_CS_MODE_GROW, 4096);
1346 tu_cs_init(&cmd_buffer->draw_cs, TU_CS_MODE_GROW, 4096);
1347 tu_cs_init(&cmd_buffer->tile_cs, TU_CS_MODE_SUB_STREAM, 1024);
1348
1349 *pCommandBuffer = tu_cmd_buffer_to_handle(cmd_buffer);
1350
1351 list_inithead(&cmd_buffer->upload.list);
1352
1353 cmd_buffer->marker_reg = REG_A6XX_CP_SCRATCH_REG(
1354 cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY ? 7 : 6);
1355
1356 VkResult result = tu_bo_init_new(device, &cmd_buffer->scratch_bo, 0x1000);
1357 if (result != VK_SUCCESS)
1358 return result;
1359
1360 return VK_SUCCESS;
1361 }
1362
1363 static void
1364 tu_cmd_buffer_destroy(struct tu_cmd_buffer *cmd_buffer)
1365 {
1366 tu_bo_finish(cmd_buffer->device, &cmd_buffer->scratch_bo);
1367
1368 list_del(&cmd_buffer->pool_link);
1369
1370 for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++)
1371 free(cmd_buffer->descriptors[i].push_set.set.mapped_ptr);
1372
1373 tu_cs_finish(cmd_buffer->device, &cmd_buffer->cs);
1374 tu_cs_finish(cmd_buffer->device, &cmd_buffer->draw_cs);
1375 tu_cs_finish(cmd_buffer->device, &cmd_buffer->tile_cs);
1376
1377 tu_bo_list_destroy(&cmd_buffer->bo_list);
1378 vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
1379 }
1380
1381 static VkResult
1382 tu_reset_cmd_buffer(struct tu_cmd_buffer *cmd_buffer)
1383 {
1384 cmd_buffer->wait_for_idle = true;
1385
1386 cmd_buffer->record_result = VK_SUCCESS;
1387
1388 tu_bo_list_reset(&cmd_buffer->bo_list);
1389 tu_cs_reset(cmd_buffer->device, &cmd_buffer->cs);
1390 tu_cs_reset(cmd_buffer->device, &cmd_buffer->draw_cs);
1391 tu_cs_reset(cmd_buffer->device, &cmd_buffer->tile_cs);
1392
1393 for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++) {
1394 cmd_buffer->descriptors[i].dirty = 0;
1395 cmd_buffer->descriptors[i].valid = 0;
1396 cmd_buffer->descriptors[i].push_dirty = false;
1397 }
1398
1399 cmd_buffer->status = TU_CMD_BUFFER_STATUS_INITIAL;
1400
1401 return cmd_buffer->record_result;
1402 }
1403
1404 static VkResult
1405 tu_cmd_state_setup_attachments(struct tu_cmd_buffer *cmd_buffer,
1406 const VkRenderPassBeginInfo *info)
1407 {
1408 struct tu_cmd_state *state = &cmd_buffer->state;
1409 const struct tu_framebuffer *fb = state->framebuffer;
1410 const struct tu_render_pass *pass = state->pass;
1411
1412 for (uint32_t i = 0; i < fb->attachment_count; ++i) {
1413 const struct tu_image_view *iview = fb->attachments[i].attachment;
1414 tu_bo_list_add(&cmd_buffer->bo_list, iview->image->bo,
1415 MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE);
1416 }
1417
1418 if (pass->attachment_count == 0) {
1419 state->attachments = NULL;
1420 return VK_SUCCESS;
1421 }
1422
1423 state->attachments =
1424 vk_alloc(&cmd_buffer->pool->alloc,
1425 pass->attachment_count * sizeof(state->attachments[0]), 8,
1426 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1427 if (state->attachments == NULL) {
1428 cmd_buffer->record_result = VK_ERROR_OUT_OF_HOST_MEMORY;
1429 return cmd_buffer->record_result;
1430 }
1431
1432 for (uint32_t i = 0; i < pass->attachment_count; ++i) {
1433 const struct tu_render_pass_attachment *att = &pass->attachments[i];
1434 VkImageAspectFlags att_aspects = vk_format_aspects(att->format);
1435 VkImageAspectFlags clear_aspects = 0;
1436
1437 if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {
1438 /* color attachment */
1439 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1440 clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
1441 }
1442 } else {
1443 /* depthstencil attachment */
1444 if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
1445 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1446 clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
1447 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1448 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
1449 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1450 }
1451 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1452 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1453 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1454 }
1455 }
1456
1457 state->attachments[i].pending_clear_aspects = clear_aspects;
1458 state->attachments[i].cleared_views = 0;
1459 if (clear_aspects && info) {
1460 assert(info->clearValueCount > i);
1461 state->attachments[i].clear_value = info->pClearValues[i];
1462 }
1463
1464 state->attachments[i].current_layout = att->initial_layout;
1465 }
1466
1467 return VK_SUCCESS;
1468 }
1469
1470 VkResult
1471 tu_AllocateCommandBuffers(VkDevice _device,
1472 const VkCommandBufferAllocateInfo *pAllocateInfo,
1473 VkCommandBuffer *pCommandBuffers)
1474 {
1475 TU_FROM_HANDLE(tu_device, device, _device);
1476 TU_FROM_HANDLE(tu_cmd_pool, pool, pAllocateInfo->commandPool);
1477
1478 VkResult result = VK_SUCCESS;
1479 uint32_t i;
1480
1481 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
1482
1483 if (!list_empty(&pool->free_cmd_buffers)) {
1484 struct tu_cmd_buffer *cmd_buffer = list_first_entry(
1485 &pool->free_cmd_buffers, struct tu_cmd_buffer, pool_link);
1486
1487 list_del(&cmd_buffer->pool_link);
1488 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
1489
1490 result = tu_reset_cmd_buffer(cmd_buffer);
1491 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
1492 cmd_buffer->level = pAllocateInfo->level;
1493
1494 pCommandBuffers[i] = tu_cmd_buffer_to_handle(cmd_buffer);
1495 } else {
1496 result = tu_create_cmd_buffer(device, pool, pAllocateInfo->level,
1497 &pCommandBuffers[i]);
1498 }
1499 if (result != VK_SUCCESS)
1500 break;
1501 }
1502
1503 if (result != VK_SUCCESS) {
1504 tu_FreeCommandBuffers(_device, pAllocateInfo->commandPool, i,
1505 pCommandBuffers);
1506
1507 /* From the Vulkan 1.0.66 spec:
1508 *
1509 * "vkAllocateCommandBuffers can be used to create multiple
1510 * command buffers. If the creation of any of those command
1511 * buffers fails, the implementation must destroy all
1512 * successfully created command buffer objects from this
1513 * command, set all entries of the pCommandBuffers array to
1514 * NULL and return the error."
1515 */
1516 memset(pCommandBuffers, 0,
1517 sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
1518 }
1519
1520 return result;
1521 }
1522
1523 void
1524 tu_FreeCommandBuffers(VkDevice device,
1525 VkCommandPool commandPool,
1526 uint32_t commandBufferCount,
1527 const VkCommandBuffer *pCommandBuffers)
1528 {
1529 for (uint32_t i = 0; i < commandBufferCount; i++) {
1530 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
1531
1532 if (cmd_buffer) {
1533 if (cmd_buffer->pool) {
1534 list_del(&cmd_buffer->pool_link);
1535 list_addtail(&cmd_buffer->pool_link,
1536 &cmd_buffer->pool->free_cmd_buffers);
1537 } else
1538 tu_cmd_buffer_destroy(cmd_buffer);
1539 }
1540 }
1541 }
1542
1543 VkResult
1544 tu_ResetCommandBuffer(VkCommandBuffer commandBuffer,
1545 VkCommandBufferResetFlags flags)
1546 {
1547 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1548 return tu_reset_cmd_buffer(cmd_buffer);
1549 }
1550
1551 VkResult
1552 tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
1553 const VkCommandBufferBeginInfo *pBeginInfo)
1554 {
1555 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1556 VkResult result = VK_SUCCESS;
1557
1558 if (cmd_buffer->status != TU_CMD_BUFFER_STATUS_INITIAL) {
1559 /* If the command buffer has already been resetted with
1560 * vkResetCommandBuffer, no need to do it again.
1561 */
1562 result = tu_reset_cmd_buffer(cmd_buffer);
1563 if (result != VK_SUCCESS)
1564 return result;
1565 }
1566
1567 memset(&cmd_buffer->state, 0, sizeof(cmd_buffer->state));
1568 cmd_buffer->usage_flags = pBeginInfo->flags;
1569
1570 tu_cs_begin(&cmd_buffer->cs);
1571
1572 cmd_buffer->marker_seqno = 0;
1573 cmd_buffer->scratch_seqno = 0;
1574
1575 /* setup initial configuration into command buffer */
1576 if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
1577 switch (cmd_buffer->queue_family_index) {
1578 case TU_QUEUE_GENERAL:
1579 tu6_init_hw(cmd_buffer, &cmd_buffer->cs);
1580 break;
1581 default:
1582 break;
1583 }
1584 }
1585
1586 cmd_buffer->status = TU_CMD_BUFFER_STATUS_RECORDING;
1587
1588 return VK_SUCCESS;
1589 }
1590
1591 void
1592 tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
1593 uint32_t firstBinding,
1594 uint32_t bindingCount,
1595 const VkBuffer *pBuffers,
1596 const VkDeviceSize *pOffsets)
1597 {
1598 }
1599
1600 void
1601 tu_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
1602 VkBuffer buffer,
1603 VkDeviceSize offset,
1604 VkIndexType indexType)
1605 {
1606 }
1607
1608 void
1609 tu_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
1610 VkPipelineBindPoint pipelineBindPoint,
1611 VkPipelineLayout _layout,
1612 uint32_t firstSet,
1613 uint32_t descriptorSetCount,
1614 const VkDescriptorSet *pDescriptorSets,
1615 uint32_t dynamicOffsetCount,
1616 const uint32_t *pDynamicOffsets)
1617 {
1618 }
1619
1620 void
1621 tu_CmdPushConstants(VkCommandBuffer commandBuffer,
1622 VkPipelineLayout layout,
1623 VkShaderStageFlags stageFlags,
1624 uint32_t offset,
1625 uint32_t size,
1626 const void *pValues)
1627 {
1628 }
1629
1630 VkResult
1631 tu_EndCommandBuffer(VkCommandBuffer commandBuffer)
1632 {
1633 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1634
1635 if (cmd_buffer->scratch_seqno) {
1636 tu_bo_list_add(&cmd_buffer->bo_list, &cmd_buffer->scratch_bo,
1637 MSM_SUBMIT_BO_WRITE);
1638 }
1639
1640 for (uint32_t i = 0; i < cmd_buffer->draw_cs.bo_count; i++) {
1641 tu_bo_list_add(&cmd_buffer->bo_list, cmd_buffer->draw_cs.bos[i],
1642 MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_DUMP);
1643 }
1644
1645 for (uint32_t i = 0; i < cmd_buffer->tile_cs.bo_count; i++) {
1646 tu_bo_list_add(&cmd_buffer->bo_list, cmd_buffer->tile_cs.bos[i],
1647 MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_DUMP);
1648 }
1649
1650 tu_cs_end(&cmd_buffer->cs);
1651
1652 assert(!cmd_buffer->state.attachments);
1653
1654 cmd_buffer->status = TU_CMD_BUFFER_STATUS_EXECUTABLE;
1655
1656 return cmd_buffer->record_result;
1657 }
1658
1659 void
1660 tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
1661 VkPipelineBindPoint pipelineBindPoint,
1662 VkPipeline _pipeline)
1663 {
1664 }
1665
1666 void
1667 tu_CmdSetViewport(VkCommandBuffer commandBuffer,
1668 uint32_t firstViewport,
1669 uint32_t viewportCount,
1670 const VkViewport *pViewports)
1671 {
1672 }
1673
1674 void
1675 tu_CmdSetScissor(VkCommandBuffer commandBuffer,
1676 uint32_t firstScissor,
1677 uint32_t scissorCount,
1678 const VkRect2D *pScissors)
1679 {
1680 }
1681
1682 void
1683 tu_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
1684 {
1685 }
1686
1687 void
1688 tu_CmdSetDepthBias(VkCommandBuffer commandBuffer,
1689 float depthBiasConstantFactor,
1690 float depthBiasClamp,
1691 float depthBiasSlopeFactor)
1692 {
1693 }
1694
1695 void
1696 tu_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
1697 const float blendConstants[4])
1698 {
1699 }
1700
1701 void
1702 tu_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
1703 float minDepthBounds,
1704 float maxDepthBounds)
1705 {
1706 }
1707
1708 void
1709 tu_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
1710 VkStencilFaceFlags faceMask,
1711 uint32_t compareMask)
1712 {
1713 }
1714
1715 void
1716 tu_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
1717 VkStencilFaceFlags faceMask,
1718 uint32_t writeMask)
1719 {
1720 }
1721
1722 void
1723 tu_CmdSetStencilReference(VkCommandBuffer commandBuffer,
1724 VkStencilFaceFlags faceMask,
1725 uint32_t reference)
1726 {
1727 }
1728
1729 void
1730 tu_CmdExecuteCommands(VkCommandBuffer commandBuffer,
1731 uint32_t commandBufferCount,
1732 const VkCommandBuffer *pCmdBuffers)
1733 {
1734 }
1735
1736 VkResult
1737 tu_CreateCommandPool(VkDevice _device,
1738 const VkCommandPoolCreateInfo *pCreateInfo,
1739 const VkAllocationCallbacks *pAllocator,
1740 VkCommandPool *pCmdPool)
1741 {
1742 TU_FROM_HANDLE(tu_device, device, _device);
1743 struct tu_cmd_pool *pool;
1744
1745 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
1746 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1747 if (pool == NULL)
1748 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1749
1750 if (pAllocator)
1751 pool->alloc = *pAllocator;
1752 else
1753 pool->alloc = device->alloc;
1754
1755 list_inithead(&pool->cmd_buffers);
1756 list_inithead(&pool->free_cmd_buffers);
1757
1758 pool->queue_family_index = pCreateInfo->queueFamilyIndex;
1759
1760 *pCmdPool = tu_cmd_pool_to_handle(pool);
1761
1762 return VK_SUCCESS;
1763 }
1764
1765 void
1766 tu_DestroyCommandPool(VkDevice _device,
1767 VkCommandPool commandPool,
1768 const VkAllocationCallbacks *pAllocator)
1769 {
1770 TU_FROM_HANDLE(tu_device, device, _device);
1771 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1772
1773 if (!pool)
1774 return;
1775
1776 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1777 &pool->cmd_buffers, pool_link)
1778 {
1779 tu_cmd_buffer_destroy(cmd_buffer);
1780 }
1781
1782 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1783 &pool->free_cmd_buffers, pool_link)
1784 {
1785 tu_cmd_buffer_destroy(cmd_buffer);
1786 }
1787
1788 vk_free2(&device->alloc, pAllocator, pool);
1789 }
1790
1791 VkResult
1792 tu_ResetCommandPool(VkDevice device,
1793 VkCommandPool commandPool,
1794 VkCommandPoolResetFlags flags)
1795 {
1796 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1797 VkResult result;
1798
1799 list_for_each_entry(struct tu_cmd_buffer, cmd_buffer, &pool->cmd_buffers,
1800 pool_link)
1801 {
1802 result = tu_reset_cmd_buffer(cmd_buffer);
1803 if (result != VK_SUCCESS)
1804 return result;
1805 }
1806
1807 return VK_SUCCESS;
1808 }
1809
1810 void
1811 tu_TrimCommandPool(VkDevice device,
1812 VkCommandPool commandPool,
1813 VkCommandPoolTrimFlagsKHR flags)
1814 {
1815 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1816
1817 if (!pool)
1818 return;
1819
1820 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1821 &pool->free_cmd_buffers, pool_link)
1822 {
1823 tu_cmd_buffer_destroy(cmd_buffer);
1824 }
1825 }
1826
1827 void
1828 tu_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
1829 const VkRenderPassBeginInfo *pRenderPassBegin,
1830 VkSubpassContents contents)
1831 {
1832 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1833 TU_FROM_HANDLE(tu_render_pass, pass, pRenderPassBegin->renderPass);
1834 TU_FROM_HANDLE(tu_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
1835 VkResult result;
1836
1837 cmd_buffer->state.pass = pass;
1838 cmd_buffer->state.subpass = pass->subpasses;
1839 cmd_buffer->state.framebuffer = framebuffer;
1840
1841 result = tu_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
1842 if (result != VK_SUCCESS)
1843 return;
1844
1845 tu_cmd_update_tiling_config(cmd_buffer, &pRenderPassBegin->renderArea);
1846 tu_cmd_prepare_tile_load_ib(cmd_buffer);
1847 tu_cmd_prepare_tile_store_ib(cmd_buffer);
1848
1849 /* draw_cs should contain entries only for this render pass */
1850 assert(!cmd_buffer->draw_cs.entry_count);
1851 tu_cs_begin(&cmd_buffer->draw_cs);
1852 }
1853
1854 void
1855 tu_CmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
1856 const VkRenderPassBeginInfo *pRenderPassBeginInfo,
1857 const VkSubpassBeginInfoKHR *pSubpassBeginInfo)
1858 {
1859 tu_CmdBeginRenderPass(commandBuffer, pRenderPassBeginInfo,
1860 pSubpassBeginInfo->contents);
1861 }
1862
1863 void
1864 tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
1865 {
1866 TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
1867
1868 tu_cmd_render_tiles(cmd);
1869
1870 cmd->state.subpass++;
1871
1872 tu_cmd_update_tiling_config(cmd, NULL);
1873 tu_cmd_prepare_tile_load_ib(cmd);
1874 tu_cmd_prepare_tile_store_ib(cmd);
1875 }
1876
1877 void
1878 tu_CmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
1879 const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
1880 const VkSubpassEndInfoKHR *pSubpassEndInfo)
1881 {
1882 tu_CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
1883 }
1884
1885 struct tu_draw_info
1886 {
1887 /**
1888 * Number of vertices.
1889 */
1890 uint32_t count;
1891
1892 /**
1893 * Index of the first vertex.
1894 */
1895 int32_t vertex_offset;
1896
1897 /**
1898 * First instance id.
1899 */
1900 uint32_t first_instance;
1901
1902 /**
1903 * Number of instances.
1904 */
1905 uint32_t instance_count;
1906
1907 /**
1908 * First index (indexed draws only).
1909 */
1910 uint32_t first_index;
1911
1912 /**
1913 * Whether it's an indexed draw.
1914 */
1915 bool indexed;
1916
1917 /**
1918 * Indirect draw parameters resource.
1919 */
1920 struct tu_buffer *indirect;
1921 uint64_t indirect_offset;
1922 uint32_t stride;
1923
1924 /**
1925 * Draw count parameters resource.
1926 */
1927 struct tu_buffer *count_buffer;
1928 uint64_t count_buffer_offset;
1929 };
1930
1931 static void
1932 tu_draw(struct tu_cmd_buffer *cmd_buffer, const struct tu_draw_info *info)
1933 {
1934 }
1935
1936 void
1937 tu_CmdDraw(VkCommandBuffer commandBuffer,
1938 uint32_t vertexCount,
1939 uint32_t instanceCount,
1940 uint32_t firstVertex,
1941 uint32_t firstInstance)
1942 {
1943 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1944 struct tu_draw_info info = {};
1945
1946 info.count = vertexCount;
1947 info.instance_count = instanceCount;
1948 info.first_instance = firstInstance;
1949 info.vertex_offset = firstVertex;
1950
1951 tu_draw(cmd_buffer, &info);
1952 }
1953
1954 void
1955 tu_CmdDrawIndexed(VkCommandBuffer commandBuffer,
1956 uint32_t indexCount,
1957 uint32_t instanceCount,
1958 uint32_t firstIndex,
1959 int32_t vertexOffset,
1960 uint32_t firstInstance)
1961 {
1962 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1963 struct tu_draw_info info = {};
1964
1965 info.indexed = true;
1966 info.count = indexCount;
1967 info.instance_count = instanceCount;
1968 info.first_index = firstIndex;
1969 info.vertex_offset = vertexOffset;
1970 info.first_instance = firstInstance;
1971
1972 tu_draw(cmd_buffer, &info);
1973 }
1974
1975 void
1976 tu_CmdDrawIndirect(VkCommandBuffer commandBuffer,
1977 VkBuffer _buffer,
1978 VkDeviceSize offset,
1979 uint32_t drawCount,
1980 uint32_t stride)
1981 {
1982 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1983 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
1984 struct tu_draw_info info = {};
1985
1986 info.count = drawCount;
1987 info.indirect = buffer;
1988 info.indirect_offset = offset;
1989 info.stride = stride;
1990
1991 tu_draw(cmd_buffer, &info);
1992 }
1993
1994 void
1995 tu_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
1996 VkBuffer _buffer,
1997 VkDeviceSize offset,
1998 uint32_t drawCount,
1999 uint32_t stride)
2000 {
2001 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2002 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
2003 struct tu_draw_info info = {};
2004
2005 info.indexed = true;
2006 info.count = drawCount;
2007 info.indirect = buffer;
2008 info.indirect_offset = offset;
2009 info.stride = stride;
2010
2011 tu_draw(cmd_buffer, &info);
2012 }
2013
2014 struct tu_dispatch_info
2015 {
2016 /**
2017 * Determine the layout of the grid (in block units) to be used.
2018 */
2019 uint32_t blocks[3];
2020
2021 /**
2022 * A starting offset for the grid. If unaligned is set, the offset
2023 * must still be aligned.
2024 */
2025 uint32_t offsets[3];
2026 /**
2027 * Whether it's an unaligned compute dispatch.
2028 */
2029 bool unaligned;
2030
2031 /**
2032 * Indirect compute parameters resource.
2033 */
2034 struct tu_buffer *indirect;
2035 uint64_t indirect_offset;
2036 };
2037
2038 static void
2039 tu_dispatch(struct tu_cmd_buffer *cmd_buffer,
2040 const struct tu_dispatch_info *info)
2041 {
2042 }
2043
2044 void
2045 tu_CmdDispatchBase(VkCommandBuffer commandBuffer,
2046 uint32_t base_x,
2047 uint32_t base_y,
2048 uint32_t base_z,
2049 uint32_t x,
2050 uint32_t y,
2051 uint32_t z)
2052 {
2053 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2054 struct tu_dispatch_info info = {};
2055
2056 info.blocks[0] = x;
2057 info.blocks[1] = y;
2058 info.blocks[2] = z;
2059
2060 info.offsets[0] = base_x;
2061 info.offsets[1] = base_y;
2062 info.offsets[2] = base_z;
2063 tu_dispatch(cmd_buffer, &info);
2064 }
2065
2066 void
2067 tu_CmdDispatch(VkCommandBuffer commandBuffer,
2068 uint32_t x,
2069 uint32_t y,
2070 uint32_t z)
2071 {
2072 tu_CmdDispatchBase(commandBuffer, 0, 0, 0, x, y, z);
2073 }
2074
2075 void
2076 tu_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
2077 VkBuffer _buffer,
2078 VkDeviceSize offset)
2079 {
2080 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2081 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
2082 struct tu_dispatch_info info = {};
2083
2084 info.indirect = buffer;
2085 info.indirect_offset = offset;
2086
2087 tu_dispatch(cmd_buffer, &info);
2088 }
2089
2090 void
2091 tu_CmdEndRenderPass(VkCommandBuffer commandBuffer)
2092 {
2093 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2094
2095 tu_cs_end(&cmd_buffer->draw_cs);
2096
2097 tu_cmd_render_tiles(cmd_buffer);
2098
2099 /* discard draw_cs entries now that the tiles are rendered */
2100 tu_cs_discard_entries(&cmd_buffer->draw_cs);
2101
2102 vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
2103 cmd_buffer->state.attachments = NULL;
2104
2105 cmd_buffer->state.pass = NULL;
2106 cmd_buffer->state.subpass = NULL;
2107 cmd_buffer->state.framebuffer = NULL;
2108 }
2109
2110 void
2111 tu_CmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
2112 const VkSubpassEndInfoKHR *pSubpassEndInfo)
2113 {
2114 tu_CmdEndRenderPass(commandBuffer);
2115 }
2116
2117 struct tu_barrier_info
2118 {
2119 uint32_t eventCount;
2120 const VkEvent *pEvents;
2121 VkPipelineStageFlags srcStageMask;
2122 };
2123
2124 static void
2125 tu_barrier(struct tu_cmd_buffer *cmd_buffer,
2126 uint32_t memoryBarrierCount,
2127 const VkMemoryBarrier *pMemoryBarriers,
2128 uint32_t bufferMemoryBarrierCount,
2129 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2130 uint32_t imageMemoryBarrierCount,
2131 const VkImageMemoryBarrier *pImageMemoryBarriers,
2132 const struct tu_barrier_info *info)
2133 {
2134 }
2135
2136 void
2137 tu_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
2138 VkPipelineStageFlags srcStageMask,
2139 VkPipelineStageFlags destStageMask,
2140 VkBool32 byRegion,
2141 uint32_t memoryBarrierCount,
2142 const VkMemoryBarrier *pMemoryBarriers,
2143 uint32_t bufferMemoryBarrierCount,
2144 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2145 uint32_t imageMemoryBarrierCount,
2146 const VkImageMemoryBarrier *pImageMemoryBarriers)
2147 {
2148 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2149 struct tu_barrier_info info;
2150
2151 info.eventCount = 0;
2152 info.pEvents = NULL;
2153 info.srcStageMask = srcStageMask;
2154
2155 tu_barrier(cmd_buffer, memoryBarrierCount, pMemoryBarriers,
2156 bufferMemoryBarrierCount, pBufferMemoryBarriers,
2157 imageMemoryBarrierCount, pImageMemoryBarriers, &info);
2158 }
2159
2160 static void
2161 write_event(struct tu_cmd_buffer *cmd_buffer,
2162 struct tu_event *event,
2163 VkPipelineStageFlags stageMask,
2164 unsigned value)
2165 {
2166 }
2167
2168 void
2169 tu_CmdSetEvent(VkCommandBuffer commandBuffer,
2170 VkEvent _event,
2171 VkPipelineStageFlags stageMask)
2172 {
2173 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2174 TU_FROM_HANDLE(tu_event, event, _event);
2175
2176 write_event(cmd_buffer, event, stageMask, 1);
2177 }
2178
2179 void
2180 tu_CmdResetEvent(VkCommandBuffer commandBuffer,
2181 VkEvent _event,
2182 VkPipelineStageFlags stageMask)
2183 {
2184 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2185 TU_FROM_HANDLE(tu_event, event, _event);
2186
2187 write_event(cmd_buffer, event, stageMask, 0);
2188 }
2189
2190 void
2191 tu_CmdWaitEvents(VkCommandBuffer commandBuffer,
2192 uint32_t eventCount,
2193 const VkEvent *pEvents,
2194 VkPipelineStageFlags srcStageMask,
2195 VkPipelineStageFlags dstStageMask,
2196 uint32_t memoryBarrierCount,
2197 const VkMemoryBarrier *pMemoryBarriers,
2198 uint32_t bufferMemoryBarrierCount,
2199 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2200 uint32_t imageMemoryBarrierCount,
2201 const VkImageMemoryBarrier *pImageMemoryBarriers)
2202 {
2203 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2204 struct tu_barrier_info info;
2205
2206 info.eventCount = eventCount;
2207 info.pEvents = pEvents;
2208 info.srcStageMask = 0;
2209
2210 tu_barrier(cmd_buffer, memoryBarrierCount, pMemoryBarriers,
2211 bufferMemoryBarrierCount, pBufferMemoryBarriers,
2212 imageMemoryBarrierCount, pImageMemoryBarriers, &info);
2213 }
2214
2215 void
2216 tu_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
2217 {
2218 /* No-op */
2219 }