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