1 /*
2 * Copyright © 2021 Collabora Ltd.
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "panvk_cmd_meta.h"
7 #include "panvk_entrypoints.h"
8
9 static bool
copy_to_image_use_gfx_pipeline(struct panvk_device * dev,struct panvk_image * dst_img)10 copy_to_image_use_gfx_pipeline(struct panvk_device *dev,
11 struct panvk_image *dst_img)
12 {
13 struct panvk_instance *instance =
14 to_panvk_instance(dev->vk.physical->instance);
15
16 if (instance->debug_flags & PANVK_DEBUG_COPY_GFX)
17 return true;
18
19 /* Writes to AFBC images must go through the graphics pipeline. */
20 if (drm_is_afbc(dst_img->vk.drm_format_mod))
21 return true;
22
23 return false;
24 }
25
26 void
panvk_per_arch(cmd_meta_compute_start)27 panvk_per_arch(cmd_meta_compute_start)(
28 struct panvk_cmd_buffer *cmdbuf,
29 struct panvk_cmd_meta_compute_save_ctx *save_ctx)
30 {
31 const struct panvk_descriptor_set *set0 =
32 cmdbuf->state.compute.desc_state.sets[0];
33 struct panvk_descriptor_set *push_set0 =
34 cmdbuf->state.compute.desc_state.push_sets[0];
35
36 save_ctx->set0 = set0;
37 if (push_set0 && push_set0 == set0) {
38 save_ctx->push_set0.desc_count = push_set0->desc_count;
39 save_ctx->push_set0.descs_dev_addr = push_set0->descs.dev;
40 memcpy(save_ctx->push_set0.desc_storage, push_set0->descs.host,
41 push_set0->desc_count * PANVK_DESCRIPTOR_SIZE);
42 }
43
44 save_ctx->push_constants = cmdbuf->state.push_constants;
45 save_ctx->cs.shader = cmdbuf->state.compute.shader;
46 save_ctx->cs.desc = cmdbuf->state.compute.cs.desc;
47 }
48
49 void
panvk_per_arch(cmd_meta_compute_end)50 panvk_per_arch(cmd_meta_compute_end)(
51 struct panvk_cmd_buffer *cmdbuf,
52 const struct panvk_cmd_meta_compute_save_ctx *save_ctx)
53 {
54 struct panvk_descriptor_set *push_set0 =
55 cmdbuf->state.compute.desc_state.push_sets[0];
56
57 cmdbuf->state.compute.desc_state.sets[0] = save_ctx->set0;
58 if (save_ctx->push_set0.desc_count) {
59 memcpy(push_set0->descs.host, save_ctx->push_set0.desc_storage,
60 save_ctx->push_set0.desc_count * PANVK_DESCRIPTOR_SIZE);
61 push_set0->descs.dev = save_ctx->push_set0.descs_dev_addr;
62 push_set0->desc_count = save_ctx->push_set0.desc_count;
63 }
64
65 cmdbuf->state.push_constants = save_ctx->push_constants;
66 compute_state_set_dirty(cmdbuf, PUSH_UNIFORMS);
67
68 cmdbuf->state.compute.shader = save_ctx->cs.shader;
69 cmdbuf->state.compute.cs.desc = save_ctx->cs.desc;
70 compute_state_set_dirty(cmdbuf, CS);
71 compute_state_set_dirty(cmdbuf, DESC_STATE);
72 }
73
74 void
panvk_per_arch(cmd_meta_gfx_start)75 panvk_per_arch(cmd_meta_gfx_start)(
76 struct panvk_cmd_buffer *cmdbuf,
77 struct panvk_cmd_meta_graphics_save_ctx *save_ctx)
78 {
79 const struct panvk_descriptor_set *set0 =
80 cmdbuf->state.gfx.desc_state.sets[0];
81 struct panvk_descriptor_set *push_set0 =
82 cmdbuf->state.gfx.desc_state.push_sets[0];
83
84 save_ctx->set0 = set0;
85 if (push_set0 && push_set0 == set0) {
86 save_ctx->push_set0.desc_count = push_set0->desc_count;
87 save_ctx->push_set0.descs_dev_addr = push_set0->descs.dev;
88 memcpy(save_ctx->push_set0.desc_storage, push_set0->descs.host,
89 push_set0->desc_count * PANVK_DESCRIPTOR_SIZE);
90 }
91
92 save_ctx->push_constants = cmdbuf->state.push_constants;
93 save_ctx->fs.shader = cmdbuf->state.gfx.fs.shader;
94 save_ctx->fs.desc = cmdbuf->state.gfx.fs.desc;
95 save_ctx->vs.shader = cmdbuf->state.gfx.vs.shader;
96 save_ctx->vs.desc = cmdbuf->state.gfx.vs.desc;
97 save_ctx->vb0 = cmdbuf->state.gfx.vb.bufs[0];
98
99 save_ctx->dyn_state.all = cmdbuf->vk.dynamic_graphics_state;
100 save_ctx->dyn_state.vi = cmdbuf->state.gfx.dynamic.vi;
101 save_ctx->dyn_state.sl = cmdbuf->state.gfx.dynamic.sl;
102 save_ctx->occlusion_query = cmdbuf->state.gfx.occlusion_query;
103
104 /* Ensure occlusion queries are disabled */
105 cmdbuf->state.gfx.occlusion_query.ptr = 0;
106 cmdbuf->state.gfx.occlusion_query.mode = MALI_OCCLUSION_MODE_DISABLED;
107 gfx_state_set_dirty(cmdbuf, OQ);
108 }
109
110 void
panvk_per_arch(cmd_meta_gfx_end)111 panvk_per_arch(cmd_meta_gfx_end)(
112 struct panvk_cmd_buffer *cmdbuf,
113 const struct panvk_cmd_meta_graphics_save_ctx *save_ctx)
114 {
115 struct panvk_descriptor_set *push_set0 =
116 cmdbuf->state.gfx.desc_state.push_sets[0];
117
118 cmdbuf->state.gfx.desc_state.sets[0] = save_ctx->set0;
119 if (save_ctx->push_set0.desc_count) {
120 memcpy(push_set0->descs.host, save_ctx->push_set0.desc_storage,
121 save_ctx->push_set0.desc_count * PANVK_DESCRIPTOR_SIZE);
122 push_set0->descs.dev = save_ctx->push_set0.descs_dev_addr;
123 push_set0->desc_count = save_ctx->push_set0.desc_count;
124 }
125
126 cmdbuf->state.push_constants = save_ctx->push_constants;
127 gfx_state_set_dirty(cmdbuf, VS_PUSH_UNIFORMS);
128 gfx_state_set_dirty(cmdbuf, FS_PUSH_UNIFORMS);
129
130 cmdbuf->state.gfx.fs.shader = save_ctx->fs.shader;
131 cmdbuf->state.gfx.fs.desc = save_ctx->fs.desc;
132 cmdbuf->state.gfx.vs.shader = save_ctx->vs.shader;
133 cmdbuf->state.gfx.vs.desc = save_ctx->vs.desc;
134 cmdbuf->state.gfx.vb.bufs[0] = save_ctx->vb0;
135
136 #if PAN_ARCH <= 7
137 cmdbuf->state.gfx.vs.attribs = 0;
138 cmdbuf->state.gfx.vs.attrib_bufs = 0;
139 cmdbuf->state.gfx.fs.rsd = 0;
140 #else
141 cmdbuf->state.gfx.fs.desc.res_table = 0;
142 cmdbuf->state.gfx.vs.desc.res_table = 0;
143 #endif
144
145 cmdbuf->vk.dynamic_graphics_state = save_ctx->dyn_state.all;
146 cmdbuf->state.gfx.dynamic.vi = save_ctx->dyn_state.vi;
147 cmdbuf->state.gfx.dynamic.sl = save_ctx->dyn_state.sl;
148 cmdbuf->state.gfx.occlusion_query = save_ctx->occlusion_query;
149 memcpy(cmdbuf->vk.dynamic_graphics_state.dirty,
150 cmdbuf->vk.dynamic_graphics_state.set,
151 sizeof(cmdbuf->vk.dynamic_graphics_state.set));
152 gfx_state_set_dirty(cmdbuf, VS);
153 gfx_state_set_dirty(cmdbuf, FS);
154 gfx_state_set_dirty(cmdbuf, VB);
155 gfx_state_set_dirty(cmdbuf, OQ);
156 gfx_state_set_dirty(cmdbuf, DESC_STATE);
157 gfx_state_set_dirty(cmdbuf, RENDER_STATE);
158 }
159
160 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdBlitImage2)161 panvk_per_arch(CmdBlitImage2)(VkCommandBuffer commandBuffer,
162 const VkBlitImageInfo2 *pBlitImageInfo)
163 {
164 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
165 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
166 struct panvk_cmd_meta_graphics_save_ctx save = {0};
167
168 panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
169 vk_meta_blit_image2(&cmdbuf->vk, &dev->meta, pBlitImageInfo);
170 panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
171 }
172
173 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdResolveImage2)174 panvk_per_arch(CmdResolveImage2)(VkCommandBuffer commandBuffer,
175 const VkResolveImageInfo2 *pResolveImageInfo)
176 {
177 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
178 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
179 struct panvk_cmd_meta_graphics_save_ctx save = {0};
180
181 panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
182 vk_meta_resolve_image2(&cmdbuf->vk, &dev->meta, pResolveImageInfo);
183 panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
184 }
185
186 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearAttachments)187 panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
188 uint32_t attachmentCount,
189 const VkClearAttachment *pAttachments,
190 uint32_t rectCount,
191 const VkClearRect *pRects)
192 {
193 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
194 const struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
195 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
196 struct panvk_cmd_meta_graphics_save_ctx save = {0};
197 struct vk_meta_rendering_info render = {
198 .view_mask = cmdbuf->state.gfx.render.view_mask,
199 .samples = fbinfo->nr_samples,
200 .color_attachment_count = fbinfo->rt_count,
201 .depth_attachment_format = cmdbuf->state.gfx.render.z_attachment.fmt,
202 .stencil_attachment_format = cmdbuf->state.gfx.render.s_attachment.fmt,
203 };
204 /* Multiview is not supported pre-v10 */
205 assert(cmdbuf->state.gfx.render.view_mask == 0 || PAN_ARCH >= 10);
206
207 for (uint32_t i = 0; i < render.color_attachment_count; i++) {
208 render.color_attachment_formats[i] =
209 cmdbuf->state.gfx.render.color_attachments.fmts[i];
210 render.color_attachment_write_masks[i] =
211 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
212 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
213 }
214
215 panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
216 vk_meta_clear_attachments(&cmdbuf->vk, &dev->meta, &render, attachmentCount,
217 pAttachments, rectCount, pRects);
218 panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
219 }
220
221 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearDepthStencilImage)222 panvk_per_arch(CmdClearDepthStencilImage)(
223 VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
224 const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
225 const VkImageSubresourceRange *pRanges)
226 {
227 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
228 VK_FROM_HANDLE(panvk_image, img, image);
229 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
230 struct panvk_cmd_meta_graphics_save_ctx save = {0};
231
232 panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
233 vk_meta_clear_depth_stencil_image(&cmdbuf->vk, &dev->meta, &img->vk,
234 imageLayout, pDepthStencil, rangeCount,
235 pRanges);
236 panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
237 }
238
239 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdClearColorImage)240 panvk_per_arch(CmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image,
241 VkImageLayout imageLayout,
242 const VkClearColorValue *pColor,
243 uint32_t rangeCount,
244 const VkImageSubresourceRange *pRanges)
245 {
246 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
247 VK_FROM_HANDLE(panvk_image, img, image);
248 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
249 struct panvk_cmd_meta_graphics_save_ctx save = {0};
250
251 panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
252 vk_meta_clear_color_image(&cmdbuf->vk, &dev->meta, &img->vk, imageLayout,
253 img->vk.format, pColor, rangeCount, pRanges);
254 panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
255 }
256
257 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyBuffer2)258 panvk_per_arch(CmdCopyBuffer2)(VkCommandBuffer commandBuffer,
259 const VkCopyBufferInfo2 *pCopyBufferInfo)
260 {
261 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
262 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
263 struct panvk_cmd_meta_compute_save_ctx save = {0};
264
265 panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
266 vk_meta_copy_buffer(&cmdbuf->vk, &dev->meta, pCopyBufferInfo);
267 panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
268 }
269
270 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyBufferToImage2)271 panvk_per_arch(CmdCopyBufferToImage2)(
272 VkCommandBuffer commandBuffer,
273 const VkCopyBufferToImageInfo2 *pCopyBufferToImageInfo)
274 {
275 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
276 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
277 VK_FROM_HANDLE(panvk_image, img, pCopyBufferToImageInfo->dstImage);
278 struct vk_meta_copy_image_properties img_props =
279 panvk_meta_copy_get_image_properties(img);
280 bool use_gfx_pipeline = copy_to_image_use_gfx_pipeline(dev, img);
281
282 if (use_gfx_pipeline) {
283 struct panvk_cmd_meta_graphics_save_ctx save = {0};
284
285 panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
286 vk_meta_copy_buffer_to_image(&cmdbuf->vk, &dev->meta,
287 pCopyBufferToImageInfo, &img_props,
288 VK_PIPELINE_BIND_POINT_GRAPHICS);
289 panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
290 } else {
291 struct panvk_cmd_meta_compute_save_ctx save = {0};
292
293 panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
294 vk_meta_copy_buffer_to_image(&cmdbuf->vk, &dev->meta,
295 pCopyBufferToImageInfo, &img_props,
296 VK_PIPELINE_BIND_POINT_COMPUTE);
297 panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
298 }
299 }
300
301 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyImageToBuffer2)302 panvk_per_arch(CmdCopyImageToBuffer2)(
303 VkCommandBuffer commandBuffer,
304 const VkCopyImageToBufferInfo2 *pCopyImageToBufferInfo)
305 {
306 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
307 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
308 VK_FROM_HANDLE(panvk_image, img, pCopyImageToBufferInfo->srcImage);
309 struct vk_meta_copy_image_properties img_props =
310 panvk_meta_copy_get_image_properties(img);
311 struct panvk_cmd_meta_compute_save_ctx save = {0};
312
313 panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
314 vk_meta_copy_image_to_buffer(&cmdbuf->vk, &dev->meta, pCopyImageToBufferInfo,
315 &img_props);
316 panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
317 }
318
319 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdFillBuffer)320 panvk_per_arch(CmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
321 VkDeviceSize dstOffset, VkDeviceSize fillSize,
322 uint32_t data)
323 {
324 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
325 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
326 struct panvk_cmd_meta_compute_save_ctx save = {0};
327
328 panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
329 vk_meta_fill_buffer(&cmdbuf->vk, &dev->meta, dstBuffer, dstOffset, fillSize,
330 data);
331 panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
332 }
333
334 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdUpdateBuffer)335 panvk_per_arch(CmdUpdateBuffer)(VkCommandBuffer commandBuffer,
336 VkBuffer dstBuffer, VkDeviceSize dstOffset,
337 VkDeviceSize dataSize, const void *pData)
338 {
339 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
340 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
341 struct panvk_cmd_meta_compute_save_ctx save = {0};
342
343 panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
344 vk_meta_update_buffer(&cmdbuf->vk, &dev->meta, dstBuffer, dstOffset,
345 dataSize, pData);
346 panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
347 }
348
349 VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdCopyImage2)350 panvk_per_arch(CmdCopyImage2)(VkCommandBuffer commandBuffer,
351 const VkCopyImageInfo2 *pCopyImageInfo)
352 {
353 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
354 struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
355 VK_FROM_HANDLE(panvk_image, src_img, pCopyImageInfo->srcImage);
356 VK_FROM_HANDLE(panvk_image, dst_img, pCopyImageInfo->dstImage);
357 struct vk_meta_copy_image_properties src_img_props =
358 panvk_meta_copy_get_image_properties(src_img);
359 struct vk_meta_copy_image_properties dst_img_props =
360 panvk_meta_copy_get_image_properties(dst_img);
361 bool use_gfx_pipeline = copy_to_image_use_gfx_pipeline(dev, dst_img);
362
363 if (use_gfx_pipeline) {
364 struct panvk_cmd_meta_graphics_save_ctx save = {0};
365
366 panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
367 vk_meta_copy_image(&cmdbuf->vk, &dev->meta, pCopyImageInfo,
368 &src_img_props, &dst_img_props,
369 VK_PIPELINE_BIND_POINT_GRAPHICS);
370 panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
371 } else {
372 struct panvk_cmd_meta_compute_save_ctx save = {0};
373
374 panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
375 vk_meta_copy_image(&cmdbuf->vk, &dev->meta, pCopyImageInfo,
376 &src_img_props, &dst_img_props,
377 VK_PIPELINE_BIND_POINT_COMPUTE);
378 panvk_per_arch(cmd_meta_compute_end)(cmdbuf, &save);
379 }
380 }
381