• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2017 Intel Corporation
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 WSI_COMMON_PRIVATE_H
24 #define WSI_COMMON_PRIVATE_H
25 
26 #include "wsi_common.h"
27 #include "util/perf/cpu_trace.h"
28 #include "vk_object.h"
29 #include "vk_sync.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 struct wsi_image;
36 struct wsi_swapchain;
37 
38 #define WSI_DEBUG_BUFFER      (1ull << 0)
39 #define WSI_DEBUG_SW          (1ull << 1)
40 #define WSI_DEBUG_NOSHM       (1ull << 2)
41 #define WSI_DEBUG_LINEAR      (1ull << 3)
42 #define WSI_DEBUG_DXGI        (1ull << 4)
43 #define WSI_DEBUG_NOWLTS      (1ull << 5)
44 
45 extern uint64_t WSI_DEBUG;
46 
47 enum wsi_image_type {
48    WSI_IMAGE_TYPE_CPU,
49    WSI_IMAGE_TYPE_DRM,
50    WSI_IMAGE_TYPE_DXGI,
51 };
52 
53 struct wsi_base_image_params {
54    enum wsi_image_type image_type;
55 };
56 
57 struct wsi_cpu_image_params {
58    struct wsi_base_image_params base;
59 
60    uint8_t *(*alloc_shm)(struct wsi_image *image, unsigned size);
61 };
62 
63 struct wsi_drm_image_params {
64    struct wsi_base_image_params base;
65 
66    bool same_gpu;
67    bool explicit_sync;
68 
69    uint32_t num_modifier_lists;
70    const uint32_t *num_modifiers;
71    const uint64_t *const *modifiers;
72 };
73 
74 struct wsi_dxgi_image_params {
75    struct wsi_base_image_params base;
76    bool storage_image;
77 };
78 
79 typedef uint32_t (*wsi_memory_type_select_cb)(const struct wsi_device *wsi,
80                                               uint32_t type_bits);
81 
82 struct wsi_image_info {
83    VkImageCreateInfo create;
84    struct wsi_image_create_info wsi;
85    VkExternalMemoryImageCreateInfo ext_mem;
86    VkImageFormatListCreateInfo format_list;
87    VkImageDrmFormatModifierListCreateInfoEXT drm_mod_list;
88 
89    enum wsi_image_type image_type;
90    bool explicit_sync;
91    bool prime_use_linear_modifier;
92 
93    /* Not really part of VkImageCreateInfo but needed to figure out the
94     * number of planes we need to bind.
95     */
96    uint32_t modifier_prop_count;
97    struct VkDrmFormatModifierPropertiesEXT *modifier_props;
98 
99    /* For buffer blit images, the linear stride in bytes */
100    uint32_t linear_stride;
101 
102    /* For buffer blit images, the size of the buffer in bytes */
103    uint64_t linear_size;
104 
105    wsi_memory_type_select_cb select_image_memory_type;
106    wsi_memory_type_select_cb select_blit_dst_memory_type;
107 
108    uint8_t *(*alloc_shm)(struct wsi_image *image, unsigned size);
109 
110    VkResult (*create_mem)(const struct wsi_swapchain *chain,
111                           const struct wsi_image_info *info,
112                           struct wsi_image *image);
113 
114    VkResult (*finish_create)(const struct wsi_swapchain *chain,
115                              const struct wsi_image_info *info,
116                              struct wsi_image *image);
117 };
118 
119 enum wsi_explicit_sync_timelines
120 {
121    WSI_ES_ACQUIRE,
122    WSI_ES_RELEASE,
123 
124    WSI_ES_COUNT,
125 };
126 
127 struct wsi_image_explicit_sync_timeline {
128    VkSemaphore semaphore;
129    uint64_t timeline;
130    int fd;
131    uint32_t handle;
132 };
133 
134 enum wsi_swapchain_blit_type {
135    WSI_SWAPCHAIN_NO_BLIT,
136    WSI_SWAPCHAIN_BUFFER_BLIT,
137    WSI_SWAPCHAIN_IMAGE_BLIT,
138 };
139 
140 struct wsi_image {
141    VkImage image;
142    VkDeviceMemory memory;
143 
144    struct {
145       VkBuffer buffer;
146       VkImage image;
147       VkDeviceMemory memory;
148       VkCommandBuffer *cmd_buffers;
149    } blit;
150    /* Whether or not the image has been acquired
151     * on the CPU side via acquire_next_image.
152     */
153    bool acquired;
154    uint64_t present_serial;
155 
156    struct wsi_image_explicit_sync_timeline explicit_sync[WSI_ES_COUNT];
157 
158 #ifndef _WIN32
159    uint64_t drm_modifier;
160 #endif
161    int num_planes;
162    uint32_t sizes[4];
163    uint32_t offsets[4];
164    uint32_t row_pitches[4];
165 #ifndef _WIN32
166    int dma_buf_fd;
167 #endif
168    void *cpu_map;
169 };
170 
171 struct wsi_swapchain {
172    struct vk_object_base base;
173 
174    const struct wsi_device *wsi;
175 
176    VkDevice device;
177    VkAllocationCallbacks alloc;
178    VkFence* fences;
179    VkPresentModeKHR present_mode;
180    VkSemaphore present_id_timeline;
181 
182    int signal_dma_buf_from_semaphore;
183    VkSemaphore dma_buf_semaphore;
184 
185    struct wsi_image_info image_info;
186    uint32_t image_count;
187 
188    uint64_t present_serial;
189 
190    struct {
191       enum wsi_swapchain_blit_type type;
192       VkSemaphore *semaphores;
193 
194       /* If the driver wants to use a special queue to execute the buffer blit,
195        * it'll implement the wsi_device::get_blit_queue callback.
196        * The created queue will be stored here and will be used to execute the
197        * buffer blit instead of using the present queue.
198        */
199       VkQueue queue;
200    } blit;
201 
202    bool capture_key_pressed;
203 
204    /* Command pools, one per queue family */
205    VkCommandPool *cmd_pools;
206 
207    VkResult (*destroy)(struct wsi_swapchain *swapchain,
208                        const VkAllocationCallbacks *pAllocator);
209    struct wsi_image *(*get_wsi_image)(struct wsi_swapchain *swapchain,
210                                       uint32_t image_index);
211    VkResult (*acquire_next_image)(struct wsi_swapchain *swap_chain,
212                                   const VkAcquireNextImageInfoKHR *info,
213                                   uint32_t *image_index);
214    VkResult (*queue_present)(struct wsi_swapchain *swap_chain,
215                              uint32_t image_index,
216                              uint64_t present_id,
217                              const VkPresentRegionKHR *damage);
218    VkResult (*wait_for_present)(struct wsi_swapchain *swap_chain,
219                                 uint64_t present_id,
220                                 uint64_t timeout);
221    VkResult (*release_images)(struct wsi_swapchain *swap_chain,
222                               uint32_t count,
223                               const uint32_t *indices);
224    void (*set_present_mode)(struct wsi_swapchain *swap_chain,
225                             VkPresentModeKHR mode);
226 };
227 
228 bool
229 wsi_device_matches_drm_fd(VkPhysicalDevice pdevice, int drm_fd);
230 
231 void
232 wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance,
233                        const VkAllocationCallbacks *pAllocator);
234 
235 void
236 wsi_win32_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance,
237                           const VkAllocationCallbacks *pAllocator);
238 
239 VkResult
240 wsi_swapchain_init(const struct wsi_device *wsi,
241                    struct wsi_swapchain *chain,
242                    VkDevice device,
243                    const VkSwapchainCreateInfoKHR *pCreateInfo,
244                    const struct wsi_base_image_params *image_params,
245                    const VkAllocationCallbacks *pAllocator);
246 
247 VkPresentModeKHR
248 wsi_swapchain_get_present_mode(struct wsi_device *wsi,
249                                const VkSwapchainCreateInfoKHR *pCreateInfo);
250 
251 void wsi_swapchain_finish(struct wsi_swapchain *chain);
252 
253 uint32_t
254 wsi_select_memory_type(const struct wsi_device *wsi,
255                        VkMemoryPropertyFlags req_flags,
256                        VkMemoryPropertyFlags deny_flags,
257                        uint32_t type_bits);
258 uint32_t
259 wsi_select_device_memory_type(const struct wsi_device *wsi,
260                               uint32_t type_bits);
261 
262 bool
263 wsi_drm_image_needs_buffer_blit(const struct wsi_device *wsi,
264                                 const struct wsi_drm_image_params *params);
265 
266 enum wsi_swapchain_blit_type
267 wsi_dxgi_image_needs_blit(const struct wsi_device *wsi,
268                           const struct wsi_dxgi_image_params *params,
269                           VkDevice device);
270 
271 VkResult
272 wsi_drm_configure_image(const struct wsi_swapchain *chain,
273                         const VkSwapchainCreateInfoKHR *pCreateInfo,
274                         const struct wsi_drm_image_params *params,
275                         struct wsi_image_info *info);
276 
277 VkResult
278 wsi_dxgi_configure_image(const struct wsi_swapchain *chain,
279                          const VkSwapchainCreateInfoKHR *pCreateInfo,
280                          const struct wsi_dxgi_image_params *params,
281                          struct wsi_image_info *info);
282 
283 bool
284 wsi_cpu_image_needs_buffer_blit(const struct wsi_device *wsi,
285                                 const struct wsi_cpu_image_params *params);
286 
287 VkResult
288 wsi_configure_cpu_image(const struct wsi_swapchain *chain,
289                         const VkSwapchainCreateInfoKHR *pCreateInfo,
290                         const struct wsi_cpu_image_params *params,
291                         struct wsi_image_info *info);
292 
293 VkResult
294 wsi_create_buffer_blit_context(const struct wsi_swapchain *chain,
295                                const struct wsi_image_info *info,
296                                struct wsi_image *image,
297                                VkExternalMemoryHandleTypeFlags handle_types);
298 
299 VkResult
300 wsi_finish_create_blit_context(const struct wsi_swapchain *chain,
301                                const struct wsi_image_info *info,
302                                struct wsi_image *image);
303 
304 void
305 wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
306                            const VkSwapchainCreateInfoKHR *pCreateInfo,
307                            uint32_t stride_align, uint32_t size_align,
308                            struct wsi_image_info *info);
309 
310 void
311 wsi_configure_image_blit_image(UNUSED const struct wsi_swapchain *chain,
312                                struct wsi_image_info *info);
313 
314 VkResult
315 wsi_configure_image(const struct wsi_swapchain *chain,
316                     const VkSwapchainCreateInfoKHR *pCreateInfo,
317                     VkExternalMemoryHandleTypeFlags handle_types,
318                     struct wsi_image_info *info);
319 void
320 wsi_destroy_image_info(const struct wsi_swapchain *chain,
321                        struct wsi_image_info *info);
322 VkResult
323 wsi_create_image(const struct wsi_swapchain *chain,
324                  const struct wsi_image_info *info,
325                  struct wsi_image *image);
326 void
327 wsi_image_init(struct wsi_image *image);
328 
329 void
330 wsi_destroy_image(const struct wsi_swapchain *chain,
331                   struct wsi_image *image);
332 
333 VkResult
334 wsi_swapchain_wait_for_present_semaphore(const struct wsi_swapchain *chain,
335                                          uint64_t present_id, uint64_t timeout);
336 
337 #ifdef HAVE_LIBDRM
338 VkResult
339 wsi_prepare_signal_dma_buf_from_semaphore(struct wsi_swapchain *chain,
340                                           const struct wsi_image *image);
341 VkResult
342 wsi_signal_dma_buf_from_semaphore(const struct wsi_swapchain *chain,
343                                   const struct wsi_image *image);
344 VkResult
345 wsi_create_sync_for_dma_buf_wait(const struct wsi_swapchain *chain,
346                                  const struct wsi_image *image,
347                                  enum vk_sync_features sync_features,
348                                  struct vk_sync **sync_out);
349 VkResult
350 wsi_create_sync_for_image_syncobj(const struct wsi_swapchain *chain,
351                                   const struct wsi_image *image,
352                                   enum vk_sync_features req_features,
353                                   struct vk_sync **sync_out);
354 
355 VkResult
356 wsi_create_image_explicit_sync_drm(const struct wsi_swapchain *chain,
357                                    struct wsi_image *image);
358 
359 void
360 wsi_destroy_image_explicit_sync_drm(const struct wsi_swapchain *chain,
361                                     struct wsi_image *image);
362 
363 VkResult
364 wsi_drm_wait_for_explicit_sync_release(struct wsi_swapchain *chain,
365                                        uint32_t image_count,
366                                        struct wsi_image **images,
367                                        uint64_t rel_timeout_ns,
368                                        uint32_t *image_index);
369 #endif
370 
371 struct wsi_interface {
372    VkResult (*get_support)(VkIcdSurfaceBase *surface,
373                            struct wsi_device *wsi_device,
374                            uint32_t queueFamilyIndex,
375                            VkBool32* pSupported);
376    VkResult (*get_capabilities2)(VkIcdSurfaceBase *surface,
377                                  struct wsi_device *wsi_device,
378                                  const void *info_next,
379                                  VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
380    VkResult (*get_formats)(VkIcdSurfaceBase *surface,
381                            struct wsi_device *wsi_device,
382                            uint32_t* pSurfaceFormatCount,
383                            VkSurfaceFormatKHR* pSurfaceFormats);
384    VkResult (*get_formats2)(VkIcdSurfaceBase *surface,
385                             struct wsi_device *wsi_device,
386                             const void *info_next,
387                             uint32_t* pSurfaceFormatCount,
388                             VkSurfaceFormat2KHR* pSurfaceFormats);
389    VkResult (*get_present_modes)(VkIcdSurfaceBase *surface,
390                                  struct wsi_device *wsi_device,
391                                  uint32_t* pPresentModeCount,
392                                  VkPresentModeKHR* pPresentModes);
393    VkResult (*get_present_rectangles)(VkIcdSurfaceBase *surface,
394                                       struct wsi_device *wsi_device,
395                                       uint32_t* pRectCount,
396                                       VkRect2D* pRects);
397    VkResult (*create_swapchain)(VkIcdSurfaceBase *surface,
398                                 VkDevice device,
399                                 struct wsi_device *wsi_device,
400                                 const VkSwapchainCreateInfoKHR* pCreateInfo,
401                                 const VkAllocationCallbacks* pAllocator,
402                                 struct wsi_swapchain **swapchain);
403 };
404 
405 VkResult wsi_x11_init_wsi(struct wsi_device *wsi_device,
406                           const VkAllocationCallbacks *alloc,
407                           const struct driOptionCache *dri_options);
408 void wsi_x11_finish_wsi(struct wsi_device *wsi_device,
409                         const VkAllocationCallbacks *alloc);
410 VkResult wsi_wl_init_wsi(struct wsi_device *wsi_device,
411                          const VkAllocationCallbacks *alloc,
412                          VkPhysicalDevice physical_device);
413 void wsi_wl_finish_wsi(struct wsi_device *wsi_device,
414                        const VkAllocationCallbacks *alloc);
415 VkResult wsi_win32_init_wsi(struct wsi_device *wsi_device,
416                          const VkAllocationCallbacks *alloc,
417                          VkPhysicalDevice physical_device);
418 void wsi_win32_finish_wsi(struct wsi_device *wsi_device,
419                        const VkAllocationCallbacks *alloc);
420 VkResult wsi_metal_init_wsi(struct wsi_device *wsi_device,
421                            const VkAllocationCallbacks *alloc,
422                            VkPhysicalDevice physical_device);
423 void wsi_metal_finish_wsi(struct wsi_device *wsi_device,
424                           const VkAllocationCallbacks *alloc);
425 
426 
427 VkResult
428 wsi_display_init_wsi(struct wsi_device *wsi_device,
429                      const VkAllocationCallbacks *alloc,
430                      int display_fd);
431 
432 void
433 wsi_display_finish_wsi(struct wsi_device *wsi_device,
434                        const VkAllocationCallbacks *alloc);
435 
436 void
437 wsi_display_setup_syncobj_fd(struct wsi_device *wsi_device,
438                              int fd);
439 
440 VkResult wsi_headless_init_wsi(struct wsi_device *wsi_device,
441                                const VkAllocationCallbacks *alloc,
442                                VkPhysicalDevice physical_device);
443 
444 void wsi_headless_finish_wsi(struct wsi_device *wsi_device,
445                              const VkAllocationCallbacks *alloc);
446 
447 VK_DEFINE_NONDISP_HANDLE_CASTS(wsi_swapchain, base, VkSwapchainKHR,
448                                VK_OBJECT_TYPE_SWAPCHAIN_KHR)
449 
450 #ifdef __cplusplus
451 }
452 #endif
453 
454 #endif /* WSI_COMMON_PRIVATE_H */
455