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
anv_wsi_proc_addr(VkPhysicalDevice physicalDevice,const char * pName)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
anv_wsi_signal_semaphore_for_memory(VkDevice _device,VkSemaphore _semaphore,VkDeviceMemory _memory)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
anv_wsi_signal_fence_for_memory(VkDevice _device,VkFence _fence,VkDeviceMemory _memory)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
anv_init_wsi(struct anv_physical_device * physical_device)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 false);
90 if (result != VK_SUCCESS)
91 return result;
92
93 physical_device->wsi_device.supports_modifiers = true;
94 physical_device->wsi_device.signal_semaphore_for_memory =
95 anv_wsi_signal_semaphore_for_memory;
96 physical_device->wsi_device.signal_fence_for_memory =
97 anv_wsi_signal_fence_for_memory;
98
99 return VK_SUCCESS;
100 }
101
102 void
anv_finish_wsi(struct anv_physical_device * physical_device)103 anv_finish_wsi(struct anv_physical_device *physical_device)
104 {
105 wsi_device_finish(&physical_device->wsi_device,
106 &physical_device->instance->alloc);
107 }
108
anv_DestroySurfaceKHR(VkInstance _instance,VkSurfaceKHR _surface,const VkAllocationCallbacks * pAllocator)109 void anv_DestroySurfaceKHR(
110 VkInstance _instance,
111 VkSurfaceKHR _surface,
112 const VkAllocationCallbacks* pAllocator)
113 {
114 ANV_FROM_HANDLE(anv_instance, instance, _instance);
115 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
116
117 if (!surface)
118 return;
119
120 vk_free2(&instance->alloc, pAllocator, surface);
121 }
122
anv_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,VkSurfaceKHR surface,VkBool32 * pSupported)123 VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
124 VkPhysicalDevice physicalDevice,
125 uint32_t queueFamilyIndex,
126 VkSurfaceKHR surface,
127 VkBool32* pSupported)
128 {
129 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
130
131 return wsi_common_get_surface_support(&device->wsi_device,
132 queueFamilyIndex,
133 surface,
134 pSupported);
135 }
136
anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities)137 VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
138 VkPhysicalDevice physicalDevice,
139 VkSurfaceKHR surface,
140 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
141 {
142 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
143
144 return wsi_common_get_surface_capabilities(&device->wsi_device,
145 surface,
146 pSurfaceCapabilities);
147 }
148
anv_GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)149 VkResult anv_GetPhysicalDeviceSurfaceCapabilities2KHR(
150 VkPhysicalDevice physicalDevice,
151 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
152 VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
153 {
154 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
155
156 return wsi_common_get_surface_capabilities2(&device->wsi_device,
157 pSurfaceInfo,
158 pSurfaceCapabilities);
159 }
160
anv_GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilities2EXT * pSurfaceCapabilities)161 VkResult anv_GetPhysicalDeviceSurfaceCapabilities2EXT(
162 VkPhysicalDevice physicalDevice,
163 VkSurfaceKHR surface,
164 VkSurfaceCapabilities2EXT* pSurfaceCapabilities)
165 {
166 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
167
168 return wsi_common_get_surface_capabilities2ext(&device->wsi_device,
169 surface,
170 pSurfaceCapabilities);
171 }
172
anv_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats)173 VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
174 VkPhysicalDevice physicalDevice,
175 VkSurfaceKHR surface,
176 uint32_t* pSurfaceFormatCount,
177 VkSurfaceFormatKHR* pSurfaceFormats)
178 {
179 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
180
181 return wsi_common_get_surface_formats(&device->wsi_device, surface,
182 pSurfaceFormatCount, pSurfaceFormats);
183 }
184
anv_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)185 VkResult anv_GetPhysicalDeviceSurfaceFormats2KHR(
186 VkPhysicalDevice physicalDevice,
187 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
188 uint32_t* pSurfaceFormatCount,
189 VkSurfaceFormat2KHR* pSurfaceFormats)
190 {
191 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
192
193 return wsi_common_get_surface_formats2(&device->wsi_device, pSurfaceInfo,
194 pSurfaceFormatCount, pSurfaceFormats);
195 }
196
anv_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes)197 VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
198 VkPhysicalDevice physicalDevice,
199 VkSurfaceKHR surface,
200 uint32_t* pPresentModeCount,
201 VkPresentModeKHR* pPresentModes)
202 {
203 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
204
205 return wsi_common_get_surface_present_modes(&device->wsi_device, surface,
206 pPresentModeCount,
207 pPresentModes);
208 }
209
anv_CreateSwapchainKHR(VkDevice _device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)210 VkResult anv_CreateSwapchainKHR(
211 VkDevice _device,
212 const VkSwapchainCreateInfoKHR* pCreateInfo,
213 const VkAllocationCallbacks* pAllocator,
214 VkSwapchainKHR* pSwapchain)
215 {
216 ANV_FROM_HANDLE(anv_device, device, _device);
217 struct wsi_device *wsi_device = &device->physical->wsi_device;
218 const VkAllocationCallbacks *alloc;
219
220 if (pAllocator)
221 alloc = pAllocator;
222 else
223 alloc = &device->vk.alloc;
224
225 return wsi_common_create_swapchain(wsi_device, _device,
226 pCreateInfo, alloc, pSwapchain);
227 }
228
anv_DestroySwapchainKHR(VkDevice _device,VkSwapchainKHR swapchain,const VkAllocationCallbacks * pAllocator)229 void anv_DestroySwapchainKHR(
230 VkDevice _device,
231 VkSwapchainKHR swapchain,
232 const VkAllocationCallbacks* pAllocator)
233 {
234 ANV_FROM_HANDLE(anv_device, device, _device);
235 const VkAllocationCallbacks *alloc;
236
237 if (pAllocator)
238 alloc = pAllocator;
239 else
240 alloc = &device->vk.alloc;
241
242 wsi_common_destroy_swapchain(_device, swapchain, alloc);
243 }
244
anv_GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)245 VkResult anv_GetSwapchainImagesKHR(
246 VkDevice device,
247 VkSwapchainKHR swapchain,
248 uint32_t* pSwapchainImageCount,
249 VkImage* pSwapchainImages)
250 {
251 return wsi_common_get_images(swapchain,
252 pSwapchainImageCount,
253 pSwapchainImages);
254 }
255
anv_AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchain,uint64_t timeout,VkSemaphore semaphore,VkFence fence,uint32_t * pImageIndex)256 VkResult anv_AcquireNextImageKHR(
257 VkDevice device,
258 VkSwapchainKHR swapchain,
259 uint64_t timeout,
260 VkSemaphore semaphore,
261 VkFence fence,
262 uint32_t* pImageIndex)
263 {
264 VkAcquireNextImageInfoKHR acquire_info = {
265 .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
266 .swapchain = swapchain,
267 .timeout = timeout,
268 .semaphore = semaphore,
269 .fence = fence,
270 .deviceMask = 0,
271 };
272
273 return anv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);
274 }
275
anv_AcquireNextImage2KHR(VkDevice _device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)276 VkResult anv_AcquireNextImage2KHR(
277 VkDevice _device,
278 const VkAcquireNextImageInfoKHR* pAcquireInfo,
279 uint32_t* pImageIndex)
280 {
281 ANV_FROM_HANDLE(anv_device, device, _device);
282
283 return wsi_common_acquire_next_image2(&device->physical->wsi_device,
284 _device, pAcquireInfo, pImageIndex);
285 }
286
anv_QueuePresentKHR(VkQueue _queue,const VkPresentInfoKHR * pPresentInfo)287 VkResult anv_QueuePresentKHR(
288 VkQueue _queue,
289 const VkPresentInfoKHR* pPresentInfo)
290 {
291 ANV_FROM_HANDLE(anv_queue, queue, _queue);
292 struct anv_device *device = queue->device;
293
294 if (device->debug_frame_desc) {
295 device->debug_frame_desc->frame_id++;
296 if (!device->info.has_llc) {
297 gen_clflush_range(device->debug_frame_desc,
298 sizeof(*device->debug_frame_desc));
299 }
300 }
301
302 if (device->has_thread_submit &&
303 pPresentInfo->waitSemaphoreCount > 0) {
304 /* Make sure all of the dependency semaphores have materialized when
305 * using a threaded submission.
306 */
307 uint32_t *syncobjs = vk_alloc(&device->vk.alloc,
308 sizeof(*syncobjs) * pPresentInfo->waitSemaphoreCount, 8,
309 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
310
311 if (!syncobjs)
312 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
313
314 uint32_t wait_count = 0;
315 for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; i++) {
316 ANV_FROM_HANDLE(anv_semaphore, semaphore, pPresentInfo->pWaitSemaphores[i]);
317 struct anv_semaphore_impl *impl =
318 semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ?
319 &semaphore->temporary : &semaphore->permanent;
320
321 if (impl->type == ANV_SEMAPHORE_TYPE_DUMMY)
322 continue;
323 assert(impl->type == ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ);
324 syncobjs[wait_count++] = impl->syncobj;
325 }
326
327 int ret = 0;
328 if (wait_count > 0) {
329 ret =
330 anv_gem_syncobj_wait(device, syncobjs, wait_count,
331 anv_get_absolute_timeout(INT64_MAX),
332 true /* wait_all */);
333 }
334
335 vk_free(&device->vk.alloc, syncobjs);
336
337 if (ret)
338 return vk_error(VK_ERROR_DEVICE_LOST);
339 }
340
341 VkResult result = wsi_common_queue_present(&device->physical->wsi_device,
342 anv_device_to_handle(queue->device),
343 _queue, 0,
344 pPresentInfo);
345
346 for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; i++) {
347 ANV_FROM_HANDLE(anv_semaphore, semaphore, pPresentInfo->pWaitSemaphores[i]);
348 /* From the Vulkan 1.0.53 spec:
349 *
350 * "If the import is temporary, the implementation must restore the
351 * semaphore to its prior permanent state after submitting the next
352 * semaphore wait operation."
353 */
354 anv_semaphore_reset_temporary(queue->device, semaphore);
355 }
356
357 return result;
358 }
359
anv_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device,VkDeviceGroupPresentCapabilitiesKHR * pCapabilities)360 VkResult anv_GetDeviceGroupPresentCapabilitiesKHR(
361 VkDevice device,
362 VkDeviceGroupPresentCapabilitiesKHR* pCapabilities)
363 {
364 memset(pCapabilities->presentMask, 0,
365 sizeof(pCapabilities->presentMask));
366 pCapabilities->presentMask[0] = 0x1;
367 pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
368
369 return VK_SUCCESS;
370 }
371
anv_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,VkSurfaceKHR surface,VkDeviceGroupPresentModeFlagsKHR * pModes)372 VkResult anv_GetDeviceGroupSurfacePresentModesKHR(
373 VkDevice device,
374 VkSurfaceKHR surface,
375 VkDeviceGroupPresentModeFlagsKHR* pModes)
376 {
377 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
378
379 return VK_SUCCESS;
380 }
381
anv_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)382 VkResult anv_GetPhysicalDevicePresentRectanglesKHR(
383 VkPhysicalDevice physicalDevice,
384 VkSurfaceKHR surface,
385 uint32_t* pRectCount,
386 VkRect2D* pRects)
387 {
388 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
389
390 return wsi_common_get_present_rectangles(&device->wsi_device,
391 surface,
392 pRectCount, pRects);
393 }
394