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