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 #include "util/u_dynarray.h"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 struct hash_table;
37 struct vk_command_buffer;
38 struct vk_device;
39 struct vk_image;
40 
41 struct vk_meta_rect {
42    uint32_t x0, y0, x1, y1;
43    float z;
44    uint32_t layer;
45 };
46 
47 #define VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA (VkPrimitiveTopology)11
48 
49 struct vk_meta_device {
50    struct hash_table *cache;
51    simple_mtx_t cache_mtx;
52 
53    uint32_t max_bind_map_buffer_size_B;
54    bool use_layered_rendering;
55    bool use_gs_for_layer;
56    bool use_stencil_export;
57 
58    VkResult (*cmd_bind_map_buffer)(struct vk_command_buffer *cmd,
59                                    struct vk_meta_device *meta,
60                                    VkBuffer buffer,
61                                    void **map_out);
62 
63    void (*cmd_draw_rects)(struct vk_command_buffer *cmd,
64                           struct vk_meta_device *meta,
65                           uint32_t rect_count,
66                           const struct vk_meta_rect *rects);
67 
68    void (*cmd_draw_volume)(struct vk_command_buffer *cmd,
69                            struct vk_meta_device *meta,
70                            const struct vk_meta_rect *rect,
71                            uint32_t layer_count);
72 };
73 
74 VkResult vk_meta_device_init(struct vk_device *device,
75                              struct vk_meta_device *meta);
76 void vk_meta_device_finish(struct vk_device *device,
77                            struct vk_meta_device *meta);
78 
79 /** Keys should start with one of these to ensure uniqueness */
80 enum vk_meta_object_key_type {
81    VK_META_OBJECT_KEY_TYPE_INVALD = 0,
82    VK_META_OBJECT_KEY_CLEAR_PIPELINE,
83    VK_META_OBJECT_KEY_BLIT_PIPELINE,
84    VK_META_OBJECT_KEY_BLIT_SAMPLER,
85 };
86 
87 uint64_t vk_meta_lookup_object(struct vk_meta_device *meta,
88                                 VkObjectType obj_type,
89                                 const void *key_data, size_t key_size);
90 
91 uint64_t vk_meta_cache_object(struct vk_device *device,
92                               struct vk_meta_device *meta,
93                               const void *key_data, size_t key_size,
94                               VkObjectType obj_type,
95                               uint64_t handle);
96 
97 static inline VkDescriptorSetLayout
vk_meta_lookup_descriptor_set_layout(struct vk_meta_device * meta,const void * key_data,size_t key_size)98 vk_meta_lookup_descriptor_set_layout(struct vk_meta_device *meta,
99                                      const void *key_data, size_t key_size)
100 {
101    return (VkDescriptorSetLayout)
102       vk_meta_lookup_object(meta, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
103                             key_data, key_size);
104 }
105 
106 static inline VkPipelineLayout
vk_meta_lookup_pipeline_layout(struct vk_meta_device * meta,const void * key_data,size_t key_size)107 vk_meta_lookup_pipeline_layout(struct vk_meta_device *meta,
108                                const void *key_data, size_t key_size)
109 {
110    return (VkPipelineLayout)
111       vk_meta_lookup_object(meta, VK_OBJECT_TYPE_PIPELINE_LAYOUT,
112                             key_data, key_size);
113 }
114 
115 static inline VkPipeline
vk_meta_lookup_pipeline(struct vk_meta_device * meta,const void * key_data,size_t key_size)116 vk_meta_lookup_pipeline(struct vk_meta_device *meta,
117                         const void *key_data, size_t key_size)
118 {
119    return (VkPipeline)vk_meta_lookup_object(meta, VK_OBJECT_TYPE_PIPELINE,
120                                             key_data, key_size);
121 }
122 
123 static inline VkSampler
vk_meta_lookup_sampler(struct vk_meta_device * meta,const void * key_data,size_t key_size)124 vk_meta_lookup_sampler(struct vk_meta_device *meta,
125                        const void *key_data, size_t key_size)
126 {
127    return (VkSampler)vk_meta_lookup_object(meta, VK_OBJECT_TYPE_SAMPLER,
128                                            key_data, key_size);
129 }
130 
131 struct vk_meta_rendering_info {
132    uint32_t view_mask;
133    uint32_t samples;
134    uint32_t color_attachment_count;
135    VkFormat color_attachment_formats[MESA_VK_MAX_COLOR_ATTACHMENTS];
136    VkFormat depth_attachment_format;
137    VkFormat stencil_attachment_format;
138 };
139 
140 VkResult
141 vk_meta_create_descriptor_set_layout(struct vk_device *device,
142                                      struct vk_meta_device *meta,
143                                      const VkDescriptorSetLayoutCreateInfo *info,
144                                      const void *key_data, size_t key_size,
145                                      VkDescriptorSetLayout *layout_out);
146 
147 VkResult
148 vk_meta_create_pipeline_layout(struct vk_device *device,
149                                struct vk_meta_device *meta,
150                                const VkPipelineLayoutCreateInfo *info,
151                                const void *key_data, size_t key_size,
152                                VkPipelineLayout *layout_out);
153 
154 VkResult
155 vk_meta_get_pipeline_layout(struct vk_device *device,
156                             struct vk_meta_device *meta,
157                             const VkDescriptorSetLayoutCreateInfo *desc_info,
158                             const VkPushConstantRange *push_range,
159                             const void *key_data, size_t key_size,
160                             VkPipelineLayout *layout_out);
161 
162 VkResult
163 vk_meta_create_graphics_pipeline(struct vk_device *device,
164                                  struct vk_meta_device *meta,
165                                  const VkGraphicsPipelineCreateInfo *info,
166                                  const struct vk_meta_rendering_info *render,
167                                  const void *key_data, size_t key_size,
168                                  VkPipeline *pipeline_out);
169 
170 VkResult
171 vk_meta_create_compute_pipeline(struct vk_device *device,
172                                 struct vk_meta_device *meta,
173                                 const VkComputePipelineCreateInfo *info,
174                                 const void *key_data, size_t key_size,
175                                 VkPipeline *pipeline_out);
176 
177 VkResult
178 vk_meta_create_sampler(struct vk_device *device,
179                        struct vk_meta_device *meta,
180                        const VkSamplerCreateInfo *info,
181                        const void *key_data, size_t key_size,
182                        VkSampler *sampler_out);
183 
184 struct vk_meta_object_list {
185    struct util_dynarray arr;
186 };
187 
188 void vk_meta_object_list_init(struct vk_meta_object_list *mol);
189 void vk_meta_object_list_reset(struct vk_device *device,
190                                struct vk_meta_object_list *mol);
191 void vk_meta_object_list_finish(struct vk_device *device,
192                                 struct vk_meta_object_list *mol);
193 
194 static inline void
vk_meta_object_list_add_obj(struct vk_meta_object_list * mol,struct vk_object_base * obj)195 vk_meta_object_list_add_obj(struct vk_meta_object_list *mol,
196                             struct vk_object_base *obj)
197 {
198    util_dynarray_append(&mol->arr, struct vk_object_base *, obj);
199 }
200 
201 static inline void
vk_meta_object_list_add_handle(struct vk_meta_object_list * mol,VkObjectType obj_type,uint64_t handle)202 vk_meta_object_list_add_handle(struct vk_meta_object_list *mol,
203                                VkObjectType obj_type,
204                                uint64_t handle)
205 {
206    vk_meta_object_list_add_obj(mol,
207       vk_object_base_from_u64_handle(handle, obj_type));
208 }
209 
210 VkResult vk_meta_create_buffer(struct vk_command_buffer *cmd,
211                                struct vk_meta_device *meta,
212                                const VkBufferCreateInfo *info,
213                                VkBuffer *buffer_out);
214 VkResult vk_meta_create_image_view(struct vk_command_buffer *cmd,
215                                    struct vk_meta_device *meta,
216                                    const VkImageViewCreateInfo *info,
217                                    VkImageView *image_view_out);
218 
219 void vk_meta_draw_rects(struct vk_command_buffer *cmd,
220                         struct vk_meta_device *meta,
221                         uint32_t rect_count,
222                         const struct vk_meta_rect *rects);
223 
224 void vk_meta_draw_volume(struct vk_command_buffer *cmd,
225                          struct vk_meta_device *meta,
226                          const struct vk_meta_rect *rect,
227                          uint32_t layer_count);
228 
229 void vk_meta_clear_attachments(struct vk_command_buffer *cmd,
230                                struct vk_meta_device *meta,
231                                const struct vk_meta_rendering_info *render,
232                                uint32_t attachment_count,
233                                const VkClearAttachment *attachments,
234                                uint32_t rect_count,
235                                const VkClearRect *rects);
236 
237 void vk_meta_clear_rendering(struct vk_meta_device *meta,
238                              struct vk_command_buffer *cmd,
239                              const VkRenderingInfo *pRenderingInfo);
240 
241 void vk_meta_clear_color_image(struct vk_command_buffer *cmd,
242                                struct vk_meta_device *meta,
243                                struct vk_image *image,
244                                VkImageLayout image_layout,
245                                VkFormat format,
246                                const VkClearColorValue *color,
247                                uint32_t range_count,
248                                const VkImageSubresourceRange *ranges);
249 
250 void vk_meta_clear_depth_stencil_image(struct vk_command_buffer *cmd,
251                                        struct vk_meta_device *meta,
252                                        struct vk_image *image,
253                                        VkImageLayout image_layout,
254                                        const VkClearDepthStencilValue *depth_stencil,
255                                        uint32_t range_count,
256                                        const VkImageSubresourceRange *ranges);
257 
258 void vk_meta_blit_image(struct vk_command_buffer *cmd,
259                         struct vk_meta_device *meta,
260                         struct vk_image *src_image,
261                         VkFormat src_format,
262                         VkImageLayout src_image_layout,
263                         struct vk_image *dst_image,
264                         VkFormat dst_format,
265                         VkImageLayout dst_image_layout,
266                         uint32_t region_count,
267                         const VkImageBlit2 *regions,
268                         VkFilter filter);
269 
270 void vk_meta_blit_image2(struct vk_command_buffer *cmd,
271                          struct vk_meta_device *meta,
272                          const VkBlitImageInfo2 *blit);
273 
274 void vk_meta_resolve_image(struct vk_command_buffer *cmd,
275                            struct vk_meta_device *meta,
276                            struct vk_image *src_image,
277                            VkFormat src_format,
278                            VkImageLayout src_image_layout,
279                            struct vk_image *dst_image,
280                            VkFormat dst_format,
281                            VkImageLayout dst_image_layout,
282                            uint32_t region_count,
283                            const VkImageResolve2 *regions,
284                            VkResolveModeFlagBits resolve_mode,
285                            VkResolveModeFlagBits stencil_resolve_mode);
286 
287 void vk_meta_resolve_image2(struct vk_command_buffer *cmd,
288                             struct vk_meta_device *meta,
289                             const VkResolveImageInfo2 *resolve);
290 
291 void vk_meta_resolve_rendering(struct vk_command_buffer *cmd,
292                                struct vk_meta_device *meta,
293                                const VkRenderingInfo *pRenderingInfo);
294 
295 #ifdef __cplusplus
296 }
297 #endif
298 
299 #endif /* VK_META_H */
300