1/*
2 * Copyright © 2015 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_H
24#define WSI_COMMON_H
25
26#include <stdint.h>
27#include <stdbool.h>
28
29#include "vk_alloc.h"
30#include "vk_dispatch_table.h"
31#include <vulkan/vulkan.h>
32#include <vulkan/vk_icd.h>
33
34#ifndef WSI_ENTRYPOINTS_H
35extern const struct vk_instance_entrypoint_table wsi_instance_entrypoints;
36extern const struct vk_physical_device_entrypoint_table wsi_physical_device_entrypoints;
37extern const struct vk_device_entrypoint_table wsi_device_entrypoints;
38#endif
39
40/* This is guaranteed to not collide with anything because it's in the
41 * VK_KHR_swapchain namespace but not actually used by the extension.
42 */
43#define VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA (VkStructureType)1000001002
44#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA (VkStructureType)1000001003
45#define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA (VkStructureType)1000001005
46#define VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA (VkStructureType)1000001006
47
48/* This is always chained to VkImageCreateInfo when a wsi image is created.
49 * It indicates that the image can be transitioned to/from
50 * VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.
51 */
52struct wsi_image_create_info {
53    VkStructureType sType;
54    const void *pNext;
55    bool scanout;
56
57    /* if true, the image is a prime blit source */
58    bool prime_blit_src;
59};
60
61struct wsi_memory_allocate_info {
62    VkStructureType sType;
63    const void *pNext;
64    bool implicit_sync;
65};
66
67/* To be chained into VkSurfaceCapabilities2KHR */
68struct wsi_surface_supported_counters {
69   VkStructureType sType;
70   const void *pNext;
71
72   VkSurfaceCounterFlagsEXT supported_surface_counters;
73
74};
75
76/* To be chained into VkSubmitInfo */
77struct wsi_memory_signal_submit_info {
78    VkStructureType sType;
79    const void *pNext;
80    VkDeviceMemory memory;
81};
82
83struct wsi_fence {
84   VkDevice                     device;
85   const struct wsi_device      *wsi_device;
86   VkDisplayKHR                 display;
87   const VkAllocationCallbacks  *alloc;
88   VkResult                     (*wait)(struct wsi_fence *fence, uint64_t abs_timeout);
89   void                         (*destroy)(struct wsi_fence *fence);
90};
91
92struct wsi_interface;
93
94struct driOptionCache;
95
96#define VK_ICD_WSI_PLATFORM_MAX (VK_ICD_WSI_PLATFORM_DISPLAY + 1)
97
98struct wsi_device {
99   /* Allocator for the instance */
100   VkAllocationCallbacks instance_alloc;
101
102   VkPhysicalDevice pdevice;
103   VkPhysicalDeviceMemoryProperties memory_props;
104   uint32_t queue_family_count;
105
106   VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info;
107
108   bool supports_modifiers;
109   uint32_t maxImageDimension2D;
110   VkPresentModeKHR override_present_mode;
111   bool force_bgra8_unorm_first;
112
113   /* Whether to enable adaptive sync for a swapchain if implemented and
114    * available. Not all window systems might support this. */
115   bool enable_adaptive_sync;
116
117   struct {
118      /* Override the minimum number of images on the swapchain.
119       * 0 = no override */
120      uint32_t override_minImageCount;
121
122      /* Forces strict number of image on the swapchain using application
123       * provided VkSwapchainCreateInfoKH::RminImageCount.
124       */
125      bool strict_imageCount;
126
127      /* Ensures to create at least the number of image specified by the
128       * driver in VkSurfaceCapabilitiesKHR::minImageCount.
129       */
130      bool ensure_minImageCount;
131
132      /* Wait for fences before submitting buffers to Xwayland. Defaults to
133       * true.
134       */
135      bool xwaylandWaitReady;
136   } x11;
137
138   bool sw;
139
140   /* Signals the semaphore such that any wait on the semaphore will wait on
141    * any reads or writes on the give memory object.  This is used to
142    * implement the semaphore signal operation in vkAcquireNextImage.
143    */
144   void (*signal_semaphore_for_memory)(VkDevice device,
145                                       VkSemaphore semaphore,
146                                       VkDeviceMemory memory);
147
148   /* Signals the fence such that any wait on the fence will wait on any reads
149    * or writes on the give memory object.  This is used to implement the
150    * semaphore signal operation in vkAcquireNextImage.
151    */
152   void (*signal_fence_for_memory)(VkDevice device,
153                                   VkFence fence,
154                                   VkDeviceMemory memory);
155
156   /*
157    * This sets the ownership for a WSI memory object:
158    *
159    * The ownership is true if and only if the application is allowed to submit
160    * command buffers that reference the buffer.
161    *
162    * This can be used to prune BO lists without too many adverse affects on
163    * implicit sync.
164    *
165    * Side note: care needs to be taken for internally delayed submissions wrt
166    * timeline semaphores.
167    */
168   void (*set_memory_ownership)(VkDevice device,
169                                VkDeviceMemory memory,
170                                VkBool32 ownership);
171
172   /*
173    * If this is set, the WSI device will call it to let the driver backend
174    * decide if it can present images directly on the given device fd.
175    */
176   bool (*can_present_on_device)(VkPhysicalDevice pdevice, int fd);
177
178#define WSI_CB(cb) PFN_vk##cb cb
179   WSI_CB(AllocateMemory);
180   WSI_CB(AllocateCommandBuffers);
181   WSI_CB(BindBufferMemory);
182   WSI_CB(BindImageMemory);
183   WSI_CB(BeginCommandBuffer);
184   WSI_CB(CmdCopyImageToBuffer);
185   WSI_CB(CreateBuffer);
186   WSI_CB(CreateCommandPool);
187   WSI_CB(CreateFence);
188   WSI_CB(CreateImage);
189   WSI_CB(DestroyBuffer);
190   WSI_CB(DestroyCommandPool);
191   WSI_CB(DestroyFence);
192   WSI_CB(DestroyImage);
193   WSI_CB(EndCommandBuffer);
194   WSI_CB(FreeMemory);
195   WSI_CB(FreeCommandBuffers);
196   WSI_CB(GetBufferMemoryRequirements);
197   WSI_CB(GetImageDrmFormatModifierPropertiesEXT);
198   WSI_CB(GetImageMemoryRequirements);
199   WSI_CB(GetImageSubresourceLayout);
200   WSI_CB(GetMemoryFdKHR);
201   WSI_CB(GetPhysicalDeviceFormatProperties);
202   WSI_CB(GetPhysicalDeviceFormatProperties2KHR);
203   WSI_CB(GetPhysicalDeviceImageFormatProperties2);
204   WSI_CB(ResetFences);
205   WSI_CB(QueueSubmit);
206   WSI_CB(WaitForFences);
207   WSI_CB(MapMemory);
208   WSI_CB(UnmapMemory);
209#undef WSI_CB
210
211    struct wsi_interface *                  wsi[VK_ICD_WSI_PLATFORM_MAX];
212};
213
214typedef PFN_vkVoidFunction (VKAPI_PTR *WSI_FN_GetPhysicalDeviceProcAddr)(VkPhysicalDevice physicalDevice, const char* pName);
215
216VkResult
217wsi_device_init(struct wsi_device *wsi,
218                VkPhysicalDevice pdevice,
219                WSI_FN_GetPhysicalDeviceProcAddr proc_addr,
220                const VkAllocationCallbacks *alloc,
221                int display_fd,
222                const struct driOptionCache *dri_options,
223                bool sw_device);
224
225void
226wsi_device_finish(struct wsi_device *wsi,
227                  const VkAllocationCallbacks *alloc);
228
229#define ICD_DEFINE_NONDISP_HANDLE_CASTS(__VkIcdType, __VkType)             \
230                                                                           \
231   static inline __VkIcdType *                                             \
232   __VkIcdType ## _from_handle(__VkType _handle)                           \
233   {                                                                       \
234      return (__VkIcdType *)(uintptr_t) _handle;                           \
235   }                                                                       \
236                                                                           \
237   static inline __VkType                                                  \
238   __VkIcdType ## _to_handle(__VkIcdType *_obj)                            \
239   {                                                                       \
240      return (__VkType)(uintptr_t) _obj;                                   \
241   }
242
243#define ICD_FROM_HANDLE(__VkIcdType, __name, __handle) \
244   __VkIcdType *__name = __VkIcdType ## _from_handle(__handle)
245
246ICD_DEFINE_NONDISP_HANDLE_CASTS(VkIcdSurfaceBase, VkSurfaceKHR)
247
248VkResult
249wsi_common_get_images(VkSwapchainKHR _swapchain,
250                      uint32_t *pSwapchainImageCount,
251                      VkImage *pSwapchainImages);
252
253VkResult
254wsi_common_acquire_next_image2(const struct wsi_device *wsi,
255                               VkDevice device,
256                               const VkAcquireNextImageInfoKHR *pAcquireInfo,
257                               uint32_t *pImageIndex);
258
259VkResult
260wsi_common_queue_present(const struct wsi_device *wsi,
261                         VkDevice device_h,
262                         VkQueue queue_h,
263                         int queue_family_index,
264                         const VkPresentInfoKHR *pPresentInfo);
265
266uint64_t
267wsi_common_get_current_time(void);
268
269#endif
270