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    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
anv_finish_wsi(struct anv_physical_device * physical_device)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 
anv_DestroySurfaceKHR(VkInstance _instance,VkSurfaceKHR _surface,const VkAllocationCallbacks * pAllocator)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 
anv_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,VkSurfaceKHR surface,VkBool32 * pSupported)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 
anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities)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 
anv_GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)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 
anv_GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilities2EXT * pSurfaceCapabilities)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 
anv_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats)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 
anv_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)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 
anv_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes)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 
anv_CreateSwapchainKHR(VkDevice _device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)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 
anv_DestroySwapchainKHR(VkDevice _device,VkSwapchainKHR swapchain,const VkAllocationCallbacks * pAllocator)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 
anv_GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)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 
anv_AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchain,uint64_t timeout,VkSemaphore semaphore,VkFence fence,uint32_t * pImageIndex)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 
anv_AcquireNextImage2KHR(VkDevice _device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)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 
anv_QueuePresentKHR(VkQueue _queue,const VkPresentInfoKHR * pPresentInfo)286 VkResult anv_QueuePresentKHR(
287     VkQueue                                  _queue,
288     const VkPresentInfoKHR*                  pPresentInfo)
289 {
290    ANV_FROM_HANDLE(anv_queue, queue, _queue);
291 
292    return wsi_common_queue_present(&queue->device->physical->wsi_device,
293                                    anv_device_to_handle(queue->device),
294                                    _queue, 0,
295                                    pPresentInfo);
296 }
297 
anv_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device,VkDeviceGroupPresentCapabilitiesKHR * pCapabilities)298 VkResult anv_GetDeviceGroupPresentCapabilitiesKHR(
299     VkDevice                                    device,
300     VkDeviceGroupPresentCapabilitiesKHR*        pCapabilities)
301 {
302    memset(pCapabilities->presentMask, 0,
303           sizeof(pCapabilities->presentMask));
304    pCapabilities->presentMask[0] = 0x1;
305    pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
306 
307    return VK_SUCCESS;
308 }
309 
anv_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,VkSurfaceKHR surface,VkDeviceGroupPresentModeFlagsKHR * pModes)310 VkResult anv_GetDeviceGroupSurfacePresentModesKHR(
311     VkDevice                                    device,
312     VkSurfaceKHR                                surface,
313     VkDeviceGroupPresentModeFlagsKHR*           pModes)
314 {
315    *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
316 
317    return VK_SUCCESS;
318 }
319 
anv_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)320 VkResult anv_GetPhysicalDevicePresentRectanglesKHR(
321     VkPhysicalDevice                            physicalDevice,
322     VkSurfaceKHR                                surface,
323     uint32_t*                                   pRectCount,
324     VkRect2D*                                   pRects)
325 {
326    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
327 
328    return wsi_common_get_present_rectangles(&device->wsi_device,
329                                             surface,
330                                             pRectCount, pRects);
331 }
332