Path: blob/21.2-virgl/src/broadcom/vulkan/v3dv_wsi.c
4560 views
/*1* Copyright © 2020 Raspberry Pi2* based on intel anv code:3* Copyright © 2015 Intel Corporation45* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice (including the next13* paragraph) shall be included in all copies or substantial portions of the14* Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING21* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS22* IN THE SOFTWARE.23*/2425#include "v3dv_private.h"26#include "drm-uapi/drm_fourcc.h"27#include "vk_format_info.h"28#include "vk_util.h"29#include "wsi_common.h"3031static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL32v3dv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)33{34V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);35PFN_vkVoidFunction func;3637func = vk_instance_dispatch_table_get(&pdevice->vk.instance->dispatch_table, pName);38if (func != NULL)39return func;4041func = vk_physical_device_dispatch_table_get(&pdevice->vk.dispatch_table, pName);42if (func != NULL)43return func;4445return vk_device_dispatch_table_get(&vk_device_trampolines, pName);46}4748static bool49v3dv_wsi_can_present_on_device(VkPhysicalDevice _pdevice, int fd)50{51V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, _pdevice);5253drmDevicePtr fd_devinfo, display_devinfo;54int ret;5556ret = drmGetDevice2(fd, 0, &fd_devinfo);57if (ret)58return false;5960ret = drmGetDevice2(pdevice->display_fd, 0, &display_devinfo);61if (ret) {62drmFreeDevice(&fd_devinfo);63return false;64}6566bool result = drmDevicesEqual(fd_devinfo, display_devinfo);6768drmFreeDevice(&fd_devinfo);69drmFreeDevice(&display_devinfo);70return result;71}7273VkResult74v3dv_wsi_init(struct v3dv_physical_device *physical_device)75{76VkResult result;7778result = wsi_device_init(&physical_device->wsi_device,79v3dv_physical_device_to_handle(physical_device),80v3dv_wsi_proc_addr,81&physical_device->vk.instance->alloc,82physical_device->master_fd, NULL, false);8384if (result != VK_SUCCESS)85return result;8687physical_device->wsi_device.supports_modifiers = true;88physical_device->wsi_device.can_present_on_device =89v3dv_wsi_can_present_on_device;9091return VK_SUCCESS;92}9394void95v3dv_wsi_finish(struct v3dv_physical_device *physical_device)96{97wsi_device_finish(&physical_device->wsi_device,98&physical_device->vk.instance->alloc);99}100101VKAPI_ATTR void VKAPI_CALL102v3dv_DestroySurfaceKHR(103VkInstance _instance,104VkSurfaceKHR _surface,105const VkAllocationCallbacks* pAllocator)106{107V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);108ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);109110if (!surface)111return;112113vk_free2(&instance->vk.alloc, pAllocator, surface);114}115116VKAPI_ATTR VkResult VKAPI_CALL117v3dv_GetPhysicalDeviceSurfaceSupportKHR(118VkPhysicalDevice physicalDevice,119uint32_t queueFamilyIndex,120VkSurfaceKHR surface,121VkBool32* pSupported)122{123V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);124125return wsi_common_get_surface_support(&device->wsi_device,126queueFamilyIndex,127surface,128pSupported);129}130131static void132constraint_surface_capabilities(VkSurfaceCapabilitiesKHR *caps)133{134/* Our display pipeline requires that images are linear, so we cannot135* ensure that our swapchain images can be sampled. If we are running under136* a compositor in windowed mode, the DRM modifier negotiation should137* probably end up selecting an UIF layout for the swapchain images but it138* may still choose linear and send images directly for scanout if the139* surface is in fullscreen mode for example. If we are not running under140* a compositor, then we would always need them to be linear anyway.141*/142caps->supportedUsageFlags &= ~VK_IMAGE_USAGE_SAMPLED_BIT;143}144145VKAPI_ATTR VkResult VKAPI_CALL146v3dv_GetPhysicalDeviceSurfaceCapabilitiesKHR(147VkPhysicalDevice physicalDevice,148VkSurfaceKHR surface,149VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)150{151V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);152153VkResult result;154result = wsi_common_get_surface_capabilities(&device->wsi_device,155surface,156pSurfaceCapabilities);157constraint_surface_capabilities(pSurfaceCapabilities);158return result;159}160161VKAPI_ATTR VkResult VKAPI_CALL162v3dv_GetPhysicalDeviceSurfaceCapabilities2KHR(163VkPhysicalDevice physicalDevice,164const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,165VkSurfaceCapabilities2KHR* pSurfaceCapabilities)166{167V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);168169VkResult result;170result = wsi_common_get_surface_capabilities2(&device->wsi_device,171pSurfaceInfo,172pSurfaceCapabilities);173constraint_surface_capabilities(&pSurfaceCapabilities->surfaceCapabilities);174return result;175}176177VKAPI_ATTR VkResult VKAPI_CALL178v3dv_GetPhysicalDeviceSurfaceFormatsKHR(179VkPhysicalDevice physicalDevice,180VkSurfaceKHR surface,181uint32_t* pSurfaceFormatCount,182VkSurfaceFormatKHR* pSurfaceFormats)183{184V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);185186return wsi_common_get_surface_formats(&device->wsi_device, surface,187pSurfaceFormatCount, pSurfaceFormats);188}189190VKAPI_ATTR VkResult VKAPI_CALL191v3dv_GetPhysicalDeviceSurfaceFormats2KHR(192VkPhysicalDevice physicalDevice,193const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,194uint32_t* pSurfaceFormatCount,195VkSurfaceFormat2KHR* pSurfaceFormats)196{197V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);198199return wsi_common_get_surface_formats2(&device->wsi_device, pSurfaceInfo,200pSurfaceFormatCount, pSurfaceFormats);201}202203VKAPI_ATTR VkResult VKAPI_CALL204v3dv_GetPhysicalDeviceSurfacePresentModesKHR(205VkPhysicalDevice physicalDevice,206VkSurfaceKHR surface,207uint32_t* pPresentModeCount,208VkPresentModeKHR* pPresentModes)209{210V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);211212return wsi_common_get_surface_present_modes(&device->wsi_device, surface,213pPresentModeCount,214pPresentModes);215}216217VKAPI_ATTR VkResult VKAPI_CALL218v3dv_CreateSwapchainKHR(219VkDevice _device,220const VkSwapchainCreateInfoKHR* pCreateInfo,221const VkAllocationCallbacks* pAllocator,222VkSwapchainKHR* pSwapchain)223{224V3DV_FROM_HANDLE(v3dv_device, device, _device);225struct v3dv_instance *instance = device->instance;226struct v3dv_physical_device *pdevice = &instance->physicalDevice;227struct wsi_device *wsi_device = &pdevice->wsi_device;228229ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface);230VkResult result =231v3dv_physical_device_acquire_display(instance, pdevice, surface);232if (result != VK_SUCCESS)233return result;234235const VkAllocationCallbacks *alloc;236if (pAllocator)237alloc = pAllocator;238else239alloc = &device->vk.alloc;240241return wsi_common_create_swapchain(wsi_device, _device,242pCreateInfo, alloc, pSwapchain);243}244245VKAPI_ATTR void VKAPI_CALL246v3dv_DestroySwapchainKHR(247VkDevice _device,248VkSwapchainKHR swapchain,249const VkAllocationCallbacks* pAllocator)250{251V3DV_FROM_HANDLE(v3dv_device, device, _device);252const VkAllocationCallbacks *alloc;253254if (pAllocator)255alloc = pAllocator;256else257alloc = &device->vk.alloc;258259wsi_common_destroy_swapchain(_device, swapchain, alloc);260}261262VKAPI_ATTR VkResult VKAPI_CALL263v3dv_GetSwapchainImagesKHR(264VkDevice device,265VkSwapchainKHR swapchain,266uint32_t* pSwapchainImageCount,267VkImage* pSwapchainImages)268{269return wsi_common_get_images(swapchain,270pSwapchainImageCount,271pSwapchainImages);272}273274struct v3dv_image *275v3dv_wsi_get_image_from_swapchain(VkSwapchainKHR swapchain, uint32_t index)276{277uint32_t n_images = index + 1;278VkImage *images = malloc(sizeof(*images) * n_images);279VkResult result = wsi_common_get_images(swapchain, &n_images, images);280281if (result != VK_SUCCESS && result != VK_INCOMPLETE) {282free(images);283return NULL;284}285286V3DV_FROM_HANDLE(v3dv_image, image, images[index]);287free(images);288289return image;290}291292VKAPI_ATTR VkResult VKAPI_CALL293v3dv_AcquireNextImageKHR(294VkDevice device,295VkSwapchainKHR swapchain,296uint64_t timeout,297VkSemaphore semaphore,298VkFence fence,299uint32_t* pImageIndex)300{301VkAcquireNextImageInfoKHR acquire_info = {302.sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,303.swapchain = swapchain,304.timeout = timeout,305.semaphore = semaphore,306.fence = fence,307.deviceMask = 0,308};309310return v3dv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);311}312313VKAPI_ATTR VkResult VKAPI_CALL314v3dv_AcquireNextImage2KHR(315VkDevice _device,316const VkAcquireNextImageInfoKHR* pAcquireInfo,317uint32_t* pImageIndex)318{319V3DV_FROM_HANDLE(v3dv_device, device, _device);320V3DV_FROM_HANDLE(v3dv_fence, fence, pAcquireInfo->fence);321V3DV_FROM_HANDLE(v3dv_semaphore, semaphore, pAcquireInfo->semaphore);322323struct v3dv_physical_device *pdevice = &device->instance->physicalDevice;324325VkResult result;326result = wsi_common_acquire_next_image2(&pdevice->wsi_device, _device,327pAcquireInfo, pImageIndex);328329if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) {330if (fence)331drmSyncobjSignal(pdevice->render_fd, &fence->sync, 1);332if (semaphore)333drmSyncobjSignal(pdevice->render_fd, &semaphore->sync, 1);334}335336return result;337}338339VKAPI_ATTR VkResult VKAPI_CALL340v3dv_QueuePresentKHR(341VkQueue _queue,342const VkPresentInfoKHR* pPresentInfo)343{344V3DV_FROM_HANDLE(v3dv_queue, queue, _queue);345struct v3dv_physical_device *pdevice =346&queue->device->instance->physicalDevice;347348return wsi_common_queue_present(&pdevice->wsi_device,349v3dv_device_to_handle(queue->device),350_queue, 0,351pPresentInfo);352}353354VKAPI_ATTR VkResult VKAPI_CALL355v3dv_GetDeviceGroupPresentCapabilitiesKHR(356VkDevice device,357VkDeviceGroupPresentCapabilitiesKHR* pCapabilities)358{359memset(pCapabilities->presentMask, 0,360sizeof(pCapabilities->presentMask));361pCapabilities->presentMask[0] = 0x1;362pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;363364return VK_SUCCESS;365}366367VKAPI_ATTR VkResult VKAPI_CALL368v3dv_GetDeviceGroupSurfacePresentModesKHR(369VkDevice device,370VkSurfaceKHR surface,371VkDeviceGroupPresentModeFlagsKHR* pModes)372{373*pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;374375return VK_SUCCESS;376}377378VKAPI_ATTR VkResult VKAPI_CALL379v3dv_GetPhysicalDevicePresentRectanglesKHR(380VkPhysicalDevice physicalDevice,381VkSurfaceKHR surface,382uint32_t* pRectCount,383VkRect2D* pRects)384{385V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);386387return wsi_common_get_present_rectangles(&device->wsi_device,388surface,389pRectCount, pRects);390}391392393