1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2020 Raspberry Pi Ltd
3bf215546Sopenharmony_ci * based on intel anv code:
4bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation
5bf215546Sopenharmony_ci
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
12bf215546Sopenharmony_ci *
13bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
14bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
15bf215546Sopenharmony_ci * Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23bf215546Sopenharmony_ci * IN THE SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "v3dv_private.h"
27bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h"
28bf215546Sopenharmony_ci#include "wsi_common_entrypoints.h"
29bf215546Sopenharmony_ci#include "vk_util.h"
30bf215546Sopenharmony_ci#include "wsi_common.h"
31bf215546Sopenharmony_ci#include "wsi_common_drm.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_cistatic VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
34bf215546Sopenharmony_civ3dv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
35bf215546Sopenharmony_ci{
36bf215546Sopenharmony_ci   V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
37bf215546Sopenharmony_ci   return vk_instance_get_proc_addr_unchecked(pdevice->vk.instance, pName);
38bf215546Sopenharmony_ci}
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_cistatic bool
41bf215546Sopenharmony_civ3dv_wsi_can_present_on_device(VkPhysicalDevice _pdevice, int fd)
42bf215546Sopenharmony_ci{
43bf215546Sopenharmony_ci   V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, _pdevice);
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci   return wsi_common_drm_devices_equal(fd, pdevice->display_fd);
46bf215546Sopenharmony_ci}
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ciVkResult
49bf215546Sopenharmony_civ3dv_wsi_init(struct v3dv_physical_device *physical_device)
50bf215546Sopenharmony_ci{
51bf215546Sopenharmony_ci   VkResult result;
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci   result = wsi_device_init(&physical_device->wsi_device,
54bf215546Sopenharmony_ci                            v3dv_physical_device_to_handle(physical_device),
55bf215546Sopenharmony_ci                            v3dv_wsi_proc_addr,
56bf215546Sopenharmony_ci                            &physical_device->vk.instance->alloc,
57bf215546Sopenharmony_ci                            physical_device->master_fd, NULL, false);
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
60bf215546Sopenharmony_ci      return result;
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci   physical_device->wsi_device.supports_modifiers = true;
63bf215546Sopenharmony_ci   physical_device->wsi_device.can_present_on_device =
64bf215546Sopenharmony_ci      v3dv_wsi_can_present_on_device;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   physical_device->vk.wsi_device = &physical_device->wsi_device;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   return VK_SUCCESS;
69bf215546Sopenharmony_ci}
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_civoid
72bf215546Sopenharmony_civ3dv_wsi_finish(struct v3dv_physical_device *physical_device)
73bf215546Sopenharmony_ci{
74bf215546Sopenharmony_ci   physical_device->vk.wsi_device = NULL;
75bf215546Sopenharmony_ci   wsi_device_finish(&physical_device->wsi_device,
76bf215546Sopenharmony_ci                     &physical_device->vk.instance->alloc);
77bf215546Sopenharmony_ci}
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_cistatic void
80bf215546Sopenharmony_ciconstraint_surface_capabilities(VkSurfaceCapabilitiesKHR *caps)
81bf215546Sopenharmony_ci{
82bf215546Sopenharmony_ci   /* Our display pipeline requires that images are linear, so we cannot
83bf215546Sopenharmony_ci    * ensure that our swapchain images can be sampled. If we are running under
84bf215546Sopenharmony_ci    * a compositor in windowed mode, the DRM modifier negotiation should
85bf215546Sopenharmony_ci    * probably end up selecting an UIF layout for the swapchain images but it
86bf215546Sopenharmony_ci    * may still choose linear and send images directly for scanout if the
87bf215546Sopenharmony_ci    * surface is in fullscreen mode for example. If we are not running under
88bf215546Sopenharmony_ci    * a compositor, then we would always need them to be linear anyway.
89bf215546Sopenharmony_ci    */
90bf215546Sopenharmony_ci   caps->supportedUsageFlags &= ~VK_IMAGE_USAGE_SAMPLED_BIT;
91bf215546Sopenharmony_ci}
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
94bf215546Sopenharmony_civ3dv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
95bf215546Sopenharmony_ci    VkPhysicalDevice                            physicalDevice,
96bf215546Sopenharmony_ci    VkSurfaceKHR                                surface,
97bf215546Sopenharmony_ci    VkSurfaceCapabilitiesKHR*                   pSurfaceCapabilities)
98bf215546Sopenharmony_ci{
99bf215546Sopenharmony_ci   VkResult result;
100bf215546Sopenharmony_ci   result = wsi_GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice,
101bf215546Sopenharmony_ci                                                        surface,
102bf215546Sopenharmony_ci                                                        pSurfaceCapabilities);
103bf215546Sopenharmony_ci   constraint_surface_capabilities(pSurfaceCapabilities);
104bf215546Sopenharmony_ci   return result;
105bf215546Sopenharmony_ci}
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
108bf215546Sopenharmony_civ3dv_GetPhysicalDeviceSurfaceCapabilities2KHR(
109bf215546Sopenharmony_ci    VkPhysicalDevice                            physicalDevice,
110bf215546Sopenharmony_ci    const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
111bf215546Sopenharmony_ci    VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities)
112bf215546Sopenharmony_ci{
113bf215546Sopenharmony_ci   VkResult result;
114bf215546Sopenharmony_ci   result = wsi_GetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice,
115bf215546Sopenharmony_ci                                                         pSurfaceInfo,
116bf215546Sopenharmony_ci                                                         pSurfaceCapabilities);
117bf215546Sopenharmony_ci   constraint_surface_capabilities(&pSurfaceCapabilities->surfaceCapabilities);
118bf215546Sopenharmony_ci   return result;
119bf215546Sopenharmony_ci}
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
122bf215546Sopenharmony_civ3dv_CreateSwapchainKHR(
123bf215546Sopenharmony_ci    VkDevice                                     _device,
124bf215546Sopenharmony_ci    const VkSwapchainCreateInfoKHR*              pCreateInfo,
125bf215546Sopenharmony_ci    const VkAllocationCallbacks*                 pAllocator,
126bf215546Sopenharmony_ci    VkSwapchainKHR*                              pSwapchain)
127bf215546Sopenharmony_ci{
128bf215546Sopenharmony_ci   V3DV_FROM_HANDLE(v3dv_device, device, _device);
129bf215546Sopenharmony_ci   struct v3dv_instance *instance = device->instance;
130bf215546Sopenharmony_ci   struct v3dv_physical_device *pdevice = &instance->physicalDevice;
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface);
133bf215546Sopenharmony_ci   VkResult result =
134bf215546Sopenharmony_ci      v3dv_physical_device_acquire_display(instance, pdevice, surface);
135bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
136bf215546Sopenharmony_ci      return result;
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci   return wsi_CreateSwapchainKHR(_device, pCreateInfo, pAllocator, pSwapchain);
139bf215546Sopenharmony_ci}
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_cistruct v3dv_image *
142bf215546Sopenharmony_civ3dv_wsi_get_image_from_swapchain(VkSwapchainKHR swapchain, uint32_t index)
143bf215546Sopenharmony_ci{
144bf215546Sopenharmony_ci   VkImage image = wsi_common_get_image(swapchain, index);
145bf215546Sopenharmony_ci   return v3dv_image_from_handle(image);
146bf215546Sopenharmony_ci}
147