• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2020 Raspberry Pi
3  * based on intel anv code:
4  * Copyright © 2015 Intel Corporation
5 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23  * IN THE SOFTWARE.
24  */
25 
26 #include "v3dv_private.h"
27 #include "drm-uapi/drm_fourcc.h"
28 #include "vk_format_info.h"
29 #include "vk_util.h"
30 #include "wsi_common.h"
31 
32 static PFN_vkVoidFunction
v3dv_wsi_proc_addr(VkPhysicalDevice physicalDevice,const char * pName)33 v3dv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
34 {
35    V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice);
36    return v3dv_lookup_entrypoint(&physical_device->devinfo, pName);
37 }
38 
39 VkResult
v3dv_wsi_init(struct v3dv_physical_device * physical_device)40 v3dv_wsi_init(struct v3dv_physical_device *physical_device)
41 {
42    VkResult result;
43 
44    result = wsi_device_init(&physical_device->wsi_device,
45                             v3dv_physical_device_to_handle(physical_device),
46                             v3dv_wsi_proc_addr,
47                             &physical_device->instance->alloc,
48                             physical_device->display_fd, NULL, false);
49 
50    if (result != VK_SUCCESS)
51       return result;
52 
53    physical_device->wsi_device.supports_modifiers = true;
54 
55    return VK_SUCCESS;
56 }
57 
58 void
v3dv_wsi_finish(struct v3dv_physical_device * physical_device)59 v3dv_wsi_finish(struct v3dv_physical_device *physical_device)
60 {
61    wsi_device_finish(&physical_device->wsi_device,
62                      &physical_device->instance->alloc);
63 }
64 
v3dv_DestroySurfaceKHR(VkInstance _instance,VkSurfaceKHR _surface,const VkAllocationCallbacks * pAllocator)65 void v3dv_DestroySurfaceKHR(
66     VkInstance                                   _instance,
67     VkSurfaceKHR                                 _surface,
68     const VkAllocationCallbacks*                 pAllocator)
69 {
70    V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);
71    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
72 
73    if (!surface)
74       return;
75 
76    vk_free2(&instance->alloc, pAllocator, surface);
77 }
78 
v3dv_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,VkSurfaceKHR surface,VkBool32 * pSupported)79 VkResult v3dv_GetPhysicalDeviceSurfaceSupportKHR(
80     VkPhysicalDevice                            physicalDevice,
81     uint32_t                                    queueFamilyIndex,
82     VkSurfaceKHR                                surface,
83     VkBool32*                                   pSupported)
84 {
85    V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
86 
87    return wsi_common_get_surface_support(&device->wsi_device,
88                                          queueFamilyIndex,
89                                          surface,
90                                          pSupported);
91 }
92 
93 static void
contraint_surface_capabilities(VkSurfaceCapabilitiesKHR * caps)94 contraint_surface_capabilities(VkSurfaceCapabilitiesKHR *caps)
95 {
96    /* Our display pipeline requires that images are linear, so we cannot
97     * ensure that our swapchain images can be sampled. If we are running under
98     * a compositor in windowed mode, the DRM modifier negotiation should
99     * probably end up selecting an UIF layout for the swapchain images but it
100     * may still choose linear and send images directly for scanout if the
101     * surface is in fullscreen mode for example. If we are not running under
102     * a compositor, then we would always need them to be linear anyway.
103     */
104    caps->supportedUsageFlags &= ~VK_IMAGE_USAGE_SAMPLED_BIT;
105 }
106 
v3dv_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities)107 VkResult v3dv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
108     VkPhysicalDevice                            physicalDevice,
109     VkSurfaceKHR                                surface,
110     VkSurfaceCapabilitiesKHR*                   pSurfaceCapabilities)
111 {
112    V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
113 
114    VkResult result;
115    result = wsi_common_get_surface_capabilities(&device->wsi_device,
116                                                 surface,
117                                                 pSurfaceCapabilities);
118    contraint_surface_capabilities(pSurfaceCapabilities);
119    return result;
120 }
121 
v3dv_GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)122 VkResult v3dv_GetPhysicalDeviceSurfaceCapabilities2KHR(
123     VkPhysicalDevice                            physicalDevice,
124     const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
125     VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities)
126 {
127    V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
128 
129    VkResult result;
130    result = wsi_common_get_surface_capabilities2(&device->wsi_device,
131                                                  pSurfaceInfo,
132                                                  pSurfaceCapabilities);
133    contraint_surface_capabilities(&pSurfaceCapabilities->surfaceCapabilities);
134    return result;
135 }
136 
v3dv_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats)137 VkResult v3dv_GetPhysicalDeviceSurfaceFormatsKHR(
138     VkPhysicalDevice                            physicalDevice,
139     VkSurfaceKHR                                surface,
140     uint32_t*                                   pSurfaceFormatCount,
141     VkSurfaceFormatKHR*                         pSurfaceFormats)
142 {
143    V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
144 
145    return wsi_common_get_surface_formats(&device->wsi_device, surface,
146                                          pSurfaceFormatCount, pSurfaceFormats);
147 }
148 
v3dv_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)149 VkResult v3dv_GetPhysicalDeviceSurfaceFormats2KHR(
150     VkPhysicalDevice                            physicalDevice,
151     const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
152     uint32_t*                                   pSurfaceFormatCount,
153     VkSurfaceFormat2KHR*                        pSurfaceFormats)
154 {
155    V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
156 
157    return wsi_common_get_surface_formats2(&device->wsi_device, pSurfaceInfo,
158                                           pSurfaceFormatCount, pSurfaceFormats);
159 }
160 
v3dv_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes)161 VkResult v3dv_GetPhysicalDeviceSurfacePresentModesKHR(
162     VkPhysicalDevice                            physicalDevice,
163     VkSurfaceKHR                                surface,
164     uint32_t*                                   pPresentModeCount,
165     VkPresentModeKHR*                           pPresentModes)
166 {
167    V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
168 
169    return wsi_common_get_surface_present_modes(&device->wsi_device, surface,
170                                                pPresentModeCount,
171                                                pPresentModes);
172 }
173 
v3dv_CreateSwapchainKHR(VkDevice _device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)174 VkResult v3dv_CreateSwapchainKHR(
175     VkDevice                                     _device,
176     const VkSwapchainCreateInfoKHR*              pCreateInfo,
177     const VkAllocationCallbacks*                 pAllocator,
178     VkSwapchainKHR*                              pSwapchain)
179 {
180    V3DV_FROM_HANDLE(v3dv_device, device, _device);
181    struct wsi_device *wsi_device = &device->instance->physicalDevice.wsi_device;
182    const VkAllocationCallbacks *alloc;
183 
184    if (pAllocator)
185      alloc = pAllocator;
186    else
187      alloc = &device->alloc;
188 
189    return wsi_common_create_swapchain(wsi_device, _device,
190                                       pCreateInfo, alloc, pSwapchain);
191 }
192 
v3dv_DestroySwapchainKHR(VkDevice _device,VkSwapchainKHR swapchain,const VkAllocationCallbacks * pAllocator)193 void v3dv_DestroySwapchainKHR(
194     VkDevice                                     _device,
195     VkSwapchainKHR                               swapchain,
196     const VkAllocationCallbacks*                 pAllocator)
197 {
198    V3DV_FROM_HANDLE(v3dv_device, device, _device);
199    const VkAllocationCallbacks *alloc;
200 
201    if (pAllocator)
202      alloc = pAllocator;
203    else
204      alloc = &device->alloc;
205 
206    wsi_common_destroy_swapchain(_device, swapchain, alloc);
207 }
208 
v3dv_GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)209 VkResult v3dv_GetSwapchainImagesKHR(
210     VkDevice                                     device,
211     VkSwapchainKHR                               swapchain,
212     uint32_t*                                    pSwapchainImageCount,
213     VkImage*                                     pSwapchainImages)
214 {
215    return wsi_common_get_images(swapchain,
216                                 pSwapchainImageCount,
217                                 pSwapchainImages);
218 }
219 
v3dv_AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchain,uint64_t timeout,VkSemaphore semaphore,VkFence fence,uint32_t * pImageIndex)220 VkResult v3dv_AcquireNextImageKHR(
221     VkDevice                                     device,
222     VkSwapchainKHR                               swapchain,
223     uint64_t                                     timeout,
224     VkSemaphore                                  semaphore,
225     VkFence                                      fence,
226     uint32_t*                                    pImageIndex)
227 {
228    VkAcquireNextImageInfoKHR acquire_info = {
229       .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
230       .swapchain = swapchain,
231       .timeout = timeout,
232       .semaphore = semaphore,
233       .fence = fence,
234       .deviceMask = 0,
235    };
236 
237    return v3dv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);
238 }
239 
v3dv_AcquireNextImage2KHR(VkDevice _device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)240 VkResult v3dv_AcquireNextImage2KHR(
241     VkDevice                                     _device,
242     const VkAcquireNextImageInfoKHR*             pAcquireInfo,
243     uint32_t*                                    pImageIndex)
244 {
245    V3DV_FROM_HANDLE(v3dv_device, device, _device);
246    V3DV_FROM_HANDLE(v3dv_fence, fence, pAcquireInfo->fence);
247    V3DV_FROM_HANDLE(v3dv_semaphore, semaphore, pAcquireInfo->semaphore);
248 
249    struct v3dv_physical_device *pdevice = &device->instance->physicalDevice;
250 
251    VkResult result;
252    result = wsi_common_acquire_next_image2(&pdevice->wsi_device, _device,
253                                            pAcquireInfo, pImageIndex);
254 
255    if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) {
256       if (fence)
257          drmSyncobjSignal(device->render_fd, &fence->sync, 1);
258       if (semaphore)
259          drmSyncobjSignal(device->render_fd, &semaphore->sync, 1);
260    }
261 
262    return result;
263 }
264 
v3dv_QueuePresentKHR(VkQueue _queue,const VkPresentInfoKHR * pPresentInfo)265 VkResult v3dv_QueuePresentKHR(
266     VkQueue                                  _queue,
267     const VkPresentInfoKHR*                  pPresentInfo)
268 {
269    V3DV_FROM_HANDLE(v3dv_queue, queue, _queue);
270    struct v3dv_physical_device *pdevice =
271       &queue->device->instance->physicalDevice;
272 
273    return wsi_common_queue_present(&pdevice->wsi_device,
274                                    v3dv_device_to_handle(queue->device),
275                                    _queue, 0,
276                                    pPresentInfo);
277 }
278 
v3dv_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device,VkDeviceGroupPresentCapabilitiesKHR * pCapabilities)279 VkResult v3dv_GetDeviceGroupPresentCapabilitiesKHR(
280     VkDevice                                    device,
281     VkDeviceGroupPresentCapabilitiesKHR*        pCapabilities)
282 {
283    memset(pCapabilities->presentMask, 0,
284           sizeof(pCapabilities->presentMask));
285    pCapabilities->presentMask[0] = 0x1;
286    pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
287 
288    return VK_SUCCESS;
289 }
290 
v3dv_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,VkSurfaceKHR surface,VkDeviceGroupPresentModeFlagsKHR * pModes)291 VkResult v3dv_GetDeviceGroupSurfacePresentModesKHR(
292     VkDevice                                    device,
293     VkSurfaceKHR                                surface,
294     VkDeviceGroupPresentModeFlagsKHR*           pModes)
295 {
296    *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
297 
298    return VK_SUCCESS;
299 }
300 
v3dv_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)301 VkResult v3dv_GetPhysicalDevicePresentRectanglesKHR(
302     VkPhysicalDevice                            physicalDevice,
303     VkSurfaceKHR                                surface,
304     uint32_t*                                   pRectCount,
305     VkRect2D*                                   pRects)
306 {
307    V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
308 
309    return wsi_common_get_present_rectangles(&device->wsi_device,
310                                             surface,
311                                             pRectCount, pRects);
312 }
313