tests:Add secondary cmd buffer image layout test

Add SecondaryCommandBufferImageLayoutTransitions positive test. This
performs an image layout transition in a secondary command buffer and
then in the primary cmd buffer.

There should be no errors, but previously validation did not correctly
handle layout transitions in a secondary command buffer.
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 55203fb..0ba0800 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -15351,6 +15351,92 @@
 //
 // These tests do not expect to encounter ANY validation errors pass only if this is true
 
+TEST_F(VkPositiveLayerTest, SecondaryCommandBufferImageLayoutTransitions) {
+    TEST_DESCRIPTION("Perform an image layout transition in a secondary command buffer followed "
+                     "by a transition in the primary.");
+    VkResult err;
+    m_errorMonitor->ExpectSuccess();
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+    // Allocate a secondary and primary cmd buffer
+    VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = m_commandPool;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
+    command_buffer_allocate_info.commandBufferCount = 1;
+
+    VkCommandBuffer secondary_command_buffer;
+    ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    VkCommandBuffer primary_command_buffer;
+    ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &primary_command_buffer));
+    VkCommandBufferBeginInfo command_buffer_begin_info = {};
+    VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
+    command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+    command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+    command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
+
+    err = vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
+    ASSERT_VK_SUCCESS(err);
+    VkImageObj image(m_device);
+    image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+    VkImageMemoryBarrier img_barrier = {};
+    img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
+    img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+    img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+    img_barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    img_barrier.image = image.handle();
+    img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+    img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+    img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    img_barrier.subresourceRange.baseArrayLayer = 0;
+    img_barrier.subresourceRange.baseMipLevel = 0;
+    img_barrier.subresourceRange.layerCount = 1;
+    img_barrier.subresourceRange.levelCount = 1;
+    vkCmdPipelineBarrier(secondary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
+                         0, nullptr, 1, &img_barrier);
+    err = vkEndCommandBuffer(secondary_command_buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    // Now update primary cmd buffer to execute secondary and transitions image
+    command_buffer_begin_info.pInheritanceInfo = nullptr;
+    err = vkBeginCommandBuffer(primary_command_buffer, &command_buffer_begin_info);
+    ASSERT_VK_SUCCESS(err);
+    vkCmdExecuteCommands(primary_command_buffer, 1, &secondary_command_buffer);
+    VkImageMemoryBarrier img_barrier2 = {};
+    img_barrier2.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    img_barrier2.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
+    img_barrier2.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+    img_barrier2.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    img_barrier2.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    img_barrier2.image = image.handle();
+    img_barrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+    img_barrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+    img_barrier2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    img_barrier2.subresourceRange.baseArrayLayer = 0;
+    img_barrier2.subresourceRange.baseMipLevel = 0;
+    img_barrier2.subresourceRange.layerCount = 1;
+    img_barrier2.subresourceRange.levelCount = 1;
+    vkCmdPipelineBarrier(primary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0,
+                         nullptr, 1, &img_barrier2);
+    err = vkEndCommandBuffer(primary_command_buffer);
+    ASSERT_VK_SUCCESS(err);
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &primary_command_buffer;
+    err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    ASSERT_VK_SUCCESS(err);
+    m_errorMonitor->VerifyNotFound();
+    err = vkDeviceWaitIdle(m_device->device());
+    ASSERT_VK_SUCCESS(err);
+    vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &secondary_command_buffer);
+    vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &primary_command_buffer);
+}
+
 // This is a positive test. No failures are expected.
 TEST_F(VkPositiveLayerTest, IgnoreUnrelatedDescriptor) {
     TEST_DESCRIPTION("Ensure that the vkUpdateDescriptorSets validation code "