• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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