layers: Retire work early on external signals
authorMike Schuchardt <mikes@lunarg.com>
Tue, 10 Oct 2017 22:12:05 +0000 (16:12 -0600)
committerChris Forbes <chrisf@ijw.co.nz>
Sat, 14 Oct 2017 00:07:26 +0000 (17:07 -0700)
Retire all work up until a signal operation on an external semaphore and
emit a warning about validation that will no longer occur.

Change-Id: I3d46464c2c32e37071d702e20e5197a495d60472

layers/core_validation.cpp

index 8d08d97..117742a 100644 (file)
@@ -181,6 +181,7 @@ struct layer_data {
     PHYS_DEV_PROPERTIES_NODE phys_dev_properties = {};
     VkPhysicalDeviceMemoryProperties phys_dev_mem_props = {};
     VkPhysicalDeviceProperties phys_dev_props = {};
+    bool external_sync_warning = false;
 };
 
 // TODO : Do we need to guard access to layer_data_map w/ lock?
@@ -2646,6 +2647,7 @@ static bool ValidateFenceForSubmit(layer_data *dev_data, FENCE_NODE *pFence) {
 
 static void PostCallRecordQueueSubmit(layer_data *dev_data, VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
                                       VkFence fence) {
+    uint64_t early_retire_seq = 0;
     auto pQueue = GetQueueState(dev_data, queue);
     auto pFence = GetFenceNode(dev_data, fence);
 
@@ -2692,8 +2694,17 @@ static void PostCallRecordQueueSubmit(layer_data *dev_data, VkQueue queue, uint3
                     pSemaphore->in_use.fetch_add(1);
                     semaphore_signals.push_back(semaphore);
                 } else {
-                    semaphore_externals.push_back(semaphore);
-                    pSemaphore->in_use.fetch_add(1);
+                    // Retire work up until this submit early, we will not see the wait that corresponds to this signal
+                    early_retire_seq = pQueue->seq + pQueue->submissions.size() + 1;
+                    if (!dev_data->external_sync_warning) {
+                        dev_data->external_sync_warning = true;
+                        log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
+                                HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
+                                "vkQueueSubmit(): Signaling external semaphore 0x%" PRIx64 " on queue 0x%" PRIx64
+                                " will disable validation of preceding command buffer lifecycle states and the in-use status of "
+                                "associated objects.",
+                                HandleToUint64(semaphore), HandleToUint64(queue));
+                    }
                 }
             }
         }
@@ -2715,6 +2726,10 @@ static void PostCallRecordQueueSubmit(layer_data *dev_data, VkQueue queue, uint3
                                          submit_idx == submitCount - 1 ? fence : VK_NULL_HANDLE);
     }
 
+    if (early_retire_seq) {
+        RetireWorkOnQueue(dev_data, pQueue, early_retire_seq);
+    }
+
     if (pFence && !submitCount) {
         // If no submissions, but just dropping a fence on the end of the queue,
         // record an empty submission with just the fence, so we can determine
@@ -8822,6 +8837,7 @@ static bool PreCallValidateQueueBindSparse(layer_data *dev_data, VkQueue queue,
 }
 static void PostCallRecordQueueBindSparse(layer_data *dev_data, VkQueue queue, uint32_t bindInfoCount,
                                           const VkBindSparseInfo *pBindInfo, VkFence fence) {
+    uint64_t early_retire_seq = 0;
     auto pFence = GetFenceNode(dev_data, fence);
     auto pQueue = GetQueueState(dev_data, queue);
 
@@ -8890,8 +8906,17 @@ static void PostCallRecordQueueBindSparse(layer_data *dev_data, VkQueue queue, u
                     pSemaphore->in_use.fetch_add(1);
                     semaphore_signals.push_back(semaphore);
                 } else {
-                    semaphore_externals.push_back(semaphore);
-                    pSemaphore->in_use.fetch_add(1);
+                    // Retire work up until this submit early, we will not see the wait that corresponds to this signal
+                    early_retire_seq = pQueue->seq + pQueue->submissions.size() + 1;
+                    if (!dev_data->external_sync_warning) {
+                        dev_data->external_sync_warning = true;
+                        log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
+                                HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
+                                "vkQueueBindSparse(): Signaling external semaphore 0x%" PRIx64 " on queue 0x%" PRIx64
+                                " will disable validation of preceding command buffer lifecycle states and the in-use status of "
+                                "associated objects.",
+                                HandleToUint64(semaphore), HandleToUint64(queue));
+                    }
                 }
             }
         }
@@ -8900,6 +8925,10 @@ static void PostCallRecordQueueBindSparse(layer_data *dev_data, VkQueue queue, u
                                          bindIdx == bindInfoCount - 1 ? fence : VK_NULL_HANDLE);
     }
 
+    if (early_retire_seq) {
+        RetireWorkOnQueue(dev_data, pQueue, early_retire_seq);
+    }
+
     if (pFence && !bindInfoCount) {
         // No work to do, just dropping a fence in the queue by itself.
         pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), std::vector<SEMAPHORE_WAIT>(), std::vector<VkSemaphore>(),