turnip: Make tu6_emit_event_write shared.
[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 tu_cs_reserve_space(cmd->device, &sub_cs, tile_load_space);
1108 tu6_emit_tile_load(cmd, &sub_cs);
1109 tu_cs_sanity_check(&sub_cs);
1110
1111 cmd->state.tile_load_ib = tu_cs_end_sub_stream(&cmd->tile_cs, &sub_cs);
1112
1113 for (uint32_t i = 0; i < subpass->color_count; ++i) {
1114 const uint32_t a = subpass->color_attachments[i].attachment;
1115 if (a != VK_ATTACHMENT_UNUSED)
1116 attachments[a].pending_clear_aspects = 0;
1117 }
1118 }
1119
1120 static void
1121 tu_cmd_prepare_tile_store_ib(struct tu_cmd_buffer *cmd)
1122 {
1123 const uint32_t tile_store_space = 32 + 32 * MAX_RTS;
1124 struct tu_cs sub_cs;
1125
1126 VkResult result = tu_cs_begin_sub_stream(cmd->device, &cmd->tile_cs,
1127 tile_store_space, &sub_cs);
1128 if (result != VK_SUCCESS) {
1129 cmd->record_result = result;
1130 return;
1131 }
1132
1133 /* emit to tile-store sub_cs */
1134 tu_cs_reserve_space(cmd->device, &sub_cs, tile_store_space);
1135 tu6_emit_tile_store(cmd, &sub_cs);
1136 tu_cs_sanity_check(&sub_cs);
1137
1138 cmd->state.tile_store_ib = tu_cs_end_sub_stream(&cmd->tile_cs, &sub_cs);
1139 }
1140
1141 static void
1142 tu_cmd_update_tiling_config(struct tu_cmd_buffer *cmd,
1143 const VkRect2D *render_area)
1144 {
1145 const struct tu_device *dev = cmd->device;
1146 const struct tu_render_pass *pass = cmd->state.pass;
1147 const struct tu_subpass *subpass = cmd->state.subpass;
1148 struct tu_tiling_config *tiling = &cmd->state.tiling_config;
1149
1150 uint32_t buffer_cpp[MAX_RTS + 2];
1151 uint32_t buffer_count = 0;
1152
1153 for (uint32_t i = 0; i < subpass->color_count; ++i) {
1154 const uint32_t a = subpass->color_attachments[i].attachment;
1155 if (a == VK_ATTACHMENT_UNUSED)
1156 continue;
1157
1158 const struct tu_render_pass_attachment *att = &pass->attachments[a];
1159 buffer_cpp[buffer_count++] =
1160 vk_format_get_blocksize(att->format) * att->samples;
1161 }
1162
1163 if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
1164 const uint32_t a = subpass->depth_stencil_attachment.attachment;
1165 const struct tu_render_pass_attachment *att = &pass->attachments[a];
1166
1167 /* TODO */
1168 assert(att->format != VK_FORMAT_D32_SFLOAT_S8_UINT);
1169
1170 buffer_cpp[buffer_count++] =
1171 vk_format_get_blocksize(att->format) * att->samples;
1172 }
1173
1174 tu_tiling_config_update(tiling, dev, buffer_cpp, buffer_count,
1175 render_area);
1176 }
1177
1178 const struct tu_dynamic_state default_dynamic_state = {
1179 .viewport =
1180 {
1181 .count = 0,
1182 },
1183 .scissor =
1184 {
1185 .count = 0,
1186 },
1187 .line_width = 1.0f,
1188 .depth_bias =
1189 {
1190 .bias = 0.0f,
1191 .clamp = 0.0f,
1192 .slope = 0.0f,
1193 },
1194 .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
1195 .depth_bounds =
1196 {
1197 .min = 0.0f,
1198 .max = 1.0f,
1199 },
1200 .stencil_compare_mask =
1201 {
1202 .front = ~0u,
1203 .back = ~0u,
1204 },
1205 .stencil_write_mask =
1206 {
1207 .front = ~0u,
1208 .back = ~0u,
1209 },
1210 .stencil_reference =
1211 {
1212 .front = 0u,
1213 .back = 0u,
1214 },
1215 };
1216
1217 static void UNUSED /* FINISHME */
1218 tu_bind_dynamic_state(struct tu_cmd_buffer *cmd_buffer,
1219 const struct tu_dynamic_state *src)
1220 {
1221 struct tu_dynamic_state *dest = &cmd_buffer->state.dynamic;
1222 uint32_t copy_mask = src->mask;
1223 uint32_t dest_mask = 0;
1224
1225 tu_use_args(cmd_buffer); /* FINISHME */
1226
1227 /* Make sure to copy the number of viewports/scissors because they can
1228 * only be specified at pipeline creation time.
1229 */
1230 dest->viewport.count = src->viewport.count;
1231 dest->scissor.count = src->scissor.count;
1232 dest->discard_rectangle.count = src->discard_rectangle.count;
1233
1234 if (copy_mask & TU_DYNAMIC_VIEWPORT) {
1235 if (memcmp(&dest->viewport.viewports, &src->viewport.viewports,
1236 src->viewport.count * sizeof(VkViewport))) {
1237 typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
1238 src->viewport.count);
1239 dest_mask |= TU_DYNAMIC_VIEWPORT;
1240 }
1241 }
1242
1243 if (copy_mask & TU_DYNAMIC_SCISSOR) {
1244 if (memcmp(&dest->scissor.scissors, &src->scissor.scissors,
1245 src->scissor.count * sizeof(VkRect2D))) {
1246 typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
1247 src->scissor.count);
1248 dest_mask |= TU_DYNAMIC_SCISSOR;
1249 }
1250 }
1251
1252 if (copy_mask & TU_DYNAMIC_LINE_WIDTH) {
1253 if (dest->line_width != src->line_width) {
1254 dest->line_width = src->line_width;
1255 dest_mask |= TU_DYNAMIC_LINE_WIDTH;
1256 }
1257 }
1258
1259 if (copy_mask & TU_DYNAMIC_DEPTH_BIAS) {
1260 if (memcmp(&dest->depth_bias, &src->depth_bias,
1261 sizeof(src->depth_bias))) {
1262 dest->depth_bias = src->depth_bias;
1263 dest_mask |= TU_DYNAMIC_DEPTH_BIAS;
1264 }
1265 }
1266
1267 if (copy_mask & TU_DYNAMIC_BLEND_CONSTANTS) {
1268 if (memcmp(&dest->blend_constants, &src->blend_constants,
1269 sizeof(src->blend_constants))) {
1270 typed_memcpy(dest->blend_constants, src->blend_constants, 4);
1271 dest_mask |= TU_DYNAMIC_BLEND_CONSTANTS;
1272 }
1273 }
1274
1275 if (copy_mask & TU_DYNAMIC_DEPTH_BOUNDS) {
1276 if (memcmp(&dest->depth_bounds, &src->depth_bounds,
1277 sizeof(src->depth_bounds))) {
1278 dest->depth_bounds = src->depth_bounds;
1279 dest_mask |= TU_DYNAMIC_DEPTH_BOUNDS;
1280 }
1281 }
1282
1283 if (copy_mask & TU_DYNAMIC_STENCIL_COMPARE_MASK) {
1284 if (memcmp(&dest->stencil_compare_mask, &src->stencil_compare_mask,
1285 sizeof(src->stencil_compare_mask))) {
1286 dest->stencil_compare_mask = src->stencil_compare_mask;
1287 dest_mask |= TU_DYNAMIC_STENCIL_COMPARE_MASK;
1288 }
1289 }
1290
1291 if (copy_mask & TU_DYNAMIC_STENCIL_WRITE_MASK) {
1292 if (memcmp(&dest->stencil_write_mask, &src->stencil_write_mask,
1293 sizeof(src->stencil_write_mask))) {
1294 dest->stencil_write_mask = src->stencil_write_mask;
1295 dest_mask |= TU_DYNAMIC_STENCIL_WRITE_MASK;
1296 }
1297 }
1298
1299 if (copy_mask & TU_DYNAMIC_STENCIL_REFERENCE) {
1300 if (memcmp(&dest->stencil_reference, &src->stencil_reference,
1301 sizeof(src->stencil_reference))) {
1302 dest->stencil_reference = src->stencil_reference;
1303 dest_mask |= TU_DYNAMIC_STENCIL_REFERENCE;
1304 }
1305 }
1306
1307 if (copy_mask & TU_DYNAMIC_DISCARD_RECTANGLE) {
1308 if (memcmp(&dest->discard_rectangle.rectangles,
1309 &src->discard_rectangle.rectangles,
1310 src->discard_rectangle.count * sizeof(VkRect2D))) {
1311 typed_memcpy(dest->discard_rectangle.rectangles,
1312 src->discard_rectangle.rectangles,
1313 src->discard_rectangle.count);
1314 dest_mask |= TU_DYNAMIC_DISCARD_RECTANGLE;
1315 }
1316 }
1317 }
1318
1319 static VkResult
1320 tu_create_cmd_buffer(struct tu_device *device,
1321 struct tu_cmd_pool *pool,
1322 VkCommandBufferLevel level,
1323 VkCommandBuffer *pCommandBuffer)
1324 {
1325 struct tu_cmd_buffer *cmd_buffer;
1326 cmd_buffer = vk_zalloc(&pool->alloc, sizeof(*cmd_buffer), 8,
1327 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1328 if (cmd_buffer == NULL)
1329 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1330
1331 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
1332 cmd_buffer->device = device;
1333 cmd_buffer->pool = pool;
1334 cmd_buffer->level = level;
1335
1336 if (pool) {
1337 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
1338 cmd_buffer->queue_family_index = pool->queue_family_index;
1339
1340 } else {
1341 /* Init the pool_link so we can safely call list_del when we destroy
1342 * the command buffer
1343 */
1344 list_inithead(&cmd_buffer->pool_link);
1345 cmd_buffer->queue_family_index = TU_QUEUE_GENERAL;
1346 }
1347
1348 tu_bo_list_init(&cmd_buffer->bo_list);
1349 tu_cs_init(&cmd_buffer->cs, TU_CS_MODE_GROW, 4096);
1350 tu_cs_init(&cmd_buffer->tile_cs, TU_CS_MODE_SUB_STREAM, 1024);
1351
1352 *pCommandBuffer = tu_cmd_buffer_to_handle(cmd_buffer);
1353
1354 list_inithead(&cmd_buffer->upload.list);
1355
1356 cmd_buffer->marker_reg = REG_A6XX_CP_SCRATCH_REG(
1357 cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY ? 7 : 6);
1358
1359 VkResult result = tu_bo_init_new(device, &cmd_buffer->scratch_bo, 0x1000);
1360 if (result != VK_SUCCESS)
1361 return result;
1362
1363 return VK_SUCCESS;
1364 }
1365
1366 static void
1367 tu_cmd_buffer_destroy(struct tu_cmd_buffer *cmd_buffer)
1368 {
1369 tu_bo_finish(cmd_buffer->device, &cmd_buffer->scratch_bo);
1370
1371 list_del(&cmd_buffer->pool_link);
1372
1373 for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++)
1374 free(cmd_buffer->descriptors[i].push_set.set.mapped_ptr);
1375
1376 tu_cs_finish(cmd_buffer->device, &cmd_buffer->cs);
1377 tu_cs_finish(cmd_buffer->device, &cmd_buffer->tile_cs);
1378
1379 tu_bo_list_destroy(&cmd_buffer->bo_list);
1380 vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
1381 }
1382
1383 static VkResult
1384 tu_reset_cmd_buffer(struct tu_cmd_buffer *cmd_buffer)
1385 {
1386 cmd_buffer->wait_for_idle = true;
1387
1388 cmd_buffer->record_result = VK_SUCCESS;
1389
1390 tu_bo_list_reset(&cmd_buffer->bo_list);
1391 tu_cs_reset(cmd_buffer->device, &cmd_buffer->cs);
1392 tu_cs_reset(cmd_buffer->device, &cmd_buffer->tile_cs);
1393
1394 for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++) {
1395 cmd_buffer->descriptors[i].dirty = 0;
1396 cmd_buffer->descriptors[i].valid = 0;
1397 cmd_buffer->descriptors[i].push_dirty = false;
1398 }
1399
1400 cmd_buffer->status = TU_CMD_BUFFER_STATUS_INITIAL;
1401
1402 return cmd_buffer->record_result;
1403 }
1404
1405 static VkResult
1406 tu_cmd_state_setup_attachments(struct tu_cmd_buffer *cmd_buffer,
1407 const VkRenderPassBeginInfo *info)
1408 {
1409 struct tu_cmd_state *state = &cmd_buffer->state;
1410 const struct tu_framebuffer *fb = state->framebuffer;
1411 const struct tu_render_pass *pass = state->pass;
1412
1413 for (uint32_t i = 0; i < fb->attachment_count; ++i) {
1414 const struct tu_image_view *iview = fb->attachments[i].attachment;
1415 tu_bo_list_add(&cmd_buffer->bo_list, iview->image->bo,
1416 MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE);
1417 }
1418
1419 if (pass->attachment_count == 0) {
1420 state->attachments = NULL;
1421 return VK_SUCCESS;
1422 }
1423
1424 state->attachments =
1425 vk_alloc(&cmd_buffer->pool->alloc,
1426 pass->attachment_count * sizeof(state->attachments[0]), 8,
1427 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1428 if (state->attachments == NULL) {
1429 cmd_buffer->record_result = VK_ERROR_OUT_OF_HOST_MEMORY;
1430 return cmd_buffer->record_result;
1431 }
1432
1433 for (uint32_t i = 0; i < pass->attachment_count; ++i) {
1434 const struct tu_render_pass_attachment *att = &pass->attachments[i];
1435 VkImageAspectFlags att_aspects = vk_format_aspects(att->format);
1436 VkImageAspectFlags clear_aspects = 0;
1437
1438 if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {
1439 /* color attachment */
1440 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1441 clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
1442 }
1443 } else {
1444 /* depthstencil attachment */
1445 if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
1446 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1447 clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
1448 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1449 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
1450 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1451 }
1452 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1453 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1454 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1455 }
1456 }
1457
1458 state->attachments[i].pending_clear_aspects = clear_aspects;
1459 state->attachments[i].cleared_views = 0;
1460 if (clear_aspects && info) {
1461 assert(info->clearValueCount > i);
1462 state->attachments[i].clear_value = info->pClearValues[i];
1463 }
1464
1465 state->attachments[i].current_layout = att->initial_layout;
1466 }
1467
1468 return VK_SUCCESS;
1469 }
1470
1471 VkResult
1472 tu_AllocateCommandBuffers(VkDevice _device,
1473 const VkCommandBufferAllocateInfo *pAllocateInfo,
1474 VkCommandBuffer *pCommandBuffers)
1475 {
1476 TU_FROM_HANDLE(tu_device, device, _device);
1477 TU_FROM_HANDLE(tu_cmd_pool, pool, pAllocateInfo->commandPool);
1478
1479 VkResult result = VK_SUCCESS;
1480 uint32_t i;
1481
1482 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
1483
1484 if (!list_empty(&pool->free_cmd_buffers)) {
1485 struct tu_cmd_buffer *cmd_buffer = list_first_entry(
1486 &pool->free_cmd_buffers, struct tu_cmd_buffer, pool_link);
1487
1488 list_del(&cmd_buffer->pool_link);
1489 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
1490
1491 result = tu_reset_cmd_buffer(cmd_buffer);
1492 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
1493 cmd_buffer->level = pAllocateInfo->level;
1494
1495 pCommandBuffers[i] = tu_cmd_buffer_to_handle(cmd_buffer);
1496 } else {
1497 result = tu_create_cmd_buffer(device, pool, pAllocateInfo->level,
1498 &pCommandBuffers[i]);
1499 }
1500 if (result != VK_SUCCESS)
1501 break;
1502 }
1503
1504 if (result != VK_SUCCESS) {
1505 tu_FreeCommandBuffers(_device, pAllocateInfo->commandPool, i,
1506 pCommandBuffers);
1507
1508 /* From the Vulkan 1.0.66 spec:
1509 *
1510 * "vkAllocateCommandBuffers can be used to create multiple
1511 * command buffers. If the creation of any of those command
1512 * buffers fails, the implementation must destroy all
1513 * successfully created command buffer objects from this
1514 * command, set all entries of the pCommandBuffers array to
1515 * NULL and return the error."
1516 */
1517 memset(pCommandBuffers, 0,
1518 sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
1519 }
1520
1521 return result;
1522 }
1523
1524 void
1525 tu_FreeCommandBuffers(VkDevice device,
1526 VkCommandPool commandPool,
1527 uint32_t commandBufferCount,
1528 const VkCommandBuffer *pCommandBuffers)
1529 {
1530 for (uint32_t i = 0; i < commandBufferCount; i++) {
1531 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
1532
1533 if (cmd_buffer) {
1534 if (cmd_buffer->pool) {
1535 list_del(&cmd_buffer->pool_link);
1536 list_addtail(&cmd_buffer->pool_link,
1537 &cmd_buffer->pool->free_cmd_buffers);
1538 } else
1539 tu_cmd_buffer_destroy(cmd_buffer);
1540 }
1541 }
1542 }
1543
1544 VkResult
1545 tu_ResetCommandBuffer(VkCommandBuffer commandBuffer,
1546 VkCommandBufferResetFlags flags)
1547 {
1548 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1549 return tu_reset_cmd_buffer(cmd_buffer);
1550 }
1551
1552 VkResult
1553 tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
1554 const VkCommandBufferBeginInfo *pBeginInfo)
1555 {
1556 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1557 VkResult result = VK_SUCCESS;
1558
1559 if (cmd_buffer->status != TU_CMD_BUFFER_STATUS_INITIAL) {
1560 /* If the command buffer has already been resetted with
1561 * vkResetCommandBuffer, no need to do it again.
1562 */
1563 result = tu_reset_cmd_buffer(cmd_buffer);
1564 if (result != VK_SUCCESS)
1565 return result;
1566 }
1567
1568 memset(&cmd_buffer->state, 0, sizeof(cmd_buffer->state));
1569 cmd_buffer->usage_flags = pBeginInfo->flags;
1570
1571 tu_cs_begin(&cmd_buffer->cs);
1572
1573 cmd_buffer->marker_seqno = 0;
1574 cmd_buffer->scratch_seqno = 0;
1575
1576 /* setup initial configuration into command buffer */
1577 if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
1578 switch (cmd_buffer->queue_family_index) {
1579 case TU_QUEUE_GENERAL:
1580 tu6_init_hw(cmd_buffer, &cmd_buffer->cs);
1581 break;
1582 default:
1583 break;
1584 }
1585 }
1586
1587 cmd_buffer->status = TU_CMD_BUFFER_STATUS_RECORDING;
1588
1589 return VK_SUCCESS;
1590 }
1591
1592 void
1593 tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
1594 uint32_t firstBinding,
1595 uint32_t bindingCount,
1596 const VkBuffer *pBuffers,
1597 const VkDeviceSize *pOffsets)
1598 {
1599 }
1600
1601 void
1602 tu_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
1603 VkBuffer buffer,
1604 VkDeviceSize offset,
1605 VkIndexType indexType)
1606 {
1607 }
1608
1609 void
1610 tu_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
1611 VkPipelineBindPoint pipelineBindPoint,
1612 VkPipelineLayout _layout,
1613 uint32_t firstSet,
1614 uint32_t descriptorSetCount,
1615 const VkDescriptorSet *pDescriptorSets,
1616 uint32_t dynamicOffsetCount,
1617 const uint32_t *pDynamicOffsets)
1618 {
1619 }
1620
1621 void
1622 tu_CmdPushConstants(VkCommandBuffer commandBuffer,
1623 VkPipelineLayout layout,
1624 VkShaderStageFlags stageFlags,
1625 uint32_t offset,
1626 uint32_t size,
1627 const void *pValues)
1628 {
1629 }
1630
1631 VkResult
1632 tu_EndCommandBuffer(VkCommandBuffer commandBuffer)
1633 {
1634 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1635
1636 if (cmd_buffer->scratch_seqno) {
1637 tu_bo_list_add(&cmd_buffer->bo_list, &cmd_buffer->scratch_bo,
1638 MSM_SUBMIT_BO_WRITE);
1639 }
1640
1641 for (uint32_t i = 0; i < cmd_buffer->tile_cs.bo_count; i++) {
1642 tu_bo_list_add(&cmd_buffer->bo_list, cmd_buffer->tile_cs.bos[i],
1643 MSM_SUBMIT_BO_READ);
1644 }
1645
1646 tu_cs_end(&cmd_buffer->cs);
1647
1648 assert(!cmd_buffer->state.attachments);
1649
1650 cmd_buffer->status = TU_CMD_BUFFER_STATUS_EXECUTABLE;
1651
1652 return cmd_buffer->record_result;
1653 }
1654
1655 void
1656 tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
1657 VkPipelineBindPoint pipelineBindPoint,
1658 VkPipeline _pipeline)
1659 {
1660 }
1661
1662 void
1663 tu_CmdSetViewport(VkCommandBuffer commandBuffer,
1664 uint32_t firstViewport,
1665 uint32_t viewportCount,
1666 const VkViewport *pViewports)
1667 {
1668 }
1669
1670 void
1671 tu_CmdSetScissor(VkCommandBuffer commandBuffer,
1672 uint32_t firstScissor,
1673 uint32_t scissorCount,
1674 const VkRect2D *pScissors)
1675 {
1676 }
1677
1678 void
1679 tu_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
1680 {
1681 }
1682
1683 void
1684 tu_CmdSetDepthBias(VkCommandBuffer commandBuffer,
1685 float depthBiasConstantFactor,
1686 float depthBiasClamp,
1687 float depthBiasSlopeFactor)
1688 {
1689 }
1690
1691 void
1692 tu_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
1693 const float blendConstants[4])
1694 {
1695 }
1696
1697 void
1698 tu_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
1699 float minDepthBounds,
1700 float maxDepthBounds)
1701 {
1702 }
1703
1704 void
1705 tu_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
1706 VkStencilFaceFlags faceMask,
1707 uint32_t compareMask)
1708 {
1709 }
1710
1711 void
1712 tu_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
1713 VkStencilFaceFlags faceMask,
1714 uint32_t writeMask)
1715 {
1716 }
1717
1718 void
1719 tu_CmdSetStencilReference(VkCommandBuffer commandBuffer,
1720 VkStencilFaceFlags faceMask,
1721 uint32_t reference)
1722 {
1723 }
1724
1725 void
1726 tu_CmdExecuteCommands(VkCommandBuffer commandBuffer,
1727 uint32_t commandBufferCount,
1728 const VkCommandBuffer *pCmdBuffers)
1729 {
1730 }
1731
1732 VkResult
1733 tu_CreateCommandPool(VkDevice _device,
1734 const VkCommandPoolCreateInfo *pCreateInfo,
1735 const VkAllocationCallbacks *pAllocator,
1736 VkCommandPool *pCmdPool)
1737 {
1738 TU_FROM_HANDLE(tu_device, device, _device);
1739 struct tu_cmd_pool *pool;
1740
1741 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
1742 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1743 if (pool == NULL)
1744 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1745
1746 if (pAllocator)
1747 pool->alloc = *pAllocator;
1748 else
1749 pool->alloc = device->alloc;
1750
1751 list_inithead(&pool->cmd_buffers);
1752 list_inithead(&pool->free_cmd_buffers);
1753
1754 pool->queue_family_index = pCreateInfo->queueFamilyIndex;
1755
1756 *pCmdPool = tu_cmd_pool_to_handle(pool);
1757
1758 return VK_SUCCESS;
1759 }
1760
1761 void
1762 tu_DestroyCommandPool(VkDevice _device,
1763 VkCommandPool commandPool,
1764 const VkAllocationCallbacks *pAllocator)
1765 {
1766 TU_FROM_HANDLE(tu_device, device, _device);
1767 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1768
1769 if (!pool)
1770 return;
1771
1772 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1773 &pool->cmd_buffers, pool_link)
1774 {
1775 tu_cmd_buffer_destroy(cmd_buffer);
1776 }
1777
1778 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1779 &pool->free_cmd_buffers, pool_link)
1780 {
1781 tu_cmd_buffer_destroy(cmd_buffer);
1782 }
1783
1784 vk_free2(&device->alloc, pAllocator, pool);
1785 }
1786
1787 VkResult
1788 tu_ResetCommandPool(VkDevice device,
1789 VkCommandPool commandPool,
1790 VkCommandPoolResetFlags flags)
1791 {
1792 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1793 VkResult result;
1794
1795 list_for_each_entry(struct tu_cmd_buffer, cmd_buffer, &pool->cmd_buffers,
1796 pool_link)
1797 {
1798 result = tu_reset_cmd_buffer(cmd_buffer);
1799 if (result != VK_SUCCESS)
1800 return result;
1801 }
1802
1803 return VK_SUCCESS;
1804 }
1805
1806 void
1807 tu_TrimCommandPool(VkDevice device,
1808 VkCommandPool commandPool,
1809 VkCommandPoolTrimFlagsKHR flags)
1810 {
1811 TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
1812
1813 if (!pool)
1814 return;
1815
1816 list_for_each_entry_safe(struct tu_cmd_buffer, cmd_buffer,
1817 &pool->free_cmd_buffers, pool_link)
1818 {
1819 tu_cmd_buffer_destroy(cmd_buffer);
1820 }
1821 }
1822
1823 void
1824 tu_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
1825 const VkRenderPassBeginInfo *pRenderPassBegin,
1826 VkSubpassContents contents)
1827 {
1828 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1829 TU_FROM_HANDLE(tu_render_pass, pass, pRenderPassBegin->renderPass);
1830 TU_FROM_HANDLE(tu_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
1831 VkResult result;
1832
1833 cmd_buffer->state.pass = pass;
1834 cmd_buffer->state.subpass = pass->subpasses;
1835 cmd_buffer->state.framebuffer = framebuffer;
1836
1837 result = tu_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
1838 if (result != VK_SUCCESS)
1839 return;
1840
1841 tu_cmd_update_tiling_config(cmd_buffer, &pRenderPassBegin->renderArea);
1842 tu_cmd_prepare_tile_load_ib(cmd_buffer);
1843 tu_cmd_prepare_tile_store_ib(cmd_buffer);
1844 }
1845
1846 void
1847 tu_CmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
1848 const VkRenderPassBeginInfo *pRenderPassBeginInfo,
1849 const VkSubpassBeginInfoKHR *pSubpassBeginInfo)
1850 {
1851 tu_CmdBeginRenderPass(commandBuffer, pRenderPassBeginInfo,
1852 pSubpassBeginInfo->contents);
1853 }
1854
1855 void
1856 tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
1857 {
1858 TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
1859
1860 tu_cmd_render_tiles(cmd);
1861
1862 cmd->state.subpass++;
1863
1864 tu_cmd_update_tiling_config(cmd, NULL);
1865 tu_cmd_prepare_tile_load_ib(cmd);
1866 tu_cmd_prepare_tile_store_ib(cmd);
1867 }
1868
1869 void
1870 tu_CmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
1871 const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
1872 const VkSubpassEndInfoKHR *pSubpassEndInfo)
1873 {
1874 tu_CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
1875 }
1876
1877 struct tu_draw_info
1878 {
1879 /**
1880 * Number of vertices.
1881 */
1882 uint32_t count;
1883
1884 /**
1885 * Index of the first vertex.
1886 */
1887 int32_t vertex_offset;
1888
1889 /**
1890 * First instance id.
1891 */
1892 uint32_t first_instance;
1893
1894 /**
1895 * Number of instances.
1896 */
1897 uint32_t instance_count;
1898
1899 /**
1900 * First index (indexed draws only).
1901 */
1902 uint32_t first_index;
1903
1904 /**
1905 * Whether it's an indexed draw.
1906 */
1907 bool indexed;
1908
1909 /**
1910 * Indirect draw parameters resource.
1911 */
1912 struct tu_buffer *indirect;
1913 uint64_t indirect_offset;
1914 uint32_t stride;
1915
1916 /**
1917 * Draw count parameters resource.
1918 */
1919 struct tu_buffer *count_buffer;
1920 uint64_t count_buffer_offset;
1921 };
1922
1923 static void
1924 tu_draw(struct tu_cmd_buffer *cmd_buffer, const struct tu_draw_info *info)
1925 {
1926 }
1927
1928 void
1929 tu_CmdDraw(VkCommandBuffer commandBuffer,
1930 uint32_t vertexCount,
1931 uint32_t instanceCount,
1932 uint32_t firstVertex,
1933 uint32_t firstInstance)
1934 {
1935 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1936 struct tu_draw_info info = {};
1937
1938 info.count = vertexCount;
1939 info.instance_count = instanceCount;
1940 info.first_instance = firstInstance;
1941 info.vertex_offset = firstVertex;
1942
1943 tu_draw(cmd_buffer, &info);
1944 }
1945
1946 void
1947 tu_CmdDrawIndexed(VkCommandBuffer commandBuffer,
1948 uint32_t indexCount,
1949 uint32_t instanceCount,
1950 uint32_t firstIndex,
1951 int32_t vertexOffset,
1952 uint32_t firstInstance)
1953 {
1954 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1955 struct tu_draw_info info = {};
1956
1957 info.indexed = true;
1958 info.count = indexCount;
1959 info.instance_count = instanceCount;
1960 info.first_index = firstIndex;
1961 info.vertex_offset = vertexOffset;
1962 info.first_instance = firstInstance;
1963
1964 tu_draw(cmd_buffer, &info);
1965 }
1966
1967 void
1968 tu_CmdDrawIndirect(VkCommandBuffer commandBuffer,
1969 VkBuffer _buffer,
1970 VkDeviceSize offset,
1971 uint32_t drawCount,
1972 uint32_t stride)
1973 {
1974 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1975 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
1976 struct tu_draw_info info = {};
1977
1978 info.count = drawCount;
1979 info.indirect = buffer;
1980 info.indirect_offset = offset;
1981 info.stride = stride;
1982
1983 tu_draw(cmd_buffer, &info);
1984 }
1985
1986 void
1987 tu_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
1988 VkBuffer _buffer,
1989 VkDeviceSize offset,
1990 uint32_t drawCount,
1991 uint32_t stride)
1992 {
1993 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
1994 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
1995 struct tu_draw_info info = {};
1996
1997 info.indexed = true;
1998 info.count = drawCount;
1999 info.indirect = buffer;
2000 info.indirect_offset = offset;
2001 info.stride = stride;
2002
2003 tu_draw(cmd_buffer, &info);
2004 }
2005
2006 struct tu_dispatch_info
2007 {
2008 /**
2009 * Determine the layout of the grid (in block units) to be used.
2010 */
2011 uint32_t blocks[3];
2012
2013 /**
2014 * A starting offset for the grid. If unaligned is set, the offset
2015 * must still be aligned.
2016 */
2017 uint32_t offsets[3];
2018 /**
2019 * Whether it's an unaligned compute dispatch.
2020 */
2021 bool unaligned;
2022
2023 /**
2024 * Indirect compute parameters resource.
2025 */
2026 struct tu_buffer *indirect;
2027 uint64_t indirect_offset;
2028 };
2029
2030 static void
2031 tu_dispatch(struct tu_cmd_buffer *cmd_buffer,
2032 const struct tu_dispatch_info *info)
2033 {
2034 }
2035
2036 void
2037 tu_CmdDispatchBase(VkCommandBuffer commandBuffer,
2038 uint32_t base_x,
2039 uint32_t base_y,
2040 uint32_t base_z,
2041 uint32_t x,
2042 uint32_t y,
2043 uint32_t z)
2044 {
2045 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2046 struct tu_dispatch_info info = {};
2047
2048 info.blocks[0] = x;
2049 info.blocks[1] = y;
2050 info.blocks[2] = z;
2051
2052 info.offsets[0] = base_x;
2053 info.offsets[1] = base_y;
2054 info.offsets[2] = base_z;
2055 tu_dispatch(cmd_buffer, &info);
2056 }
2057
2058 void
2059 tu_CmdDispatch(VkCommandBuffer commandBuffer,
2060 uint32_t x,
2061 uint32_t y,
2062 uint32_t z)
2063 {
2064 tu_CmdDispatchBase(commandBuffer, 0, 0, 0, x, y, z);
2065 }
2066
2067 void
2068 tu_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
2069 VkBuffer _buffer,
2070 VkDeviceSize offset)
2071 {
2072 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2073 TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
2074 struct tu_dispatch_info info = {};
2075
2076 info.indirect = buffer;
2077 info.indirect_offset = offset;
2078
2079 tu_dispatch(cmd_buffer, &info);
2080 }
2081
2082 void
2083 tu_CmdEndRenderPass(VkCommandBuffer commandBuffer)
2084 {
2085 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2086
2087 tu_cmd_render_tiles(cmd_buffer);
2088
2089 vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
2090 cmd_buffer->state.attachments = NULL;
2091
2092 cmd_buffer->state.pass = NULL;
2093 cmd_buffer->state.subpass = NULL;
2094 cmd_buffer->state.framebuffer = NULL;
2095 }
2096
2097 void
2098 tu_CmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
2099 const VkSubpassEndInfoKHR *pSubpassEndInfo)
2100 {
2101 tu_CmdEndRenderPass(commandBuffer);
2102 }
2103
2104 struct tu_barrier_info
2105 {
2106 uint32_t eventCount;
2107 const VkEvent *pEvents;
2108 VkPipelineStageFlags srcStageMask;
2109 };
2110
2111 static void
2112 tu_barrier(struct tu_cmd_buffer *cmd_buffer,
2113 uint32_t memoryBarrierCount,
2114 const VkMemoryBarrier *pMemoryBarriers,
2115 uint32_t bufferMemoryBarrierCount,
2116 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2117 uint32_t imageMemoryBarrierCount,
2118 const VkImageMemoryBarrier *pImageMemoryBarriers,
2119 const struct tu_barrier_info *info)
2120 {
2121 }
2122
2123 void
2124 tu_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
2125 VkPipelineStageFlags srcStageMask,
2126 VkPipelineStageFlags destStageMask,
2127 VkBool32 byRegion,
2128 uint32_t memoryBarrierCount,
2129 const VkMemoryBarrier *pMemoryBarriers,
2130 uint32_t bufferMemoryBarrierCount,
2131 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2132 uint32_t imageMemoryBarrierCount,
2133 const VkImageMemoryBarrier *pImageMemoryBarriers)
2134 {
2135 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2136 struct tu_barrier_info info;
2137
2138 info.eventCount = 0;
2139 info.pEvents = NULL;
2140 info.srcStageMask = srcStageMask;
2141
2142 tu_barrier(cmd_buffer, memoryBarrierCount, pMemoryBarriers,
2143 bufferMemoryBarrierCount, pBufferMemoryBarriers,
2144 imageMemoryBarrierCount, pImageMemoryBarriers, &info);
2145 }
2146
2147 static void
2148 write_event(struct tu_cmd_buffer *cmd_buffer,
2149 struct tu_event *event,
2150 VkPipelineStageFlags stageMask,
2151 unsigned value)
2152 {
2153 }
2154
2155 void
2156 tu_CmdSetEvent(VkCommandBuffer commandBuffer,
2157 VkEvent _event,
2158 VkPipelineStageFlags stageMask)
2159 {
2160 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2161 TU_FROM_HANDLE(tu_event, event, _event);
2162
2163 write_event(cmd_buffer, event, stageMask, 1);
2164 }
2165
2166 void
2167 tu_CmdResetEvent(VkCommandBuffer commandBuffer,
2168 VkEvent _event,
2169 VkPipelineStageFlags stageMask)
2170 {
2171 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2172 TU_FROM_HANDLE(tu_event, event, _event);
2173
2174 write_event(cmd_buffer, event, stageMask, 0);
2175 }
2176
2177 void
2178 tu_CmdWaitEvents(VkCommandBuffer commandBuffer,
2179 uint32_t eventCount,
2180 const VkEvent *pEvents,
2181 VkPipelineStageFlags srcStageMask,
2182 VkPipelineStageFlags dstStageMask,
2183 uint32_t memoryBarrierCount,
2184 const VkMemoryBarrier *pMemoryBarriers,
2185 uint32_t bufferMemoryBarrierCount,
2186 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
2187 uint32_t imageMemoryBarrierCount,
2188 const VkImageMemoryBarrier *pImageMemoryBarriers)
2189 {
2190 TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
2191 struct tu_barrier_info info;
2192
2193 info.eventCount = eventCount;
2194 info.pEvents = pEvents;
2195 info.srcStageMask = 0;
2196
2197 tu_barrier(cmd_buffer, memoryBarrierCount, pMemoryBarriers,
2198 bufferMemoryBarrierCount, pBufferMemoryBarriers,
2199 imageMemoryBarrierCount, pImageMemoryBarriers, &info);
2200 }
2201
2202 void
2203 tu_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
2204 {
2205 /* No-op */
2206 }