@@ -10738,6 +10738,70 @@ TEST_F(VkLayerTest, TwoCommandBufferUpdateBufferRaWDependencyMissingBarrier) {
1073810738
1073910739 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
1074010740}
10741+
10742+ TEST_F(VkLayerTest, TwoSecondaryCBUpdateBufferRaWDependencyMissingBarrier) {
10743+ TEST_DESCRIPTION(
10744+ "Two secondary command buffers executed back to back where first writes buffer then second uses buffer with no barrier "
10745+ "before use");
10746+
10747+ ASSERT_NO_FATAL_FAILURE(Init());
10748+ ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10749+
10750+ // Two secondary cmd buffers ([0] writes buffer, [1] reads it)
10751+ VkCommandBuffer secondary_cbs[2];
10752+ VkCommandBufferAllocateInfo alloc_info;
10753+ alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
10754+ alloc_info.pNext = nullptr;
10755+ alloc_info.commandBufferCount = 2;
10756+ alloc_info.commandPool = m_commandPool->handle();
10757+ alloc_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
10758+ vkAllocateCommandBuffers(m_device->device(), &alloc_info, secondary_cbs);
10759+
10760+ // First secondary command buffer will write to buffer
10761+ VkCommandBufferInheritanceInfo cbii = {};
10762+ cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
10763+ VkCommandBufferBeginInfo cbbi;
10764+ cbbi.pNext = nullptr;
10765+ cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
10766+ cbbi.pInheritanceInfo = &cbii;
10767+ cbbi.flags = 0;
10768+ vkBeginCommandBuffer(secondary_cbs[0], &cbbi);
10769+
10770+ VkDeviceSize buff_size = 1024;
10771+ uint32_t qfi = 0;
10772+ VkBufferCreateInfo bci = {};
10773+ bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10774+ bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
10775+ bci.size = buff_size;
10776+ bci.queueFamilyIndexCount = 1;
10777+ bci.pQueueFamilyIndices = &qfi;
10778+ VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
10779+ vk_testing::Buffer src_buffer; // We update into this buffer then use it as copy src
10780+ src_buffer.init(*m_device, bci, reqs);
10781+ bci.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
10782+ vk_testing::Buffer dst_buffer;
10783+ dst_buffer.init(*m_device, bci, reqs);
10784+
10785+ VkDeviceSize update_offset = 0;
10786+ uint32_t Data[] = {1, 2, 3, 4, 5, 6, 7, 8};
10787+ VkDeviceSize data_size = sizeof(Data) / sizeof(uint32_t);
10788+ vkCmdUpdateBuffer(secondary_cbs[0], src_buffer.handle(), update_offset, data_size, &Data);
10789+ vkEndCommandBuffer(secondary_cbs[0]);
10790+
10791+ // Second secondary CB uses prev buffer as src for copy
10792+ vkBeginCommandBuffer(secondary_cbs[1], &cbbi);
10793+ // Copy src buffer contents to dst buffer
10794+ VkBufferCopy buff_copy = {0, // srcOffset
10795+ 0, // dstOffset
10796+ buff_size};
10797+ vkCmdCopyBuffer(secondary_cbs[1], src_buffer.handle(), dst_buffer.handle(), 1, &buff_copy);
10798+ vkEndCommandBuffer(secondary_cbs[1]);
10799+ // Execute the secondary cmd buffers into the primary CB and verify that error occurs
10800+ m_commandBuffer->begin();
10801+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " causes a read after write conflict with ");
10802+ vkCmdExecuteCommands(m_commandBuffer->handle(), 2, secondary_cbs);
10803+ m_errorMonitor->VerifyFound();
10804+ }
1074110805#endif
1074210806TEST_F(VkLayerTest, ClearColorImageWithBadRange) {
1074310807 TEST_DESCRIPTION("Record clear color with an invalid VkImageSubresourceRange");
0 commit comments