layers: Fix event tracking to differentiate reading and writing
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 32465f2..8aa1547 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -2716,6 +2716,151 @@
#if DRAW_STATE_TESTS
// This is a positive test. No errors should be generated.
+TEST_F(VkLayerTest, WaitEventThenSet) {
+ TEST_DESCRIPTION(
+ "Wait on a event then set it after the wait has been submitted.");
+
+ if ((m_device->queue_props.empty()) ||
+ (m_device->queue_props[0].queueCount < 2))
+ return;
+
+ m_errorMonitor->ExpectSuccess();
+
+ VkEvent event;
+ VkEventCreateInfo event_create_info{};
+ event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+ vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
+
+ VkCommandPool command_pool;
+ VkCommandPoolCreateInfo pool_create_info{};
+ pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+ pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+ vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr,
+ &command_pool);
+
+ VkCommandBuffer command_buffer;
+ VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+ command_buffer_allocate_info.sType =
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ command_buffer_allocate_info.commandPool = command_pool;
+ command_buffer_allocate_info.commandBufferCount = 1;
+ command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info,
+ &command_buffer);
+
+ VkQueue queue = VK_NULL_HANDLE;
+ vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_,
+ 1, &queue);
+
+ {
+ VkCommandBufferBeginInfo begin_info{};
+ begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkBeginCommandBuffer(command_buffer, &begin_info);
+
+ vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
+ nullptr, 0, nullptr);
+ vkCmdResetEvent(command_buffer, event,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
+ vkEndCommandBuffer(command_buffer);
+ }
+ {
+ VkSubmitInfo submit_info{};
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.commandBufferCount = 1;
+ submit_info.pCommandBuffers = &command_buffer;
+ submit_info.signalSemaphoreCount = 0;
+ submit_info.pSignalSemaphores = nullptr;
+ vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+ }
+ { vkSetEvent(m_device->device(), event); }
+
+ vkQueueWaitIdle(queue);
+
+ vkDestroyEvent(m_device->device(), event, nullptr);
+ vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
+ vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+ m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkLayerTest, ResetEventThenSet) {
+ TEST_DESCRIPTION(
+ "Reset an event then set it after the reset has been submitted.");
+
+ if ((m_device->queue_props.empty()) ||
+ (m_device->queue_props[0].queueCount < 2))
+ return;
+
+ m_errorMonitor->ExpectSuccess();
+
+ VkEvent event;
+ VkEventCreateInfo event_create_info{};
+ event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+ vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
+
+ VkCommandPool command_pool;
+ VkCommandPoolCreateInfo pool_create_info{};
+ pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+ pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+ vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr,
+ &command_pool);
+
+ VkCommandBuffer command_buffer;
+ VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+ command_buffer_allocate_info.sType =
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ command_buffer_allocate_info.commandPool = command_pool;
+ command_buffer_allocate_info.commandBufferCount = 1;
+ command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info,
+ &command_buffer);
+
+ VkQueue queue = VK_NULL_HANDLE;
+ vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_,
+ 1, &queue);
+
+ {
+ VkCommandBufferBeginInfo begin_info{};
+ begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkBeginCommandBuffer(command_buffer, &begin_info);
+
+ vkCmdResetEvent(command_buffer, event,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
+ vkCmdWaitEvents(command_buffer, 1, &event,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
+ nullptr, 0, nullptr);
+ vkEndCommandBuffer(command_buffer);
+ }
+ {
+ VkSubmitInfo submit_info{};
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.commandBufferCount = 1;
+ submit_info.pCommandBuffers = &command_buffer;
+ submit_info.signalSemaphoreCount = 0;
+ submit_info.pSignalSemaphores = nullptr;
+ vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+ }
+ {
+ m_errorMonitor->SetDesiredFailureMsg(
+ VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkSetEvent() on event "
+ "0x1 that is already in use by a "
+ "command buffer.");
+ vkSetEvent(m_device->device(), event);
+ m_errorMonitor->VerifyFound();
+ }
+
+ vkQueueWaitIdle(queue);
+
+ vkDestroyEvent(m_device->device(), event, nullptr);
+ vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
+ vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+}
+
+// This is a positive test. No errors should be generated.
TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "