support and use VkSubmitInfo semaphore signaling and waiting
diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp
index 272bbc5..d1a2173 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -1163,6 +1163,31 @@
             pCBInfo->lastSubmittedFence = fence;
             pCBInfo->lastSubmittedQueue = queue;
         }
+
+        for (uint32_t i = 0; i < submit->waitSemCount; i++) {
+            VkSemaphore sem = submit->pWaitSemaphores[i];
+
+            if (semaphoreMap.find(sem.handle) != semaphoreMap.end()) {
+                if (semaphoreMap[sem.handle] != MEMTRACK_SEMAPHORE_STATE_SIGNALLED) {
+                    skipCall = log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_SEMAPHORE, sem.handle,
+                            0, MEMTRACK_NONE, "SEMAPHORE",
+                            "vkQueueSubmit: Semaphore must be in signaled state before passing to pWaitSemaphores");
+                }
+                semaphoreMap[sem.handle] = MEMTRACK_SEMAPHORE_STATE_WAIT;
+            }
+        }
+        for (uint32_t i = 0; i < submit->signalSemCount; i++) {
+            VkSemaphore sem = submit->pWaitSemaphores[i];
+
+            if (semaphoreMap.find(sem.handle) != semaphoreMap.end()) {
+                if (semaphoreMap[sem.handle] != MEMTRACK_SEMAPHORE_STATE_UNSET) {
+                    skipCall = log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_SEMAPHORE, sem.handle,
+                            0, MEMTRACK_NONE, "SEMAPHORE",
+                            "vkQueueSubmit: Semaphore must not be currently signaled or in a wait state");
+                }
+                semaphoreMap[sem.handle] = MEMTRACK_SEMAPHORE_STATE_SIGNALLED;
+            }
+        }
     }
 
     loader_platform_thread_unlock_mutex(&globalLock);
@@ -1170,6 +1195,20 @@
         result = get_dispatch_table(mem_tracker_device_table_map, queue)->QueueSubmit(
             queue, submitCount, pSubmitInfo, fence);
     }
+
+    loader_platform_thread_lock_mutex(&globalLock);
+    for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
+        const VkSubmitInfo *submit = &pSubmitInfo[submit_idx];
+        for (uint32_t i = 0; i < submit->waitSemCount; i++) {
+            VkSemaphore sem = submit->pWaitSemaphores[i];
+
+            if (semaphoreMap.find(sem.handle) != semaphoreMap.end()) {
+                semaphoreMap[sem.handle] = MEMTRACK_SEMAPHORE_STATE_UNSET;
+            }
+        }
+    }
+    loader_platform_thread_unlock_mutex(&globalLock);
+
     return result;
 }
 
diff --git a/tests/vktestframework.cpp b/tests/vktestframework.cpp
index c588264..f320460 100644
--- a/tests/vktestframework.cpp
+++ b/tests/vktestframework.cpp
@@ -534,13 +534,6 @@
     // return codes
     assert(!err);
 
-    // Wait for the present complete semaphore to be signaled to ensure
-    // that the image won't be rendered to until the presentation
-    // engine has fully released ownership to the application, and it is
-    // okay to render to the image.
-    vkQueueWaitSemaphore(m_queue.handle(), presentCompleteSemaphore);
-    vkDestroySemaphore(m_device.handle(), presentCompleteSemaphore);
-
     VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
     buf.init_as_src(m_device, (VkDeviceSize)m_display_image->m_data_size, flags);
     dest_ptr = buf.memory().map();
@@ -586,10 +579,14 @@
     VkCmdBuffer cmdBufs[1];
     cmdBufs[0] = m_cmdbuf.handle();
 
+    // Wait for the present complete semaphore to be signaled to ensure
+    // that the image won't be rendered to until the presentation
+    // engine has fully released ownership to the application, and it is
+    // okay to render to the image.
     VkFence nullFence = { VK_NULL_HANDLE };
     VkSubmitInfo submit_info;
-    submit_info.waitSemCount = 0;
-    submit_info.pWaitSemaphores = NULL;
+    submit_info.waitSemCount = 1;
+    submit_info.pWaitSemaphores = &presentCompleteSemaphore,
     submit_info.cmdBufferCount = 1;
     submit_info.pCommandBuffers = cmdBufs;
     submit_info.signalSemCount = 0;
@@ -598,6 +595,8 @@
     vkQueueSubmit(m_queue.handle(), 1, &submit_info, nullFence);
     m_queue.wait();
 
+    vkDestroySemaphore(m_device.handle(), presentCompleteSemaphore);
+
     VkPresentInfoKHR present = {};
     present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
     present.pNext = NULL;