Path: blob/21.2-virgl/src/intel/vulkan/anv_wsi.c
4547 views
/*1* Copyright © 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "anv_private.h"24#include "anv_measure.h"25#include "wsi_common.h"26#include "vk_util.h"2728static PFN_vkVoidFunction29anv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)30{31ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);32return vk_instance_get_proc_addr_unchecked(&pdevice->instance->vk, pName);33}3435static void36anv_wsi_signal_semaphore_for_memory(VkDevice _device,37VkSemaphore _semaphore,38VkDeviceMemory _memory)39{40ANV_FROM_HANDLE(anv_device, device, _device);41ANV_FROM_HANDLE(anv_semaphore, semaphore, _semaphore);42ANV_FROM_HANDLE(anv_device_memory, memory, _memory);4344/* Put a BO semaphore with the image BO in the temporary. For BO binary45* semaphores, we always set EXEC_OBJECT_WRITE so this creates a WaR46* hazard with the display engine's read to ensure that no one writes to47* the image before the read is complete.48*/49anv_semaphore_reset_temporary(device, semaphore);5051struct anv_semaphore_impl *impl = &semaphore->temporary;52impl->type = ANV_SEMAPHORE_TYPE_WSI_BO;53impl->bo = anv_bo_ref(memory->bo);54}5556static void57anv_wsi_signal_fence_for_memory(VkDevice _device,58VkFence _fence,59VkDeviceMemory _memory)60{61ANV_FROM_HANDLE(anv_device, device, _device);62ANV_FROM_HANDLE(anv_fence, fence, _fence);63ANV_FROM_HANDLE(anv_device_memory, memory, _memory);6465/* Put a BO fence with the image BO in the temporary. For BO fences, we66* always just wait until the BO isn't busy and reads from the BO should67* count as busy.68*/69anv_fence_reset_temporary(device, fence);7071struct anv_fence_impl *impl = &fence->temporary;72impl->type = ANV_FENCE_TYPE_WSI_BO;73impl->bo.bo = anv_bo_ref(memory->bo);74impl->bo.state = ANV_BO_FENCE_STATE_SUBMITTED;75}7677VkResult78anv_init_wsi(struct anv_physical_device *physical_device)79{80VkResult result;8182result = wsi_device_init(&physical_device->wsi_device,83anv_physical_device_to_handle(physical_device),84anv_wsi_proc_addr,85&physical_device->instance->vk.alloc,86physical_device->master_fd,87&physical_device->instance->dri_options,88false);89if (result != VK_SUCCESS)90return result;9192physical_device->wsi_device.supports_modifiers = true;93physical_device->wsi_device.signal_semaphore_for_memory =94anv_wsi_signal_semaphore_for_memory;95physical_device->wsi_device.signal_fence_for_memory =96anv_wsi_signal_fence_for_memory;9798return VK_SUCCESS;99}100101void102anv_finish_wsi(struct anv_physical_device *physical_device)103{104wsi_device_finish(&physical_device->wsi_device,105&physical_device->instance->vk.alloc);106}107108void anv_DestroySurfaceKHR(109VkInstance _instance,110VkSurfaceKHR _surface,111const VkAllocationCallbacks* pAllocator)112{113ANV_FROM_HANDLE(anv_instance, instance, _instance);114ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);115116if (!surface)117return;118119vk_free2(&instance->vk.alloc, pAllocator, surface);120}121122VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(123VkPhysicalDevice physicalDevice,124uint32_t queueFamilyIndex,125VkSurfaceKHR surface,126VkBool32* pSupported)127{128ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);129130return wsi_common_get_surface_support(&device->wsi_device,131queueFamilyIndex,132surface,133pSupported);134}135136VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(137VkPhysicalDevice physicalDevice,138VkSurfaceKHR surface,139VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)140{141ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);142143return wsi_common_get_surface_capabilities(&device->wsi_device,144surface,145pSurfaceCapabilities);146}147148VkResult anv_GetPhysicalDeviceSurfaceCapabilities2KHR(149VkPhysicalDevice physicalDevice,150const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,151VkSurfaceCapabilities2KHR* pSurfaceCapabilities)152{153ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);154155return wsi_common_get_surface_capabilities2(&device->wsi_device,156pSurfaceInfo,157pSurfaceCapabilities);158}159160VkResult anv_GetPhysicalDeviceSurfaceCapabilities2EXT(161VkPhysicalDevice physicalDevice,162VkSurfaceKHR surface,163VkSurfaceCapabilities2EXT* pSurfaceCapabilities)164{165ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);166167return wsi_common_get_surface_capabilities2ext(&device->wsi_device,168surface,169pSurfaceCapabilities);170}171172VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(173VkPhysicalDevice physicalDevice,174VkSurfaceKHR surface,175uint32_t* pSurfaceFormatCount,176VkSurfaceFormatKHR* pSurfaceFormats)177{178ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);179180return wsi_common_get_surface_formats(&device->wsi_device, surface,181pSurfaceFormatCount, pSurfaceFormats);182}183184VkResult anv_GetPhysicalDeviceSurfaceFormats2KHR(185VkPhysicalDevice physicalDevice,186const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,187uint32_t* pSurfaceFormatCount,188VkSurfaceFormat2KHR* pSurfaceFormats)189{190ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);191192return wsi_common_get_surface_formats2(&device->wsi_device, pSurfaceInfo,193pSurfaceFormatCount, pSurfaceFormats);194}195196VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(197VkPhysicalDevice physicalDevice,198VkSurfaceKHR surface,199uint32_t* pPresentModeCount,200VkPresentModeKHR* pPresentModes)201{202ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);203204return wsi_common_get_surface_present_modes(&device->wsi_device, surface,205pPresentModeCount,206pPresentModes);207}208209VkResult anv_CreateSwapchainKHR(210VkDevice _device,211const VkSwapchainCreateInfoKHR* pCreateInfo,212const VkAllocationCallbacks* pAllocator,213VkSwapchainKHR* pSwapchain)214{215ANV_FROM_HANDLE(anv_device, device, _device);216struct wsi_device *wsi_device = &device->physical->wsi_device;217const VkAllocationCallbacks *alloc;218219if (pAllocator)220alloc = pAllocator;221else222alloc = &device->vk.alloc;223224return wsi_common_create_swapchain(wsi_device, _device,225pCreateInfo, alloc, pSwapchain);226}227228void anv_DestroySwapchainKHR(229VkDevice _device,230VkSwapchainKHR swapchain,231const VkAllocationCallbacks* pAllocator)232{233ANV_FROM_HANDLE(anv_device, device, _device);234const VkAllocationCallbacks *alloc;235236if (pAllocator)237alloc = pAllocator;238else239alloc = &device->vk.alloc;240241wsi_common_destroy_swapchain(_device, swapchain, alloc);242}243244VkResult anv_GetSwapchainImagesKHR(245VkDevice device,246VkSwapchainKHR swapchain,247uint32_t* pSwapchainImageCount,248VkImage* pSwapchainImages)249{250return wsi_common_get_images(swapchain,251pSwapchainImageCount,252pSwapchainImages);253}254255VkResult anv_AcquireNextImageKHR(256VkDevice device,257VkSwapchainKHR swapchain,258uint64_t timeout,259VkSemaphore semaphore,260VkFence fence,261uint32_t* pImageIndex)262{263VkAcquireNextImageInfoKHR 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};271272return anv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);273}274275VkResult anv_AcquireNextImage2KHR(276VkDevice _device,277const VkAcquireNextImageInfoKHR* pAcquireInfo,278uint32_t* pImageIndex)279{280ANV_FROM_HANDLE(anv_device, device, _device);281282anv_measure_acquire(device);283return wsi_common_acquire_next_image2(&device->physical->wsi_device,284_device, pAcquireInfo, pImageIndex);285}286287VkResult anv_QueuePresentKHR(288VkQueue _queue,289const VkPresentInfoKHR* pPresentInfo)290{291ANV_FROM_HANDLE(anv_queue, queue, _queue);292struct anv_device *device = queue->device;293294if (device->debug_frame_desc) {295device->debug_frame_desc->frame_id++;296if (!device->info.has_llc) {297intel_clflush_range(device->debug_frame_desc,298sizeof(*device->debug_frame_desc));299}300}301302if (device->has_thread_submit &&303pPresentInfo->waitSemaphoreCount > 0) {304/* Make sure all of the dependency semaphores have materialized when305* using a threaded submission.306*/307VK_MULTIALLOC(ma);308VK_MULTIALLOC_DECL(&ma, uint64_t, values,309pPresentInfo->waitSemaphoreCount);310VK_MULTIALLOC_DECL(&ma, uint32_t, syncobjs,311pPresentInfo->waitSemaphoreCount);312313if (!vk_multialloc_alloc(&ma, &device->vk.alloc,314VK_SYSTEM_ALLOCATION_SCOPE_COMMAND))315return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);316317uint32_t wait_count = 0;318for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; i++) {319ANV_FROM_HANDLE(anv_semaphore, semaphore, pPresentInfo->pWaitSemaphores[i]);320struct anv_semaphore_impl *impl =321semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ?322&semaphore->temporary : &semaphore->permanent;323324if (impl->type == ANV_SEMAPHORE_TYPE_DUMMY)325continue;326assert(impl->type == ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ);327syncobjs[wait_count] = impl->syncobj;328values[wait_count] = 0;329wait_count++;330}331332int ret = 0;333if (wait_count > 0) {334ret =335anv_gem_syncobj_timeline_wait(device,336syncobjs, values, wait_count,337anv_get_absolute_timeout(INT64_MAX),338true /* wait_all */,339true /* wait_materialize */);340}341342vk_free(&device->vk.alloc, values);343344if (ret)345return vk_error(VK_ERROR_DEVICE_LOST);346}347348VkResult result = wsi_common_queue_present(&device->physical->wsi_device,349anv_device_to_handle(queue->device),350_queue, 0,351pPresentInfo);352353for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; i++) {354ANV_FROM_HANDLE(anv_semaphore, semaphore, pPresentInfo->pWaitSemaphores[i]);355/* From the Vulkan 1.0.53 spec:356*357* "If the import is temporary, the implementation must restore the358* semaphore to its prior permanent state after submitting the next359* semaphore wait operation."360*/361anv_semaphore_reset_temporary(queue->device, semaphore);362}363364return result;365}366367VkResult anv_GetDeviceGroupPresentCapabilitiesKHR(368VkDevice device,369VkDeviceGroupPresentCapabilitiesKHR* pCapabilities)370{371memset(pCapabilities->presentMask, 0,372sizeof(pCapabilities->presentMask));373pCapabilities->presentMask[0] = 0x1;374pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;375376return VK_SUCCESS;377}378379VkResult anv_GetDeviceGroupSurfacePresentModesKHR(380VkDevice device,381VkSurfaceKHR surface,382VkDeviceGroupPresentModeFlagsKHR* pModes)383{384*pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;385386return VK_SUCCESS;387}388389VkResult anv_GetPhysicalDevicePresentRectanglesKHR(390VkPhysicalDevice physicalDevice,391VkSurfaceKHR surface,392uint32_t* pRectCount,393VkRect2D* pRects)394{395ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);396397return wsi_common_get_present_rectangles(&device->wsi_device,398surface,399pRectCount, pRects);400}401402403