diff --git a/tests/unit/sync_val_positive.cpp b/tests/unit/sync_val_positive.cpp index 853a7ff8864..1fd27d131bf 100644 --- a/tests/unit/sync_val_positive.cpp +++ b/tests/unit/sync_val_positive.cpp @@ -411,3 +411,96 @@ TEST_F(PositiveSyncVal, ShaderReferencesNotBoundSet) { vk::CmdEndRenderPass(*m_commandBuffer); m_commandBuffer->end(); } + +TEST_F(PositiveSyncVal, Issue6177) { + SetTargetApiVersion(VK_API_VERSION_1_3); + AddSurfaceExtension(); + ASSERT_NO_FATAL_FAILURE(InitSyncValFramework(true)); + if (DeviceValidationVersion() < VK_API_VERSION_1_3) { + GTEST_SKIP() << "Test requires at least Vulkan 1.3"; + } + if (!AreRequiredExtensionsEnabled()) { + GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported."; + } + auto sync2_features = LvlInitStruct(); + GetPhysicalDeviceFeatures2(sync2_features); + if (!sync2_features.synchronization2) { + GTEST_SKIP() << "synchronization2 required"; + } + ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &sync2_features)); + if (!InitSwapchain()) { + GTEST_SKIP() << "Cannot create surface or swapchain"; + } + + const vk_testing::Semaphore acquire_semaphore(*m_device); + const vk_testing::Semaphore submit_semaphore(*m_device); + const auto swapchain_images = GetSwapchainImages(m_swapchain); + + uint32_t image_index = 0; + ASSERT_VK_SUCCESS( + vk::AcquireNextImageKHR(device(), m_swapchain, kWaitTimeout, acquire_semaphore, VK_NULL_HANDLE, &image_index)); + + auto image_barrier = LvlInitStruct(); + + // NOTE: VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT should be identical to VK_PIPELINE_STAGE_2_NONE but for some + // reason it does not. + // + // VK_PIPELINE_STAGE_2_NONE produces the first error + // reported here https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/6177. + // + // The second error happens either when VkPresentInfoKHR does not specify waiting semaphore, or + // for some reason when we use VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT instead of NONE, but in that + // case we don't get the first error. Because TOP_OF_PIPE and NONE in source stage should be + // the same it's one more evidence something is wrong. + + // image_barrier.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + image_barrier.srcStageMask = VK_PIPELINE_STAGE_2_NONE; + image_barrier.srcAccessMask = 0; + image_barrier.dstStageMask = VK_PIPELINE_STAGE_2_NONE; + image_barrier.dstAccessMask = 0; + image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + image_barrier.image = swapchain_images[image_index]; + image_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_barrier.subresourceRange.baseMipLevel = 0; + image_barrier.subresourceRange.levelCount = 1; + image_barrier.subresourceRange.baseArrayLayer = 0; + image_barrier.subresourceRange.layerCount = 1; + + auto dep_info = LvlInitStruct(); + dep_info.imageMemoryBarrierCount = 1; + dep_info.pImageMemoryBarriers = &image_barrier; + + m_commandBuffer->begin(); + vk::CmdPipelineBarrier2(*m_commandBuffer, &dep_info); + m_commandBuffer->end(); + + auto wait_info = LvlInitStruct(); + wait_info.semaphore = acquire_semaphore; + wait_info.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + auto command_buffer_info = LvlInitStruct(); + command_buffer_info.commandBuffer = *m_commandBuffer; + + auto signal_info = LvlInitStruct(); + signal_info.semaphore = submit_semaphore; + signal_info.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + auto submit = LvlInitStruct(); + submit.waitSemaphoreInfoCount = 1; + submit.pWaitSemaphoreInfos = &wait_info; + submit.commandBufferInfoCount = 1; + submit.pCommandBufferInfos = &command_buffer_info; + submit.signalSemaphoreInfoCount = 1; + submit.pSignalSemaphoreInfos = &signal_info; + ASSERT_VK_SUCCESS(vk::QueueSubmit2(m_device->m_queue, 1, &submit, VK_NULL_HANDLE)); + + auto present = LvlInitStruct(); + present.waitSemaphoreCount = 1; + present.pWaitSemaphores = &submit_semaphore.handle(); + present.swapchainCount = 1; + present.pSwapchains = &m_swapchain; + present.pImageIndices = &image_index; + ASSERT_VK_SUCCESS(vk::QueuePresentKHR(m_device->m_queue, &present)); + ASSERT_VK_SUCCESS(vk::QueueWaitIdle(m_device->m_queue)); +}