888a91d862033b8b7bcb42aaea27d75cec9bffdb
[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 void
37 anv_wsi_signal_semaphore_for_memory(VkDevice _device,
38 VkSemaphore _semaphore,
39 VkDeviceMemory _memory)
40 {
41 ANV_FROM_HANDLE(anv_device, device, _device);
42 ANV_FROM_HANDLE(anv_semaphore, semaphore, _semaphore);
43 ANV_FROM_HANDLE(anv_device_memory, memory, _memory);
44
45 /* Put a BO semaphore with the image BO in the temporary. For BO binary
46 * semaphores, we always set EXEC_OBJECT_WRITE so this creates a WaR
47 * hazard with the display engine's read to ensure that no one writes to
48 * the image before the read is complete.
49 */
50 anv_semaphore_reset_temporary(device, semaphore);
51
52 struct anv_semaphore_impl *impl = &semaphore->temporary;
53 impl->type = ANV_SEMAPHORE_TYPE_WSI_BO;
54 impl->bo = anv_bo_ref(memory->bo);
55 }
56
57 static void
58 anv_wsi_signal_fence_for_memory(VkDevice _device,
59 VkFence _fence,
60 VkDeviceMemory _memory)
61 {
62 ANV_FROM_HANDLE(anv_device, device, _device);
63 ANV_FROM_HANDLE(anv_fence, fence, _fence);
64 ANV_FROM_HANDLE(anv_device_memory, memory, _memory);
65
66 /* Put a BO fence with the image BO in the temporary. For BO fences, we
67 * always just wait until the BO isn't busy and reads from the BO should
68 * count as busy.
69 */
70 anv_fence_reset_temporary(device, fence);
71
72 struct anv_fence_impl *impl = &fence->temporary;
73 impl->type = ANV_FENCE_TYPE_WSI_BO;
74 impl->bo.bo = anv_bo_ref(memory->bo);
75 impl->bo.state = ANV_BO_FENCE_STATE_SUBMITTED;
76 }
77
78 VkResult
79 anv_init_wsi(struct anv_physical_device *physical_device)
80 {
81 VkResult result;
82
83 result = wsi_device_init(&physical_device->wsi_device,
84 anv_physical_device_to_handle(physical_device),
85 anv_wsi_proc_addr,
86 &physical_device->instance->alloc,
87 physical_device->master_fd,
88 &physical_device->instance->dri_options);
89 if (result != VK_SUCCESS)
90 return result;
91
92 physical_device->wsi_device.supports_modifiers = true;
93 physical_device->wsi_device.signal_semaphore_for_memory =
94 anv_wsi_signal_semaphore_for_memory;
95 physical_device->wsi_device.signal_fence_for_memory =
96 anv_wsi_signal_fence_for_memory;
97
98 return VK_SUCCESS;
99 }
100
101 void
102 anv_finish_wsi(struct anv_physical_device *physical_device)
103 {
104 wsi_device_finish(&physical_device->wsi_device,
105 &physical_device->instance->alloc);
106 }
107
108 void anv_DestroySurfaceKHR(
109 VkInstance _instance,
110 VkSurfaceKHR _surface,
111 const VkAllocationCallbacks* pAllocator)
112 {
113 ANV_FROM_HANDLE(anv_instance, instance, _instance);
114 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
115
116 if (!surface)
117 return;
118
119 vk_free2(&instance->alloc, pAllocator, surface);
120 }
121
122 VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
123 VkPhysicalDevice physicalDevice,
124 uint32_t queueFamilyIndex,
125 VkSurfaceKHR surface,
126 VkBool32* pSupported)
127 {
128 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
129
130 return wsi_common_get_surface_support(&device->wsi_device,
131 queueFamilyIndex,
132 surface,
133 pSupported);
134 }
135
136 VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
137 VkPhysicalDevice physicalDevice,
138 VkSurfaceKHR surface,
139 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
140 {
141 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
142
143 return wsi_common_get_surface_capabilities(&device->wsi_device,
144 surface,
145 pSurfaceCapabilities);
146 }
147
148 VkResult anv_GetPhysicalDeviceSurfaceCapabilities2KHR(
149 VkPhysicalDevice physicalDevice,
150 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
151 VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
152 {
153 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
154
155 return wsi_common_get_surface_capabilities2(&device->wsi_device,
156 pSurfaceInfo,
157 pSurfaceCapabilities);
158 }
159
160 VkResult anv_GetPhysicalDeviceSurfaceCapabilities2EXT(
161 VkPhysicalDevice physicalDevice,
162 VkSurfaceKHR surface,
163 VkSurfaceCapabilities2EXT* pSurfaceCapabilities)
164 {
165 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
166
167 return wsi_common_get_surface_capabilities2ext(&device->wsi_device,
168 surface,
169 pSurfaceCapabilities);
170 }
171
172 VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
173 VkPhysicalDevice physicalDevice,
174 VkSurfaceKHR surface,
175 uint32_t* pSurfaceFormatCount,
176 VkSurfaceFormatKHR* pSurfaceFormats)
177 {
178 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
179
180 return wsi_common_get_surface_formats(&device->wsi_device, surface,
181 pSurfaceFormatCount, pSurfaceFormats);
182 }
183
184 VkResult anv_GetPhysicalDeviceSurfaceFormats2KHR(
185 VkPhysicalDevice physicalDevice,
186 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
187 uint32_t* pSurfaceFormatCount,
188 VkSurfaceFormat2KHR* pSurfaceFormats)
189 {
190 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
191
192 return wsi_common_get_surface_formats2(&device->wsi_device, pSurfaceInfo,
193 pSurfaceFormatCount, pSurfaceFormats);
194 }
195
196 VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
197 VkPhysicalDevice physicalDevice,
198 VkSurfaceKHR surface,
199 uint32_t* pPresentModeCount,
200 VkPresentModeKHR* pPresentModes)
201 {
202 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
203
204 return wsi_common_get_surface_present_modes(&device->wsi_device, surface,
205 pPresentModeCount,
206 pPresentModes);
207 }
208
209 VkResult anv_CreateSwapchainKHR(
210 VkDevice _device,
211 const VkSwapchainCreateInfoKHR* pCreateInfo,
212 const VkAllocationCallbacks* pAllocator,
213 VkSwapchainKHR* pSwapchain)
214 {
215 ANV_FROM_HANDLE(anv_device, device, _device);
216 struct wsi_device *wsi_device = &device->physical->wsi_device;
217 const VkAllocationCallbacks *alloc;
218
219 if (pAllocator)
220 alloc = pAllocator;
221 else
222 alloc = &device->vk.alloc;
223
224 return wsi_common_create_swapchain(wsi_device, _device,
225 pCreateInfo, alloc, pSwapchain);
226 }
227
228 void anv_DestroySwapchainKHR(
229 VkDevice _device,
230 VkSwapchainKHR swapchain,
231 const VkAllocationCallbacks* pAllocator)
232 {
233 ANV_FROM_HANDLE(anv_device, device, _device);
234 const VkAllocationCallbacks *alloc;
235
236 if (pAllocator)
237 alloc = pAllocator;
238 else
239 alloc = &device->vk.alloc;
240
241 wsi_common_destroy_swapchain(_device, swapchain, alloc);
242 }
243
244 VkResult anv_GetSwapchainImagesKHR(
245 VkDevice device,
246 VkSwapchainKHR swapchain,
247 uint32_t* pSwapchainImageCount,
248 VkImage* pSwapchainImages)
249 {
250 return wsi_common_get_images(swapchain,
251 pSwapchainImageCount,
252 pSwapchainImages);
253 }
254
255 VkResult anv_AcquireNextImageKHR(
256 VkDevice device,
257 VkSwapchainKHR swapchain,
258 uint64_t timeout,
259 VkSemaphore semaphore,
260 VkFence fence,
261 uint32_t* pImageIndex)
262 {
263 VkAcquireNextImageInfoKHR acquire_info = {
264 .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
265 .swapchain = swapchain,
266 .timeout = timeout,
267 .semaphore = semaphore,
268 .fence = fence,
269 .deviceMask = 0,
270 };
271
272 return anv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);
273 }
274
275 VkResult anv_AcquireNextImage2KHR(
276 VkDevice _device,
277 const VkAcquireNextImageInfoKHR* pAcquireInfo,
278 uint32_t* pImageIndex)
279 {
280 ANV_FROM_HANDLE(anv_device, device, _device);
281
282 return wsi_common_acquire_next_image2(&device->physical->wsi_device,
283 _device, pAcquireInfo, pImageIndex);
284 }
285
286 VkResult anv_QueuePresentKHR(
287 VkQueue _queue,
288 const VkPresentInfoKHR* pPresentInfo)
289 {
290 ANV_FROM_HANDLE(anv_queue, queue, _queue);
291 struct anv_device *device = queue->device;
292
293 if (device->debug_frame_desc) {
294 device->debug_frame_desc->frame_id++;
295 if (!device->info.has_llc) {
296 gen_clflush_range(device->debug_frame_desc,
297 sizeof(*device->debug_frame_desc));
298 }
299 }
300
301 return wsi_common_queue_present(&queue->device->physical->wsi_device,
302 anv_device_to_handle(queue->device),
303 _queue, 0,
304 pPresentInfo);
305 }
306
307 VkResult anv_GetDeviceGroupPresentCapabilitiesKHR(
308 VkDevice device,
309 VkDeviceGroupPresentCapabilitiesKHR* pCapabilities)
310 {
311 memset(pCapabilities->presentMask, 0,
312 sizeof(pCapabilities->presentMask));
313 pCapabilities->presentMask[0] = 0x1;
314 pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
315
316 return VK_SUCCESS;
317 }
318
319 VkResult anv_GetDeviceGroupSurfacePresentModesKHR(
320 VkDevice device,
321 VkSurfaceKHR surface,
322 VkDeviceGroupPresentModeFlagsKHR* pModes)
323 {
324 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
325
326 return VK_SUCCESS;
327 }
328
329 VkResult anv_GetPhysicalDevicePresentRectanglesKHR(
330 VkPhysicalDevice physicalDevice,
331 VkSurfaceKHR surface,
332 uint32_t* pRectCount,
333 VkRect2D* pRects)
334 {
335 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
336
337 return wsi_common_get_present_rectangles(&device->wsi_device,
338 surface,
339 pRectCount, pRects);
340 }