diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index ad2130c409f..93cd054c05f 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -110,6 +110,16 @@ wsi_device_init(struct wsi_device *wsi, GetPhysicalDeviceMemoryProperties(pdevice, &wsi->memory_props); GetPhysicalDeviceQueueFamilyProperties(pdevice, &wsi->queue_family_count, NULL); + assert(wsi->queue_family_count <= 64); + VkQueueFamilyProperties queue_properties[64]; + GetPhysicalDeviceQueueFamilyProperties(pdevice, &wsi->queue_family_count, queue_properties); + + for (unsigned i = 0; i < wsi->queue_family_count; i++) { + VkFlags req_flags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT; + if (queue_properties[i].queueFlags & req_flags) + wsi->queue_supports_blit |= BITFIELD64_BIT(i); + } + for (VkExternalSemaphoreHandleTypeFlags handle_type = 1; handle_type <= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; handle_type <<= 1) { @@ -438,6 +448,10 @@ wsi_swapchain_init(const struct wsi_device *wsi, VK_FROM_HANDLE(vk_queue, queue, chain->blit.queue); queue_family_index = queue->queue_family_index; } + + if (!(wsi->queue_supports_blit & BITFIELD64_BIT(queue_family_index))) + continue; + const VkCommandPoolCreateInfo cmd_pool_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .pNext = NULL, @@ -540,6 +554,8 @@ wsi_swapchain_finish(struct wsi_swapchain *chain) int cmd_pools_count = chain->blit.queue != VK_NULL_HANDLE ? 1 : chain->wsi->queue_family_count; for (uint32_t i = 0; i < cmd_pools_count; i++) { + if (!chain->cmd_pools[i]) + continue; chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i], &chain->alloc); } @@ -734,6 +750,8 @@ wsi_destroy_image(const struct wsi_swapchain *chain, chain->blit.queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; for (uint32_t i = 0; i < cmd_buffer_count; i++) { + if (!chain->cmd_pools[i]) + continue; wsi->FreeCommandBuffers(chain->device, chain->cmd_pools[i], 1, &image->blit.cmd_buffers[i]); } @@ -758,8 +776,14 @@ wsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, struct wsi_device *wsi_device = device->wsi_device; struct wsi_interface *iface = wsi_device->wsi[surface->platform]; - return iface->get_support(surface, wsi_device, - queueFamilyIndex, pSupported); + VkResult res = iface->get_support(surface, wsi_device, + queueFamilyIndex, pSupported); + if (res == VK_SUCCESS) { + bool blit = wsi_device->queue_supports_blit & BITFIELD64_BIT(queueFamilyIndex); + *pSupported = (bool)*pSupported && blit; + } + + return res; } VKAPI_ATTR VkResult VKAPI_CALL @@ -1795,6 +1819,9 @@ wsi_finish_create_blit_context(const struct wsi_swapchain *chain, return VK_ERROR_OUT_OF_HOST_MEMORY; for (uint32_t i = 0; i < cmd_buffer_count; i++) { + if (!chain->cmd_pools[i]) + continue; + const VkCommandBufferAllocateInfo cmd_buffer_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .pNext = NULL, diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 5a3be83f3f3..b6b803c52ef 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -106,6 +106,7 @@ struct wsi_device { VkPhysicalDevice pdevice; VkPhysicalDeviceMemoryProperties memory_props; uint32_t queue_family_count; + uint64_t queue_supports_blit; VkPhysicalDeviceDrmPropertiesEXT drm_info; VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info; diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index ffc15f32bc5..4d52171e28b 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -996,6 +996,9 @@ wsi_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevi struct wsi_wayland *wsi = (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND]; + if (!(wsi_device->queue_supports_blit & BITFIELD64_BIT(queueFamilyIndex))) + return false; + struct wsi_wl_display display; VkResult ret = wsi_wl_display_init(wsi, &display, wl_display, false, wsi_device->sw); diff --git a/src/vulkan/wsi/wsi_common_win32.cpp b/src/vulkan/wsi/wsi_common_win32.cpp index b867d0ec1f9..a85e6909e5d 100644 --- a/src/vulkan/wsi/wsi_common_win32.cpp +++ b/src/vulkan/wsi/wsi_common_win32.cpp @@ -112,7 +112,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL wsi_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) { - return true; + return wsi_device->queue_supports_blit & BITFIELD64_BIT(queueFamilyIndex); } VKAPI_ATTR VkResult VKAPI_CALL diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 9cfdc6f9683..b7724c028ea 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -572,6 +572,9 @@ wsi_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, { VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); struct wsi_device *wsi_device = pdevice->wsi_device; + if (!(wsi_device->queue_supports_blit & BITFIELD64_BIT(queueFamilyIndex))) + return false; + struct wsi_x11_connection *wsi_conn = wsi_x11_get_connection(wsi_device, connection);