vulkan/wsi: move swapchain create/destroy to common code
[mesa.git] / src / intel / vulkan / anv_wsi.c
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
24 #include "anv_private.h"
25 #include "wsi_common.h"
26 #include "vk_format_info.h"
27 #include "vk_util.h"
28
29 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
30 #define WSI_CB(x) .x = anv_##x
31 static const struct wsi_callbacks wsi_cbs = {
32 WSI_CB(GetPhysicalDeviceFormatProperties),
33 };
34 #endif
35
36 static PFN_vkVoidFunction
37 anv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
38 {
39 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
40 return anv_lookup_entrypoint(&physical_device->info, pName);
41 }
42
43 static uint32_t
44 anv_wsi_queue_get_family_index(VkQueue queue)
45 {
46 return 0;
47 }
48
49 VkResult
50 anv_init_wsi(struct anv_physical_device *physical_device)
51 {
52 VkResult result;
53
54 wsi_device_init(&physical_device->wsi_device,
55 anv_physical_device_to_handle(physical_device),
56 anv_wsi_proc_addr);
57
58 physical_device->wsi_device.queue_get_family_index =
59 anv_wsi_queue_get_family_index;
60
61 #ifdef VK_USE_PLATFORM_XCB_KHR
62 result = wsi_x11_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
63 if (result != VK_SUCCESS)
64 return result;
65 #endif
66
67 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
68 result = wsi_wl_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc,
69 anv_physical_device_to_handle(physical_device),
70 &wsi_cbs);
71 if (result != VK_SUCCESS) {
72 #ifdef VK_USE_PLATFORM_XCB_KHR
73 wsi_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
74 #endif
75 return result;
76 }
77 #endif
78
79 return VK_SUCCESS;
80 }
81
82 void
83 anv_finish_wsi(struct anv_physical_device *physical_device)
84 {
85 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
86 wsi_wl_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
87 #endif
88 #ifdef VK_USE_PLATFORM_XCB_KHR
89 wsi_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
90 #endif
91 }
92
93 void anv_DestroySurfaceKHR(
94 VkInstance _instance,
95 VkSurfaceKHR _surface,
96 const VkAllocationCallbacks* pAllocator)
97 {
98 ANV_FROM_HANDLE(anv_instance, instance, _instance);
99 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
100
101 if (!surface)
102 return;
103
104 vk_free2(&instance->alloc, pAllocator, surface);
105 }
106
107 VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
108 VkPhysicalDevice physicalDevice,
109 uint32_t queueFamilyIndex,
110 VkSurfaceKHR _surface,
111 VkBool32* pSupported)
112 {
113 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
114 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
115 struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
116
117 return iface->get_support(surface, &device->wsi_device,
118 &device->instance->alloc,
119 queueFamilyIndex, device->local_fd, true, pSupported);
120 }
121
122 VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
123 VkPhysicalDevice physicalDevice,
124 VkSurfaceKHR _surface,
125 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
126 {
127 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
128 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
129 struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
130
131 return iface->get_capabilities(surface, pSurfaceCapabilities);
132 }
133
134 VkResult anv_GetPhysicalDeviceSurfaceCapabilities2KHR(
135 VkPhysicalDevice physicalDevice,
136 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
137 VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
138 {
139 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
140 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
141 struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
142
143 return iface->get_capabilities2(surface, pSurfaceInfo->pNext,
144 pSurfaceCapabilities);
145 }
146
147 VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
148 VkPhysicalDevice physicalDevice,
149 VkSurfaceKHR _surface,
150 uint32_t* pSurfaceFormatCount,
151 VkSurfaceFormatKHR* pSurfaceFormats)
152 {
153 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
154 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
155 struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
156
157 return iface->get_formats(surface, &device->wsi_device, pSurfaceFormatCount,
158 pSurfaceFormats);
159 }
160
161 VkResult anv_GetPhysicalDeviceSurfaceFormats2KHR(
162 VkPhysicalDevice physicalDevice,
163 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
164 uint32_t* pSurfaceFormatCount,
165 VkSurfaceFormat2KHR* pSurfaceFormats)
166 {
167 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
168 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
169 struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
170
171 return iface->get_formats2(surface, &device->wsi_device, pSurfaceInfo->pNext,
172 pSurfaceFormatCount, pSurfaceFormats);
173 }
174
175 VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
176 VkPhysicalDevice physicalDevice,
177 VkSurfaceKHR _surface,
178 uint32_t* pPresentModeCount,
179 VkPresentModeKHR* pPresentModes)
180 {
181 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
182 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
183 struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
184
185 return iface->get_present_modes(surface, pPresentModeCount,
186 pPresentModes);
187 }
188
189 VkResult anv_CreateSwapchainKHR(
190 VkDevice _device,
191 const VkSwapchainCreateInfoKHR* pCreateInfo,
192 const VkAllocationCallbacks* pAllocator,
193 VkSwapchainKHR* pSwapchain)
194 {
195 ANV_FROM_HANDLE(anv_device, device, _device);
196 struct wsi_device *wsi_device = &device->instance->physicalDevice.wsi_device;
197 const VkAllocationCallbacks *alloc;
198
199 if (pAllocator)
200 alloc = pAllocator;
201 else
202 alloc = &device->alloc;
203
204 return wsi_common_create_swapchain(wsi_device, _device, device->fd,
205 pCreateInfo, alloc, pSwapchain);
206 }
207
208 void anv_DestroySwapchainKHR(
209 VkDevice _device,
210 VkSwapchainKHR swapchain,
211 const VkAllocationCallbacks* pAllocator)
212 {
213 ANV_FROM_HANDLE(anv_device, device, _device);
214 const VkAllocationCallbacks *alloc;
215
216 if (pAllocator)
217 alloc = pAllocator;
218 else
219 alloc = &device->alloc;
220
221 wsi_common_destroy_swapchain(_device, swapchain, alloc);
222 }
223
224 VkResult anv_GetSwapchainImagesKHR(
225 VkDevice device,
226 VkSwapchainKHR swapchain,
227 uint32_t* pSwapchainImageCount,
228 VkImage* pSwapchainImages)
229 {
230 return wsi_common_get_images(swapchain,
231 pSwapchainImageCount,
232 pSwapchainImages);
233 }
234
235 VkResult anv_AcquireNextImageKHR(
236 VkDevice _device,
237 VkSwapchainKHR _swapchain,
238 uint64_t timeout,
239 VkSemaphore semaphore,
240 VkFence _fence,
241 uint32_t* pImageIndex)
242 {
243 ANV_FROM_HANDLE(anv_device, device, _device);
244 ANV_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
245 ANV_FROM_HANDLE(anv_fence, fence, _fence);
246
247 VkResult result = swapchain->acquire_next_image(swapchain, timeout,
248 semaphore, pImageIndex);
249
250 /* Thanks to implicit sync, the image is ready immediately. However, we
251 * should wait for the current GPU state to finish.
252 */
253 if (fence)
254 anv_QueueSubmit(anv_queue_to_handle(&device->queue), 0, NULL, _fence);
255
256 return result;
257 }
258
259 VkResult anv_QueuePresentKHR(
260 VkQueue _queue,
261 const VkPresentInfoKHR* pPresentInfo)
262 {
263 ANV_FROM_HANDLE(anv_queue, queue, _queue);
264 struct anv_physical_device *pdevice =
265 &queue->device->instance->physicalDevice;
266
267 return wsi_common_queue_present(&pdevice->wsi_device,
268 anv_device_to_handle(queue->device),
269 _queue, 0,
270 pPresentInfo);
271 }