X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_wsi.c;h=5e9c239e6370648c9d27ca2baf2624b009823023;hb=e12688f365258f6f719983528a2af9b6ca4e25c5;hp=a946bd4a8c5ad6cf1b9ef1be706571e6e7f3d373;hpb=0a153f4ee472f8f17575bbfe05f1c96fb5ecf1ea;p=mesa.git diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index a946bd4a8c5..5e9c239e637 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -24,18 +24,40 @@ */ #include "radv_private.h" +#include "radv_meta.h" #include "wsi_common.h" +#include "vk_util.h" +#include "util/macros.h" -static const struct wsi_callbacks wsi_cbs = { - .get_phys_device_format_properties = radv_GetPhysicalDeviceFormatProperties, +#define WSI_CB(x) .x = radv_##x +MAYBE_UNUSED static const struct wsi_callbacks wsi_cbs = { + WSI_CB(GetPhysicalDeviceFormatProperties), }; +static PFN_vkVoidFunction +radv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName) +{ + return radv_lookup_entrypoint(pName); +} + +static uint32_t +radv_wsi_queue_get_family_index(VkQueue _queue) +{ + RADV_FROM_HANDLE(radv_queue, queue, _queue); + return queue->queue_family_index; +} + VkResult radv_init_wsi(struct radv_physical_device *physical_device) { VkResult result; - memset(physical_device->wsi_device.wsi, 0, sizeof(physical_device->wsi_device.wsi)); + wsi_device_init(&physical_device->wsi_device, + radv_physical_device_to_handle(physical_device), + radv_wsi_proc_addr); + + physical_device->wsi_device.queue_get_family_index = + radv_wsi_queue_get_family_index; #ifdef VK_USE_PLATFORM_XCB_KHR result = wsi_x11_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc); @@ -75,7 +97,7 @@ void radv_DestroySurfaceKHR( const VkAllocationCallbacks* pAllocator) { RADV_FROM_HANDLE(radv_instance, instance, _instance); - RADV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); vk_free2(&instance->alloc, pAllocator, surface); } @@ -87,12 +109,12 @@ VkResult radv_GetPhysicalDeviceSurfaceSupportKHR( VkBool32* pSupported) { RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice); - RADV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); struct wsi_interface *iface = device->wsi_device.wsi[surface->platform]; return iface->get_support(surface, &device->wsi_device, &device->instance->alloc, - queueFamilyIndex, pSupported); + queueFamilyIndex, device->local_fd, true, pSupported); } VkResult radv_GetPhysicalDeviceSurfaceCapabilitiesKHR( @@ -101,7 +123,7 @@ VkResult radv_GetPhysicalDeviceSurfaceCapabilitiesKHR( VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) { RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice); - RADV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); struct wsi_interface *iface = device->wsi_device.wsi[surface->platform]; return iface->get_capabilities(surface, pSurfaceCapabilities); @@ -114,7 +136,7 @@ VkResult radv_GetPhysicalDeviceSurfaceFormatsKHR( VkSurfaceFormatKHR* pSurfaceFormats) { RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice); - RADV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); struct wsi_interface *iface = device->wsi_device.wsi[surface->platform]; return iface->get_formats(surface, &device->wsi_device, pSurfaceFormatCount, @@ -128,120 +150,13 @@ VkResult radv_GetPhysicalDeviceSurfacePresentModesKHR( VkPresentModeKHR* pPresentModes) { RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice); - RADV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); struct wsi_interface *iface = device->wsi_device.wsi[surface->platform]; return iface->get_present_modes(surface, pPresentModeCount, pPresentModes); } -static VkResult -radv_wsi_image_create(VkDevice device_h, - const VkSwapchainCreateInfoKHR *pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImage *image_p, - VkDeviceMemory *memory_p, - uint32_t *size, - uint32_t *offset, - uint32_t *row_pitch, int *fd_p) -{ - struct radv_device *device = radv_device_from_handle(device_h); - VkResult result = VK_SUCCESS; - struct radeon_surf *surface; - VkImage image_h; - struct radv_image *image; - bool bret; - int fd; - - result = radv_image_create(device_h, - &(struct radv_image_create_info) { - .vk_info = - &(VkImageCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .imageType = VK_IMAGE_TYPE_2D, - .format = pCreateInfo->imageFormat, - .extent = { - .width = pCreateInfo->imageExtent.width, - .height = pCreateInfo->imageExtent.height, - .depth = 1 - }, - .mipLevels = 1, - .arrayLayers = 1, - .samples = 1, - /* FIXME: Need a way to use X tiling to allow scanout */ - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - .flags = 0, - }, - .scanout = true}, - NULL, - &image_h); - if (result != VK_SUCCESS) - return result; - - image = radv_image_from_handle(image_h); - - VkDeviceMemory memory_h; - struct radv_device_memory *memory; - result = radv_AllocateMemory(device_h, - &(VkMemoryAllocateInfo) { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .allocationSize = image->size, - .memoryTypeIndex = 0, - }, - NULL /* XXX: pAllocator */, - &memory_h); - if (result != VK_SUCCESS) - goto fail_create_image; - - memory = radv_device_memory_from_handle(memory_h); - - radv_BindImageMemory(VK_NULL_HANDLE, image_h, memory_h, 0); - - bret = device->ws->buffer_get_fd(device->ws, - memory->bo, &fd); - if (bret == false) - goto fail_alloc_memory; - - { - struct radeon_bo_metadata metadata; - radv_init_metadata(device, image, &metadata); - device->ws->buffer_set_metadata(memory->bo, &metadata); - } - surface = &image->surface; - - *image_p = image_h; - *memory_p = memory_h; - *fd_p = fd; - *size = image->size; - *offset = image->offset; - *row_pitch = surface->level[0].pitch_bytes; - return VK_SUCCESS; - fail_alloc_memory: - radv_FreeMemory(device_h, memory_h, pAllocator); - -fail_create_image: - radv_DestroyImage(device_h, image_h, pAllocator); - - return result; -} - -static void -radv_wsi_image_free(VkDevice device, - const VkAllocationCallbacks* pAllocator, - VkImage image_h, - VkDeviceMemory memory_h) -{ - radv_DestroyImage(device, image_h, pAllocator); - - radv_FreeMemory(device, memory_h, pAllocator); -} - -static const struct wsi_image_fns radv_wsi_image_fns = { - .create_wsi_image = radv_wsi_image_create, - .free_wsi_image = radv_wsi_image_free, -}; - VkResult radv_CreateSwapchainKHR( VkDevice _device, const VkSwapchainCreateInfoKHR* pCreateInfo, @@ -249,9 +164,9 @@ VkResult radv_CreateSwapchainKHR( VkSwapchainKHR* pSwapchain) { RADV_FROM_HANDLE(radv_device, device, _device); - RADV_FROM_HANDLE(_VkIcdSurfaceBase, surface, pCreateInfo->surface); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface); struct wsi_interface *iface = - device->instance->physicalDevice.wsi_device.wsi[surface->platform]; + device->physical_device->wsi_device.wsi[surface->platform]; struct wsi_swapchain *swapchain; const VkAllocationCallbacks *alloc; if (pAllocator) @@ -259,9 +174,10 @@ VkResult radv_CreateSwapchainKHR( else alloc = &device->alloc; VkResult result = iface->create_swapchain(surface, _device, - &device->instance->physicalDevice.wsi_device, + &device->physical_device->wsi_device, + device->physical_device->local_fd, pCreateInfo, - alloc, &radv_wsi_image_fns, + alloc, &swapchain); if (result != VK_SUCCESS) return result; @@ -288,6 +204,9 @@ void radv_DestroySwapchainKHR( RADV_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); const VkAllocationCallbacks *alloc; + if (!_swapchain) + return; + if (pAllocator) alloc = pAllocator; else @@ -327,11 +246,10 @@ VkResult radv_AcquireNextImageKHR( VkResult result = swapchain->acquire_next_image(swapchain, timeout, semaphore, pImageIndex); - if (fence && result == VK_SUCCESS) { + if (fence && (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)) { fence->submitted = true; fence->signalled = true; } - return result; } @@ -341,31 +259,77 @@ VkResult radv_QueuePresentKHR( { RADV_FROM_HANDLE(radv_queue, queue, _queue); VkResult result = VK_SUCCESS; + const VkPresentRegionsKHR *regions = + vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR); for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) { RADV_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]); + struct radeon_winsys_cs *cs; + const VkPresentRegionKHR *region = NULL; + VkResult item_result; + struct radv_winsys_sem_info sem_info; + + item_result = radv_alloc_sem_info(&sem_info, + pPresentInfo->waitSemaphoreCount, + pPresentInfo->pWaitSemaphores, + 0, + NULL); + if (pPresentInfo->pResults != NULL) + pPresentInfo->pResults[i] = item_result; + result = result == VK_SUCCESS ? item_result : result; + if (item_result != VK_SUCCESS) { + radv_free_sem_info(&sem_info); + continue; + } assert(radv_device_from_handle(swapchain->device) == queue->device); if (swapchain->fences[0] == VK_NULL_HANDLE) { - result = radv_CreateFence(radv_device_to_handle(queue->device), + item_result = radv_CreateFence(radv_device_to_handle(queue->device), &(VkFenceCreateInfo) { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .flags = 0, }, &swapchain->alloc, &swapchain->fences[0]); - if (result != VK_SUCCESS) - return result; + if (pPresentInfo->pResults != NULL) + pPresentInfo->pResults[i] = item_result; + result = result == VK_SUCCESS ? item_result : result; + if (item_result != VK_SUCCESS) { + radv_free_sem_info(&sem_info); + continue; + } } else { radv_ResetFences(radv_device_to_handle(queue->device), 1, &swapchain->fences[0]); } - radv_QueueSubmit(_queue, 0, NULL, swapchain->fences[0]); + cs = queue->device->empty_cs[queue->queue_family_index]; + RADV_FROM_HANDLE(radv_fence, fence, swapchain->fences[0]); + struct radeon_winsys_fence *base_fence = fence->fence; + struct radeon_winsys_ctx *ctx = queue->hw_ctx; - result = swapchain->queue_present(swapchain, - pPresentInfo->pImageIndices[i]); + queue->device->ws->cs_submit(ctx, queue->queue_idx, + &cs, + 1, NULL, NULL, + &sem_info, + false, base_fence); + fence->submitted = true; + + if (regions && regions->pRegions) + region = ®ions->pRegions[i]; + + item_result = swapchain->queue_present(swapchain, + _queue, + pPresentInfo->waitSemaphoreCount, + pPresentInfo->pWaitSemaphores, + pPresentInfo->pImageIndices[i], + region); /* TODO: What if one of them returns OUT_OF_DATE? */ - if (result != VK_SUCCESS) - return result; + if (pPresentInfo->pResults != NULL) + pPresentInfo->pResults[i] = item_result; + result = result == VK_SUCCESS ? item_result : result; + if (item_result != VK_SUCCESS) { + radv_free_sem_info(&sem_info); + continue; + } VkFence last = swapchain->fences[2]; swapchain->fences[2] = swapchain->fences[1]; @@ -377,6 +341,7 @@ VkResult radv_QueuePresentKHR( 1, &last, true, 1); } + radv_free_sem_info(&sem_info); } return VK_SUCCESS;