anv: refcount semaphores
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sat, 26 Oct 2019 15:59:59 +0000 (18:59 +0300)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Mon, 11 Nov 2019 21:46:51 +0000 (21:46 +0000)
Delayed submissions required by timeline semaphores mean we need to be
able to update the sync fd backed semaphores in a delayed fashion.
This could mean a race between the application destroying the
semaphore and the submission code trying to update it with the new
sync fd.

This change prepares semaphores to be refcounted, we'll most likely
only take a reference for cases where we signal a sync fd semaphore.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/intel/vulkan/anv_private.h
src/intel/vulkan/anv_queue.c

index ff28d897a21b38f6a0f4cd8dcf09d2e8174f1087..3aae01e6b2ff3f5959efcc1da461a68a92ee6332 100644 (file)
@@ -2806,6 +2806,8 @@ struct anv_semaphore_impl {
 };
 
 struct anv_semaphore {
+   uint32_t refcount;
+
    /* Permanent semaphore state.  Every semaphore has some form of permanent
     * state (type != ANV_SEMAPHORE_TYPE_NONE).  This may be a BO to fence on
     * (for cross-process semaphores0 or it could just be a dummy for use
index 8bf58e3214abe8aae9028b850d83cdfa0f8d660d..74f3a3c42548380de455361aa4cf56d32eccce4c 100644 (file)
@@ -947,11 +947,13 @@ VkResult anv_CreateSemaphore(
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO);
 
-   semaphore = vk_alloc2(&device->alloc, pAllocator, sizeof(*semaphore), 8,
-                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   semaphore = vk_alloc(&device->alloc, sizeof(*semaphore), 8,
+                        VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
    if (semaphore == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   p_atomic_set(&semaphore->refcount, 1);
+
    const VkExportSemaphoreCreateInfo *export =
       vk_find_struct_const(pCreateInfo->pNext, EXPORT_SEMAPHORE_CREATE_INFO);
     VkExternalSemaphoreHandleTypeFlags handleTypes =
@@ -1049,6 +1051,25 @@ anv_semaphore_reset_temporary(struct anv_device *device,
    anv_semaphore_impl_cleanup(device, &semaphore->temporary);
 }
 
+static struct anv_semaphore *
+anv_semaphore_ref(struct anv_semaphore *semaphore)
+{
+   assert(semaphore->refcount);
+   p_atomic_inc(&semaphore->refcount);
+   return semaphore;
+}
+
+static void
+anv_semaphore_unref(struct anv_device *device, struct anv_semaphore *semaphore)
+{
+   if (!p_atomic_dec_zero(&semaphore->refcount))
+      return;
+
+   anv_semaphore_impl_cleanup(device, &semaphore->temporary);
+   anv_semaphore_impl_cleanup(device, &semaphore->permanent);
+   vk_free(&device->alloc, semaphore);
+}
+
 void anv_DestroySemaphore(
     VkDevice                                    _device,
     VkSemaphore                                 _semaphore,
@@ -1060,10 +1081,7 @@ void anv_DestroySemaphore(
    if (semaphore == NULL)
       return;
 
-   anv_semaphore_impl_cleanup(device, &semaphore->temporary);
-   anv_semaphore_impl_cleanup(device, &semaphore->permanent);
-
-   vk_free2(&device->alloc, pAllocator, semaphore);
+   anv_semaphore_unref(device, semaphore);
 }
 
 void anv_GetPhysicalDeviceExternalSemaphoreProperties(