1 /*
2 * Copyright © 2022 Collabora Ltd
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23 #ifndef VK_META_H
24 #define VK_META_H
25
26 #include "vk_limits.h"
27 #include "vk_object.h"
28
29 #include "util/simple_mtx.h"
30
31 #include "compiler/nir/nir.h"
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 struct hash_table;
38 struct vk_command_buffer;
39 struct vk_buffer;
40 struct vk_device;
41 struct vk_image;
42
43 struct vk_meta_rect {
44 uint32_t x0, y0, x1, y1;
45 float z;
46 uint32_t layer;
47 };
48
49 #define VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA (VkPrimitiveTopology)11
50 #define VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA (VkImageViewCreateFlagBits)0x80000000
51
52 struct vk_meta_copy_image_properties {
53 union {
54 struct {
55 /* Format to use for the image view of a color aspect.
56 * Format must not be compressed and be in the RGB/sRGB colorspace.
57 */
58 VkFormat view_format;
59 } color;
60
61 struct {
62 struct {
63 /* Format to use for the image view of a depth aspect.
64 * Format must not be compressed and be in the RGB/sRGB colorspace.
65 */
66 VkFormat view_format;
67
68 /* Describe the depth/stencil componant layout. Bits in the mask
69 * must be consecutive and match the original depth bit size.
70 */
71 uint8_t component_mask;
72 } depth;
73
74 struct {
75 /* Format to use for the image view of a stencil aspect.
76 * Format must not be compressed and be in the RGB/sRGB colorspace.
77 */
78 VkFormat view_format;
79
80 /* Describe the depth/stencil componant layout. Bits in the mask
81 * must be consecutive and match the original depth bit size.
82 */
83 uint8_t component_mask;
84 } stencil;
85 };
86 };
87
88 /* Size of the image tile. Used to select the optimal workgroup size. */
89 VkExtent3D tile_size;
90 };
91
92 enum vk_meta_buffer_chunk_size_id {
93 VK_META_BUFFER_1_BYTE_CHUNK = 0,
94 VK_META_BUFFER_2_BYTE_CHUNK,
95 VK_META_BUFFER_4_BYTE_CHUNK,
96 VK_META_BUFFER_8_BYTE_CHUNK,
97 VK_META_BUFFER_16_BYTE_CHUNK,
98 VK_META_BUFFER_CHUNK_SIZE_COUNT,
99 };
100
101 struct vk_meta_device {
102 struct hash_table *cache;
103 simple_mtx_t cache_mtx;
104
105 VkPipelineCache pipeline_cache;
106
107 uint32_t max_bind_map_buffer_size_B;
108 bool use_layered_rendering;
109 bool use_gs_for_layer;
110 bool use_stencil_export;
111
112 bool use_rect_list_pipeline;
113
114 struct {
115 /* Optimal workgroup size for each possible chunk size. This should be
116 * chosen to keep things cache-friendly (something big enough to maximize
117 * cache hits on executing threads, but small enough to not trash the
118 * cache) while keeping GPU utilization high enough to not make copies
119 * fast enough.
120 */
121 uint32_t optimal_wg_size[VK_META_BUFFER_CHUNK_SIZE_COUNT];
122 } buffer_access;
123
124 VkResult (*cmd_bind_map_buffer)(struct vk_command_buffer *cmd,
125 struct vk_meta_device *meta,
126 VkBuffer buffer,
127 void **map_out);
128
129 void (*cmd_draw_rects)(struct vk_command_buffer *cmd,
130 struct vk_meta_device *meta,
131 uint32_t rect_count,
132 const struct vk_meta_rect *rects);
133
134 void (*cmd_draw_volume)(struct vk_command_buffer *cmd,
135 struct vk_meta_device *meta,
136 const struct vk_meta_rect *rect,
137 uint32_t layer_count);
138 };
139
140 static inline uint32_t
vk_meta_buffer_access_wg_size(const struct vk_meta_device * meta,uint32_t chunk_size)141 vk_meta_buffer_access_wg_size(const struct vk_meta_device *meta,
142 uint32_t chunk_size)
143 {
144 assert(util_is_power_of_two_nonzero(chunk_size));
145 unsigned idx = ffs(chunk_size) - 1;
146
147 assert(idx < ARRAY_SIZE(meta->buffer_access.optimal_wg_size));
148 assert(meta->buffer_access.optimal_wg_size[idx] != 0);
149
150 return meta->buffer_access.optimal_wg_size[idx];
151 }
152
153 VkResult vk_meta_device_init(struct vk_device *device,
154 struct vk_meta_device *meta);
155 void vk_meta_device_finish(struct vk_device *device,
156 struct vk_meta_device *meta);
157
158 /** Keys should start with one of these to ensure uniqueness */
159 enum vk_meta_object_key_type {
160 VK_META_OBJECT_KEY_TYPE_INVALID = 0,
161 VK_META_OBJECT_KEY_CLEAR_PIPELINE,
162 VK_META_OBJECT_KEY_BLIT_PIPELINE,
163 VK_META_OBJECT_KEY_BLIT_SAMPLER,
164 VK_META_OBJECT_KEY_COPY_BUFFER_PIPELINE,
165 VK_META_OBJECT_KEY_COPY_IMAGE_TO_BUFFER_PIPELINE,
166 VK_META_OBJECT_KEY_COPY_BUFFER_TO_IMAGE_PIPELINE,
167 VK_META_OBJECT_KEY_COPY_IMAGE_PIPELINE,
168 VK_META_OBJECT_KEY_FILL_BUFFER_PIPELINE,
169
170 /* Should be used as an offset for driver-specific object types. */
171 VK_META_OBJECT_KEY_DRIVER_OFFSET = 0x80000000,
172 };
173
174 uint64_t vk_meta_lookup_object(struct vk_meta_device *meta,
175 VkObjectType obj_type,
176 const void *key_data, size_t key_size);
177
178 uint64_t vk_meta_cache_object(struct vk_device *device,
179 struct vk_meta_device *meta,
180 const void *key_data, size_t key_size,
181 VkObjectType obj_type,
182 uint64_t handle);
183
184 static inline VkDescriptorSetLayout
vk_meta_lookup_descriptor_set_layout(struct vk_meta_device * meta,const void * key_data,size_t key_size)185 vk_meta_lookup_descriptor_set_layout(struct vk_meta_device *meta,
186 const void *key_data, size_t key_size)
187 {
188 return (VkDescriptorSetLayout)
189 vk_meta_lookup_object(meta, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
190 key_data, key_size);
191 }
192
193 static inline VkPipelineLayout
vk_meta_lookup_pipeline_layout(struct vk_meta_device * meta,const void * key_data,size_t key_size)194 vk_meta_lookup_pipeline_layout(struct vk_meta_device *meta,
195 const void *key_data, size_t key_size)
196 {
197 return (VkPipelineLayout)
198 vk_meta_lookup_object(meta, VK_OBJECT_TYPE_PIPELINE_LAYOUT,
199 key_data, key_size);
200 }
201
202 static inline VkPipeline
vk_meta_lookup_pipeline(struct vk_meta_device * meta,const void * key_data,size_t key_size)203 vk_meta_lookup_pipeline(struct vk_meta_device *meta,
204 const void *key_data, size_t key_size)
205 {
206 return (VkPipeline)vk_meta_lookup_object(meta, VK_OBJECT_TYPE_PIPELINE,
207 key_data, key_size);
208 }
209
210 static inline VkSampler
vk_meta_lookup_sampler(struct vk_meta_device * meta,const void * key_data,size_t key_size)211 vk_meta_lookup_sampler(struct vk_meta_device *meta,
212 const void *key_data, size_t key_size)
213 {
214 return (VkSampler)vk_meta_lookup_object(meta, VK_OBJECT_TYPE_SAMPLER,
215 key_data, key_size);
216 }
217
218 struct vk_meta_rendering_info {
219 uint32_t view_mask;
220 uint32_t samples;
221 uint32_t color_attachment_count;
222 VkFormat color_attachment_formats[MESA_VK_MAX_COLOR_ATTACHMENTS];
223 VkColorComponentFlags color_attachment_write_masks[MESA_VK_MAX_COLOR_ATTACHMENTS];
224 VkFormat depth_attachment_format;
225 VkFormat stencil_attachment_format;
226 };
227
228 VkResult
229 vk_meta_create_descriptor_set_layout(struct vk_device *device,
230 struct vk_meta_device *meta,
231 const VkDescriptorSetLayoutCreateInfo *info,
232 const void *key_data, size_t key_size,
233 VkDescriptorSetLayout *layout_out);
234
235 VkResult
236 vk_meta_create_pipeline_layout(struct vk_device *device,
237 struct vk_meta_device *meta,
238 const VkPipelineLayoutCreateInfo *info,
239 const void *key_data, size_t key_size,
240 VkPipelineLayout *layout_out);
241
242 VkResult
243 vk_meta_get_pipeline_layout(struct vk_device *device,
244 struct vk_meta_device *meta,
245 const VkDescriptorSetLayoutCreateInfo *desc_info,
246 const VkPushConstantRange *push_range,
247 const void *key_data, size_t key_size,
248 VkPipelineLayout *layout_out);
249
250 VkResult
251 vk_meta_create_graphics_pipeline(struct vk_device *device,
252 struct vk_meta_device *meta,
253 const VkGraphicsPipelineCreateInfo *info,
254 const struct vk_meta_rendering_info *render,
255 const void *key_data, size_t key_size,
256 VkPipeline *pipeline_out);
257
258 VkResult
259 vk_meta_create_compute_pipeline(struct vk_device *device,
260 struct vk_meta_device *meta,
261 const VkComputePipelineCreateInfo *info,
262 const void *key_data, size_t key_size,
263 VkPipeline *pipeline_out);
264
265 VkResult
266 vk_meta_create_sampler(struct vk_device *device,
267 struct vk_meta_device *meta,
268 const VkSamplerCreateInfo *info,
269 const void *key_data, size_t key_size,
270 VkSampler *sampler_out);
271
272 VkResult vk_meta_create_buffer(struct vk_command_buffer *cmd,
273 struct vk_meta_device *meta,
274 const VkBufferCreateInfo *info,
275 VkBuffer *buffer_out);
276
277 VkResult vk_meta_create_buffer_view(struct vk_command_buffer *cmd,
278 struct vk_meta_device *meta,
279 const VkBufferViewCreateInfo *info,
280 VkBufferView *buffer_view_out);
281
282 VkResult vk_meta_create_image_view(struct vk_command_buffer *cmd,
283 struct vk_meta_device *meta,
284 const VkImageViewCreateInfo *info,
285 VkImageView *image_view_out);
286
287 void vk_meta_draw_rects(struct vk_command_buffer *cmd,
288 struct vk_meta_device *meta,
289 uint32_t rect_count,
290 const struct vk_meta_rect *rects);
291
292 void vk_meta_draw_volume(struct vk_command_buffer *cmd,
293 struct vk_meta_device *meta,
294 const struct vk_meta_rect *rect,
295 uint32_t layer_count);
296
297 void vk_meta_clear_attachments(struct vk_command_buffer *cmd,
298 struct vk_meta_device *meta,
299 const struct vk_meta_rendering_info *render,
300 uint32_t attachment_count,
301 const VkClearAttachment *attachments,
302 uint32_t rect_count,
303 const VkClearRect *rects);
304
305 void vk_meta_clear_rendering(struct vk_meta_device *meta,
306 struct vk_command_buffer *cmd,
307 const VkRenderingInfo *pRenderingInfo);
308
309 void vk_meta_clear_color_image(struct vk_command_buffer *cmd,
310 struct vk_meta_device *meta,
311 struct vk_image *image,
312 VkImageLayout image_layout,
313 VkFormat format,
314 const VkClearColorValue *color,
315 uint32_t range_count,
316 const VkImageSubresourceRange *ranges);
317
318 void vk_meta_clear_depth_stencil_image(struct vk_command_buffer *cmd,
319 struct vk_meta_device *meta,
320 struct vk_image *image,
321 VkImageLayout image_layout,
322 const VkClearDepthStencilValue *depth_stencil,
323 uint32_t range_count,
324 const VkImageSubresourceRange *ranges);
325
326 void vk_meta_blit_image(struct vk_command_buffer *cmd,
327 struct vk_meta_device *meta,
328 struct vk_image *src_image,
329 VkFormat src_format,
330 VkImageLayout src_image_layout,
331 struct vk_image *dst_image,
332 VkFormat dst_format,
333 VkImageLayout dst_image_layout,
334 uint32_t region_count,
335 const VkImageBlit2 *regions,
336 VkFilter filter);
337
338 void vk_meta_blit_image2(struct vk_command_buffer *cmd,
339 struct vk_meta_device *meta,
340 const VkBlitImageInfo2 *blit);
341
342 void vk_meta_resolve_image(struct vk_command_buffer *cmd,
343 struct vk_meta_device *meta,
344 struct vk_image *src_image,
345 VkFormat src_format,
346 VkImageLayout src_image_layout,
347 struct vk_image *dst_image,
348 VkFormat dst_format,
349 VkImageLayout dst_image_layout,
350 uint32_t region_count,
351 const VkImageResolve2 *regions,
352 VkResolveModeFlagBits resolve_mode,
353 VkResolveModeFlagBits stencil_resolve_mode);
354
355 void vk_meta_resolve_image2(struct vk_command_buffer *cmd,
356 struct vk_meta_device *meta,
357 const VkResolveImageInfo2 *resolve);
358
359 void vk_meta_resolve_rendering(struct vk_command_buffer *cmd,
360 struct vk_meta_device *meta,
361 const VkRenderingInfo *pRenderingInfo);
362
363 VkDeviceAddress vk_meta_buffer_address(struct vk_device *device,
364 VkBuffer buffer, uint64_t offset,
365 uint64_t range);
366
367 void vk_meta_copy_buffer(struct vk_command_buffer *cmd,
368 struct vk_meta_device *meta,
369 const VkCopyBufferInfo2 *info);
370
371 void vk_meta_copy_image_to_buffer(
372 struct vk_command_buffer *cmd, struct vk_meta_device *meta,
373 const VkCopyImageToBufferInfo2 *info,
374 const struct vk_meta_copy_image_properties *img_props);
375
376 void vk_meta_copy_buffer_to_image(
377 struct vk_command_buffer *cmd, struct vk_meta_device *meta,
378 const VkCopyBufferToImageInfo2 *info,
379 const struct vk_meta_copy_image_properties *img_props,
380 VkPipelineBindPoint bind_point);
381
382 void vk_meta_copy_image(struct vk_command_buffer *cmd,
383 struct vk_meta_device *meta,
384 const VkCopyImageInfo2 *info,
385 const struct vk_meta_copy_image_properties *src_props,
386 const struct vk_meta_copy_image_properties *dst_props,
387 VkPipelineBindPoint bind_point);
388
389 void vk_meta_update_buffer(struct vk_command_buffer *cmd,
390 struct vk_meta_device *meta, VkBuffer buffer,
391 VkDeviceSize offset, VkDeviceSize size,
392 const void *data);
393
394 void vk_meta_fill_buffer(struct vk_command_buffer *cmd,
395 struct vk_meta_device *meta, VkBuffer buffer,
396 VkDeviceSize offset, VkDeviceSize size, uint32_t data);
397
398 static inline enum glsl_sampler_dim
vk_image_view_type_to_sampler_dim(VkImageViewType view_type)399 vk_image_view_type_to_sampler_dim(VkImageViewType view_type)
400 {
401 switch (view_type) {
402 case VK_IMAGE_VIEW_TYPE_1D:
403 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
404 return GLSL_SAMPLER_DIM_1D;
405
406 case VK_IMAGE_VIEW_TYPE_2D:
407 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
408 return GLSL_SAMPLER_DIM_2D;
409
410 case VK_IMAGE_VIEW_TYPE_CUBE:
411 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
412 return GLSL_SAMPLER_DIM_CUBE;
413
414 case VK_IMAGE_VIEW_TYPE_3D:
415 return GLSL_SAMPLER_DIM_3D;
416
417 default:
418 unreachable();
419 }
420 }
421
422 static inline bool
vk_image_view_type_is_array(VkImageViewType view_type)423 vk_image_view_type_is_array(VkImageViewType view_type)
424 {
425 switch (view_type) {
426 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
427 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
428 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
429 return true;
430
431 case VK_IMAGE_VIEW_TYPE_1D:
432 case VK_IMAGE_VIEW_TYPE_2D:
433 case VK_IMAGE_VIEW_TYPE_3D:
434 case VK_IMAGE_VIEW_TYPE_CUBE:
435 return false;
436
437 default:
438 unreachable();
439 }
440 }
441
442 #ifdef __cplusplus
443 }
444 #endif
445
446 #endif /* VK_META_H */
447