Module: Mesa
Branch: main
Commit: d7938de8feead53700ea9ecdbcae11d9d4e7a30b
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=d7938de8feead53700ea9ecdbcae11d9d4e7a30b

Author: Rhys Perry <[email protected]>
Date:   Tue Dec  5 16:08:22 2023 +0000

vulkan/wsi: don't support present with queues where blit is unsupported

Since we might have to perform a copy, video and sparse queues cannot be
used to present.

Attempting to create a command buffer on RADV for the sparse binding queue
causes a crash.

Signed-off-by: Rhys Perry <[email protected]>
Reviewed-by: Lionel Landwerlin <[email protected]>
Fixes: 748b7f80ef1c ("radv: Move sparse binding into a dedicated queue.")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26523>

---

 src/vulkan/wsi/wsi_common.c         | 31 +++++++++++++++++++++++++++++--
 src/vulkan/wsi/wsi_common.h         |  1 +
 src/vulkan/wsi/wsi_common_wayland.c |  3 +++
 src/vulkan/wsi/wsi_common_win32.cpp |  2 +-
 src/vulkan/wsi/wsi_common_x11.c     |  3 +++
 5 files changed, 37 insertions(+), 3 deletions(-)

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);
 

Reply via email to