ef07bd6c27bcc3c04b46d97c38b6440cc01f54a0
[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 VkResult result = tu_cs_reserve_space(cmd->device, cs, 64);
1037 if (result != VK_SUCCESS) {
1038 cmd->record_result = result;
1039 return;
1040 }
1041
1042 tu6_emit_tile_select(cmd, cs, tile);
1043 tu_cs_emit_ib(cs, &cmd->state.tile_load_ib);
1044
1045 /* draw IB? */
1046
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->tile_cs, TU_CS_MODE_SUB_STREAM, 1024);
1347
1348 *pCommandBuffer = tu_cmd_buffer_to_handle(cmd_buffer);
1349
1350 list_inithead(&cmd_buffer->upload.list);
1351
1352 cmd_buffer->marker_reg = REG_A6XX_CP_SCRATCH_REG(
1353 cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY ? 7 : 6);
1354
1355 VkResult result = tu_bo_init_new(device, &cmd_buffer->scratch_bo, 0x1000);
1356 if (result != VK_SUCCESS)
1357 return result;
1358
1359 return VK_SUCCESS;
1360 }
1361
1362 static void
1363 tu_cmd_buffer_destroy(struct tu_cmd_buffer *cmd_buffer)
1364 {
1365 tu_bo_finish(cmd_buffer->device, &cmd_buffer->scratch_bo);
1366
1367 list_del(&cmd_buffer->pool_link);
1368
1369 for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++)
1370 free(cmd_buffer->descriptors[i].push_set.set.mapped_ptr);
1371
1372 tu_cs_finish(cmd_buffer->device, &cmd_buffer->cs);
1373 tu_cs_finish(cmd_buffer->device, &cmd_buffer->tile_cs);
1374
1375 tu_bo_list_destroy(&cmd_buffer->bo_list);
1376 vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
1377 }
1378
1379 static VkResult
1380 tu_reset_cmd_buffer(struct tu_cmd_buffer *cmd_buffer)
1381 {
1382 cmd_buffer->wait_for_idle = true;
1383
1384 cmd_buffer->record_result = VK_SUCCESS;
1385
1386 tu_bo_list_reset(&cmd_buffer->bo_list);
1387 tu_cs_reset(cmd_buffer->device, &cmd_buffer->cs);
1388 tu_cs_reset(cmd_buffer->device, &cmd_buffer->tile_cs);
1389
1390 for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++) {
1391 cmd_buffer->descriptors[i].dirty = 0;
1392 cmd_buffer->descriptors[i].valid = 0;
1393 cmd_buffer->descriptors[i].push_dirty = false;
1394 }
1395
1396 cmd_buffer->status = TU_CMD_BUFFER_STATUS_INITIAL;
1397
1398 return cmd_buffer->record_result;
1399 }
1400
1401 static VkResult
1402 tu_cmd_state_setup_attachments(struct tu_cmd_buffer *cmd_buffer,
1403 const VkRenderPassBeginInfo *info)
1404 {
1405 struct tu_cmd_state *state = &cmd_buffer->state;
1406 const struct tu_framebuffer *fb = state->framebuffer;
1407 const struct tu_render_pass *pass = state->pass;
1408
1409 for (uint32_t i = 0; i < fb->attachment_count; ++i) {
1410 const struct tu_image_view *iview = fb->attachments[i].attachment;
1411 tu_bo_list_add(&cmd_buffer->bo_list, iview->image->bo,
1412 MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE);
1413 }
1414
1415 if (pass->attachment_count == 0) {
1416 state->attachments = NULL;
1417 return VK_SUCCESS;
1418 }
1419
1420 state->attachments =
1421 vk_alloc(&cmd_buffer->pool->alloc,
1422 pass->attachment_count * sizeof(state->attachments[0]), 8,
1423 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1424 if (state->attachments == NULL) {
1425 cmd_buffer->record_result = VK_ERROR_OUT_OF_HOST_MEMORY;
1426 return cmd_buffer->record_result;
1427 }
1428
1429 for (uint32_t i = 0; i < pass->attachment_count; ++i) {
1430 const struct tu_render_pass_attachment *att = &pass->attachments[i];
1431 VkImageAspectFlags att_aspects = vk_format_aspects(att->format);
1432 VkImageAspectFlags clear_aspects = 0;
1433
1434 if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {
1435 /* color attachment */
1436 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1437 clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
1438 }
1439 } else {
1440 /* depthstencil attachment */
1441 if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
1442 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1443 clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
1444 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1445 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
1446 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1447 }
1448 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1449 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1450 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1451 }
1452 }
1453
1454 state->attachments[i].pending_clear_aspects = clear_aspects;
1455 state->attachments[i].cleared_views = 0;
1456 if (clear_aspects && info) {
1457 assert(info->clearValueCount > i);
1458 state->attachments[i].clear_value = info->pClearValues[i];
1459 }
1460
1461 state->attachments[i].current_layout = att->initial_layout;
1462 }
1463
1464 return VK_SUCCESS;
1465 }
1466
1467 VkResult
1468 tu_AllocateCommandBuffers(VkDevice _device,
1469 const VkCommandBufferAllocateInfo *pAllocateInfo,
1470 VkCommandBuffer *pCommandBuffers)
1471 {
1472 TU_FROM_HANDLE(tu_device, device, _device);
1473 TU_FROM_HANDLE(tu_cmd_pool, pool, pAllocateInfo->commandPool);
1474
1475 VkResult result = VK_SUCCESS;
1476 uint32_t i;
1477
1478 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
1479
1480 if (!list_empty(&pool->free_cmd_buffers)) {
1481 struct tu_cmd_buffer *cmd_buffer = list_first_entry(
1482 &pool->free_cmd_buffers, struct tu_cmd_buffer, pool_link);
1483
1484 list_del(&cmd_buffer->pool_link);
1485 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
1486
1487 result = tu_reset_cmd_buffer(cmd_buffer);
1488 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
1489 cmd_buffer->level = pAllocateInfo->level;
1490
1491 pCommandBuffers[i] = tu_cmd_buffer_to_handle(cmd_buffer);
1492 } else {
1493 result = tu_create_cmd_buffer(device, pool, pAllocateInfo->level,
1494 &pCommandBuffers[i]);
1495 }
1496 if (result != VK_SUCCESS)
1497 break;
1498 }
1499
1500 if (result != VK_SUCCESS) {
1501 tu_FreeCommandBuffers(_device, pAllocateInfo->commandPool, i,
1502 pCommandBuffers);
1503
1504 /* From the Vulkan 1.0.66 spec:
1505 *
1506 * "vkAllocateCommandBuffers can be used to create multiple
1507 * command buffers. If the creation of any of those command
1508 * buffers fails, the implementation must destroy all
1509 * successfully created command buffer objects from this
1510 * command, set all entries of the pCommandBuffers array to
1511 * NULL and return the error."
1512 */
1513 memset(pCommandBuffers, 0,
1514 sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
1515 }
1516
1517 return result;
1518 }
1519
1520 void
1521 tu_FreeCommandBuffers(VkDevice device,
1522 VkCommandPool commandPool,
1523 uint32_t commandBufferCount,
1524 const VkCommandBuffer *pCommandBuffers)
1525 {
1526 for (uint32_t i = 0; i < commandBufferCount; i++) {
1527 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
1528
1529 if (cmd_buffer) {
1530 if (cmd_buffer->pool) {
1531 list_del(&cmd_buffer->pool_link);
1532 list_addtail(&cmd_buffer->pool_link,
1533 &cmd_buffer->pool->free_cmd_buffers);
1534 } else
1535 tu_cmd_buffer_destroy(cmd_buffer);
1536 }
1537 }
1538 }
1539
1540 VkResult
1541 tu_ResetCommandBuffer(VkCommandBuffer commandBuffer,
1542 VkCommandBufferResetFlags flags)
1543 {
1544 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1545 return tu_reset_cmd_buffer(cmd_buffer);
1546 }
1547
1548 VkResult
1549 tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
1550 const VkCommandBufferBeginInfo *pBeginInfo)
1551 {
1552 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1553 VkResult result = VK_SUCCESS;
1554
1555 if (cmd_buffer->status != TU_CMD_BUFFER_STATUS_INITIAL) {
1556 /* If the command buffer has already been resetted with
1557 * vkResetCommandBuffer, no need to do it again.
1558 */
1559 result = tu_reset_cmd_buffer(cmd_buffer);
1560 if (result != VK_SUCCESS)
1561 return result;
1562 }
1563
1564 memset(&cmd_buffer->state, 0, sizeof(cmd_buffer->state));
1565 cmd_buffer->usage_flags = pBeginInfo->flags;
1566
1567 tu_cs_begin(&cmd_buffer->cs);
1568
1569 cmd_buffer->marker_seqno = 0;
1570 cmd_buffer->scratch_seqno = 0;
1571
1572 /* setup initial configuration into command buffer */
1573 if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
1574 switch (cmd_buffer->queue_family_index) {
1575 case TU_QUEUE_GENERAL:
1576 tu6_init_hw(cmd_buffer, &cmd_buffer->cs);
1577 break;
1578 default:
1579 break;
1580 }
1581 }
1582
1583 cmd_buffer->status = TU_CMD_BUFFER_STATUS_RECORDING;
1584
1585 return VK_SUCCESS;
1586 }
1587
1588 void
1589 tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
1590 uint32_t firstBinding,
1591 uint32_t bindingCount,
1592 const VkBuffer *pBuffers,
1593 const VkDeviceSize *pOffsets)
1594 {
1595 }
1596
1597 void
1598 tu_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
1599 VkBuffer buffer,
1600 VkDeviceSize offset,
1601 VkIndexType indexType)
1602 {
1603 }
1604
1605 void
1606 tu_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
1607 VkPipelineBindPoint pipelineBindPoint,
1608 VkPipelineLayout _layout,
1609 uint32_t firstSet,
1610 uint32_t descriptorSetCount,
1611 const VkDescriptorSet *pDescriptorSets,
1612 uint32_t dynamicOffsetCount,
1613 const uint32_t *pDynamicOffsets)
1614 {
1615 }
1616
1617 void
1618 tu_CmdPushConstants(VkCommandBuffer commandBuffer,
1619 VkPipelineLayout layout,
1620 VkShaderStageFlags stageFlags,
1621 uint32_t offset,
1622 uint32_t size,
1623 const void *pValues)
1624 {
1625 }
1626
1627 VkResult
1628 tu_EndCommandBuffer(VkCommandBuffer commandBuffer)
1629 {
1630 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1631
1632 if (cmd_buffer->scratch_seqno) {
1633 tu_bo_list_add(&cmd_buffer->bo_list, &cmd_buffer->scratch_bo,
1634 MSM_SUBMIT_BO_WRITE);
1635 }
1636
1637 for (uint32_t i = 0; i < cmd_buffer->tile_cs.bo_count; i++) {
1638 tu_bo_list_add(&cmd_buffer->bo_list, cmd_buffer->tile_cs.bos[i],
1639 MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_DUMP);
1640 }
1641
1642 tu_cs_end(&cmd_buffer->cs);
1643
1644 assert(!cmd_buffer->state.attachments);
1645
1646 cmd_buffer->status = TU_CMD_BUFFER_STATUS_EXECUTABLE;
1647
1648 return cmd_buffer->record_result;
1649 }
1650
1651 void
1652 tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
1653 VkPipelineBindPoint pipelineBindPoint,
1654 VkPipeline _pipeline)
1655 {
1656 }
1657
1658 void
1659 tu_CmdSetViewport(VkCommandBuffer commandBuffer,
1660 uint32_t firstViewport,
1661 uint32_t viewportCount,
1662 const VkViewport *pViewports)
1663 {
1664 }
1665
1666 void
1667 tu_CmdSetScissor(VkCommandBuffer commandBuffer,
1668 uint32_t firstScissor,
1669 uint32_t scissorCount,
1670 const VkRect2D *pScissors)
1671 {
1672 }
1673
1674 void
1675 tu_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
1676 {
1677 }
1678
1679 void
1680 tu_CmdSetDepthBias(VkCommandBuffer commandBuffer,
1681 float depthBiasConstantFactor,
1682 float depthBiasClamp,
1683 float depthBiasSlopeFactor)
1684 {
1685 }
1686
1687 void
1688 tu_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
1689 const float blendConstants[4])
1690 {
1691 }
1692
1693 void
1694 tu_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
1695 float minDepthBounds,
1696 float maxDepthBounds)
1697 {
1698 }
1699
1700 void
1701 tu_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
1702 VkStencilFaceFlags faceMask,
1703 uint32_t compareMask)
1704 {
1705 }
1706
1707 void
1708 tu_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
1709 VkStencilFaceFlags faceMask,
1710 uint32_t writeMask)
1711 {
1712 }
1713
1714 void
1715 tu_CmdSetStencilReference(VkCommandBuffer commandBuffer,
1716 VkStencilFaceFlags faceMask,
1717 uint32_t reference)
1718 {
1719 }
1720
1721 void
1722 tu_CmdExecuteCommands(VkCommandBuffer commandBuffer,
1723 uint32_t commandBufferCount,
1724 const VkCommandBuffer *pCmdBuffers)
1725 {
1726 }
1727
1728 VkResult
1729 tu_CreateCommandPool(VkDevice _device,
1730 const VkCommandPoolCreateInfo *pCreateInfo,
1731 const VkAllocationCallbacks *pAllocator,
1732 VkCommandPool *pCmdPool)
1733 {
1734 TU_FROM_HANDLE(tu_device, device, _device);
1735 struct tu_cmd_pool *pool;
1736
1737 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
1738 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1739 if (pool == NULL)
1740 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1741
1742 if (pAllocator)
1743 pool->alloc = *pAllocator;
1744 else
1745 pool->alloc = device->alloc;
1746
1747 list_inithead(&pool->cmd_buffers);
1748 list_inithead(&pool->free_cmd_buffers);
1749
1750 pool->queue_family_index = pCreateInfo->queueFamilyIndex;
1751
1752 *pCmdPool = tu_cmd_pool_to_handle(pool);
1753
1754 return VK_SUCCESS;
1755 }
1756
1757 void
1758 tu_DestroyCommandPool(VkDevice _device,
1759 VkCommandPool commandPool,
1760 const VkAllocationCallbacks *pAllocator)
1761 {
1762 TU_FROM_HANDLE(tu_device, device, _device);
1763 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1764
1765 if (!pool)
1766 return;
1767
1768 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1769 &pool->cmd_buffers, pool_link)
1770 {
1771 tu_cmd_buffer_destroy(cmd_buffer);
1772 }
1773
1774 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1775 &pool->free_cmd_buffers, pool_link)
1776 {
1777 tu_cmd_buffer_destroy(cmd_buffer);
1778 }
1779
1780 vk_free2(&device->alloc, pAllocator, pool);
1781 }
1782
1783 VkResult
1784 tu_ResetCommandPool(VkDevice device,
1785 VkCommandPool commandPool,
1786 VkCommandPoolResetFlags flags)
1787 {
1788 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1789 VkResult result;
1790
1791 list_for_each_entry(struct tu_cmd_buffer, cmd_buffer, &pool->cmd_buffers,
1792 pool_link)
1793 {
1794 result = tu_reset_cmd_buffer(cmd_buffer);
1795 if (result != VK_SUCCESS)
1796 return result;
1797 }
1798
1799 return VK_SUCCESS;
1800 }
1801
1802 void
1803 tu_TrimCommandPool(VkDevice device,
1804 VkCommandPool commandPool,
1805 VkCommandPoolTrimFlagsKHR flags)
1806 {
1807 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1808
1809 if (!pool)
1810 return;
1811
1812 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1813 &pool->free_cmd_buffers, pool_link)
1814 {
1815 tu_cmd_buffer_destroy(cmd_buffer);
1816 }
1817 }
1818
1819 void
1820 tu_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
1821 const VkRenderPassBeginInfo *pRenderPassBegin,
1822 VkSubpassContents contents)
1823 {
1824 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1825 TU_FROM_HANDLE(tu_render_pass, pass, pRenderPassBegin->renderPass);
1826 TU_FROM_HANDLE(tu_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
1827 VkResult result;
1828
1829 cmd_buffer->state.pass = pass;
1830 cmd_buffer->state.subpass = pass->subpasses;
1831 cmd_buffer->state.framebuffer = framebuffer;
1832
1833 result = tu_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
1834 if (result != VK_SUCCESS)
1835 return;
1836
1837 tu_cmd_update_tiling_config(cmd_buffer, &pRenderPassBegin->renderArea);
1838 tu_cmd_prepare_tile_load_ib(cmd_buffer);
1839 tu_cmd_prepare_tile_store_ib(cmd_buffer);
1840 }
1841
1842 void
1843 tu_CmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
1844 const VkRenderPassBeginInfo *pRenderPassBeginInfo,
1845 const VkSubpassBeginInfoKHR *pSubpassBeginInfo)
1846 {
1847 tu_CmdBeginRenderPass(commandBuffer, pRenderPassBeginInfo,
1848 pSubpassBeginInfo->contents);
1849 }
1850
1851 void
1852 tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
1853 {
1854 TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
1855
1856 tu_cmd_render_tiles(cmd);
1857
1858 cmd->state.subpass++;
1859
1860 tu_cmd_update_tiling_config(cmd, NULL);
1861 tu_cmd_prepare_tile_load_ib(cmd);
1862 tu_cmd_prepare_tile_store_ib(cmd);
1863 }
1864
1865 void
1866 tu_CmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
1867 const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
1868 const VkSubpassEndInfoKHR *pSubpassEndInfo)
1869 {
1870 tu_CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
1871 }
1872
1873 struct tu_draw_info
1874 {
1875 /**
1876 * Number of vertices.
1877 */
1878 uint32_t count;
1879
1880 /**
1881 * Index of the first vertex.
1882 */
1883 int32_t vertex_offset;
1884
1885 /**
1886 * First instance id.
1887 */
1888 uint32_t first_instance;
1889
1890 /**
1891 * Number of instances.
1892 */
1893 uint32_t instance_count;
1894
1895 /**
1896 * First index (indexed draws only).
1897 */
1898 uint32_t first_index;
1899
1900 /**
1901 * Whether it's an indexed draw.
1902 */
1903 bool indexed;
1904
1905 /**
1906 * Indirect draw parameters resource.
1907 */
1908 struct tu_buffer *indirect;
1909 uint64_t indirect_offset;
1910 uint32_t stride;
1911
1912 /**
1913 * Draw count parameters resource.
1914 */
1915 struct tu_buffer *count_buffer;
1916 uint64_t count_buffer_offset;
1917 };
1918
1919 static void
1920 tu_draw(struct tu_cmd_buffer *cmd_buffer, const struct tu_draw_info *info)
1921 {
1922 }
1923
1924 void
1925 tu_CmdDraw(VkCommandBuffer commandBuffer,
1926 uint32_t vertexCount,
1927 uint32_t instanceCount,
1928 uint32_t firstVertex,
1929 uint32_t firstInstance)
1930 {
1931 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1932 struct tu_draw_info info = {};
1933
1934 info.count = vertexCount;
1935 info.instance_count = instanceCount;
1936 info.first_instance = firstInstance;
1937 info.vertex_offset = firstVertex;
1938
1939 tu_draw(cmd_buffer, &info);
1940 }
1941
1942 void
1943 tu_CmdDrawIndexed(VkCommandBuffer commandBuffer,
1944 uint32_t indexCount,
1945 uint32_t instanceCount,
1946 uint32_t firstIndex,
1947 int32_t vertexOffset,
1948 uint32_t firstInstance)
1949 {
1950 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1951 struct tu_draw_info info = {};
1952
1953 info.indexed = true;
1954 info.count = indexCount;
1955 info.instance_count = instanceCount;
1956 info.first_index = firstIndex;
1957 info.vertex_offset = vertexOffset;
1958 info.first_instance = firstInstance;
1959
1960 tu_draw(cmd_buffer, &info);
1961 }
1962
1963 void
1964 tu_CmdDrawIndirect(VkCommandBuffer commandBuffer,
1965 VkBuffer _buffer,
1966 VkDeviceSize offset,
1967 uint32_t drawCount,
1968 uint32_t stride)
1969 {
1970 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1971 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
1972 struct tu_draw_info info = {};
1973
1974 info.count = drawCount;
1975 info.indirect = buffer;
1976 info.indirect_offset = offset;
1977 info.stride = stride;
1978
1979 tu_draw(cmd_buffer, &info);
1980 }
1981
1982 void
1983 tu_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
1984 VkBuffer _buffer,
1985 VkDeviceSize offset,
1986 uint32_t drawCount,
1987 uint32_t stride)
1988 {
1989 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1990 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
1991 struct tu_draw_info info = {};
1992
1993 info.indexed = true;
1994 info.count = drawCount;
1995 info.indirect = buffer;
1996 info.indirect_offset = offset;
1997 info.stride = stride;
1998
1999 tu_draw(cmd_buffer, &info);
2000 }
2001
2002 struct tu_dispatch_info
2003 {
2004 /**
2005 * Determine the layout of the grid (in block units) to be used.
2006 */
2007 uint32_t blocks[3];
2008
2009 /**
2010 * A starting offset for the grid. If unaligned is set, the offset
2011 * must still be aligned.
2012 */
2013 uint32_t offsets[3];
2014 /**
2015 * Whether it's an unaligned compute dispatch.
2016 */
2017 bool unaligned;
2018
2019 /**
2020 * Indirect compute parameters resource.
2021 */
2022 struct tu_buffer *indirect;
2023 uint64_t indirect_offset;
2024 };
2025
2026 static void
2027 tu_dispatch(struct tu_cmd_buffer *cmd_buffer,
2028 const struct tu_dispatch_info *info)
2029 {
2030 }
2031
2032 void
2033 tu_CmdDispatchBase(VkCommandBuffer commandBuffer,
2034 uint32_t base_x,
2035 uint32_t base_y,
2036 uint32_t base_z,
2037 uint32_t x,
2038 uint32_t y,
2039 uint32_t z)
2040 {
2041 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2042 struct tu_dispatch_info info = {};
2043
2044 info.blocks[0] = x;
2045 info.blocks[1] = y;
2046 info.blocks[2] = z;
2047
2048 info.offsets[0] = base_x;
2049 info.offsets[1] = base_y;
2050 info.offsets[2] = base_z;
2051 tu_dispatch(cmd_buffer, &info);
2052 }
2053
2054 void
2055 tu_CmdDispatch(VkCommandBuffer commandBuffer,
2056 uint32_t x,
2057 uint32_t y,
2058 uint32_t z)
2059 {
2060 tu_CmdDispatchBase(commandBuffer, 0, 0, 0, x, y, z);
2061 }
2062
2063 void
2064 tu_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
2065 VkBuffer _buffer,
2066 VkDeviceSize offset)
2067 {
2068 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2069 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
2070 struct tu_dispatch_info info = {};
2071
2072 info.indirect = buffer;
2073 info.indirect_offset = offset;
2074
2075 tu_dispatch(cmd_buffer, &info);
2076 }
2077
2078 void
2079 tu_CmdEndRenderPass(VkCommandBuffer commandBuffer)
2080 {
2081 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2082
2083 tu_cmd_render_tiles(cmd_buffer);
2084
2085 vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
2086 cmd_buffer->state.attachments = NULL;
2087
2088 cmd_buffer->state.pass = NULL;
2089 cmd_buffer->state.subpass = NULL;
2090 cmd_buffer->state.framebuffer = NULL;
2091 }
2092
2093 void
2094 tu_CmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
2095 const VkSubpassEndInfoKHR *pSubpassEndInfo)
2096 {
2097 tu_CmdEndRenderPass(commandBuffer);
2098 }
2099
2100 struct tu_barrier_info
2101 {
2102 uint32_t eventCount;
2103 const VkEvent *pEvents;
2104 VkPipelineStageFlags srcStageMask;
2105 };
2106
2107 static void
2108 tu_barrier(struct tu_cmd_buffer *cmd_buffer,
2109 uint32_t memoryBarrierCount,
2110 const VkMemoryBarrier *pMemoryBarriers,
2111 uint32_t bufferMemoryBarrierCount,
2112 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2113 uint32_t imageMemoryBarrierCount,
2114 const VkImageMemoryBarrier *pImageMemoryBarriers,
2115 const struct tu_barrier_info *info)
2116 {
2117 }
2118
2119 void
2120 tu_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
2121 VkPipelineStageFlags srcStageMask,
2122 VkPipelineStageFlags destStageMask,
2123 VkBool32 byRegion,
2124 uint32_t memoryBarrierCount,
2125 const VkMemoryBarrier *pMemoryBarriers,
2126 uint32_t bufferMemoryBarrierCount,
2127 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2128 uint32_t imageMemoryBarrierCount,
2129 const VkImageMemoryBarrier *pImageMemoryBarriers)
2130 {
2131 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2132 struct tu_barrier_info info;
2133
2134 info.eventCount = 0;
2135 info.pEvents = NULL;
2136 info.srcStageMask = srcStageMask;
2137
2138 tu_barrier(cmd_buffer, memoryBarrierCount, pMemoryBarriers,
2139 bufferMemoryBarrierCount, pBufferMemoryBarriers,
2140 imageMemoryBarrierCount, pImageMemoryBarriers, &info);
2141 }
2142
2143 static void
2144 write_event(struct tu_cmd_buffer *cmd_buffer,
2145 struct tu_event *event,
2146 VkPipelineStageFlags stageMask,
2147 unsigned value)
2148 {
2149 }
2150
2151 void
2152 tu_CmdSetEvent(VkCommandBuffer commandBuffer,
2153 VkEvent _event,
2154 VkPipelineStageFlags stageMask)
2155 {
2156 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2157 TU_FROM_HANDLE(tu_event, event, _event);
2158
2159 write_event(cmd_buffer, event, stageMask, 1);
2160 }
2161
2162 void
2163 tu_CmdResetEvent(VkCommandBuffer commandBuffer,
2164 VkEvent _event,
2165 VkPipelineStageFlags stageMask)
2166 {
2167 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2168 TU_FROM_HANDLE(tu_event, event, _event);
2169
2170 write_event(cmd_buffer, event, stageMask, 0);
2171 }
2172
2173 void
2174 tu_CmdWaitEvents(VkCommandBuffer commandBuffer,
2175 uint32_t eventCount,
2176 const VkEvent *pEvents,
2177 VkPipelineStageFlags srcStageMask,
2178 VkPipelineStageFlags dstStageMask,
2179 uint32_t memoryBarrierCount,
2180 const VkMemoryBarrier *pMemoryBarriers,
2181 uint32_t bufferMemoryBarrierCount,
2182 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2183 uint32_t imageMemoryBarrierCount,
2184 const VkImageMemoryBarrier *pImageMemoryBarriers)
2185 {
2186 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2187 struct tu_barrier_info info;
2188
2189 info.eventCount = eventCount;
2190 info.pEvents = pEvents;
2191 info.srcStageMask = 0;
2192
2193 tu_barrier(cmd_buffer, memoryBarrierCount, pMemoryBarriers,
2194 bufferMemoryBarrierCount, pBufferMemoryBarriers,
2195 imageMemoryBarrierCount, pImageMemoryBarriers, &info);
2196 }
2197
2198 void
2199 tu_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
2200 {
2201 /* No-op */
2202 }