| /* |
| * Copyright (c) 2015-2025 The Khronos Group Inc. |
| * Copyright (c) 2015-2025 Valve Corporation |
| * Copyright (c) 2015-2025 LunarG, Inc. |
| * Copyright (c) 2015-2025 Google, Inc. |
| * Modifications Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| |
| #include <vulkan/vulkan_core.h> |
| #include "../framework/layer_validation_tests.h" |
| #include "../framework/descriptor_helper.h" |
| #include "../framework/pipeline_helper.h" |
| #include "../framework/render_pass_helper.h" |
| |
| class NegativeSecondaryCommandBuffer : public VkLayerTest {}; |
| |
| TEST_F(NegativeSecondaryCommandBuffer, AsPrimary) { |
| TEST_DESCRIPTION("Create a secondary command buffer and pass it to QueueSubmit."); |
| m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pCommandBuffers-00075"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(); |
| secondary.End(); |
| |
| m_default_queue->Submit(secondary); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, Barrier) { |
| TEST_DESCRIPTION("Add an invalid image barrier in a secondary command buffer"); |
| RETURN_IF_SKIP(Init()); |
| |
| // A renderpass with a single subpass that declared a self-dependency |
| RenderPassSingleSubpass rp(*this); |
| rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); |
| rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}); |
| rp.AddColorAttachment(0); |
| rp.AddSubpassDependency(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, |
| VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT); |
| rp.CreateRenderPass(); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView imageView = image.CreateView(); |
| // Second image that img_barrier will incorrectly use |
| vkt::Image image2(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| |
| vkt::Framebuffer fb(*m_device, rp, 1, &imageView.handle()); |
| |
| m_command_buffer.Begin(); |
| |
| VkRenderPassBeginInfo rpbi = |
| vku::InitStruct<VkRenderPassBeginInfo>(nullptr, rp.Handle(), fb.handle(), VkRect2D{{0, 0}, {32u, 32u}}, 0u, nullptr); |
| vk::CmdBeginRenderPass(m_command_buffer, &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| vkt::CommandPool pool(*m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); |
| vkt::CommandBuffer secondary(*m_device, pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, |
| rp, |
| 0, |
| VK_NULL_HANDLE, // Set to NULL FB handle intentionally to flesh out any errors |
| VK_FALSE, |
| 0, |
| 0}; |
| VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, |
| &cbii}; |
| vk::BeginCommandBuffer(secondary, &cbbi); |
| VkImageMemoryBarrier img_barrier = vku::InitStructHelper(); |
| img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; |
| img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; |
| img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| img_barrier.image = image2; // Image mis-matches with FB image |
| img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
| img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
| img_barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| vk::CmdPipelineBarrier(secondary, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, |
| VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); |
| secondary.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPipelineBarrier-image-04073"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, Sync2AsPrimary) { |
| TEST_DESCRIPTION("Create a secondary command buffer and pass it to QueueSubmit2KHR."); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(Init()); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferSubmitInfo-commandBuffer-03890"); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(); |
| secondary.End(); |
| |
| VkCommandBufferSubmitInfo cb_info = vku::InitStructHelper(); |
| cb_info.commandBuffer = secondary; |
| |
| VkSubmitInfo2 submit_info = vku::InitStructHelper(); |
| submit_info.commandBufferInfoCount = 1; |
| submit_info.pCommandBufferInfos = &cb_info; |
| |
| vk::QueueSubmit2KHR(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, RerecordedExplicitReset) { |
| #if defined(VVL_ENABLE_TSAN) |
| GTEST_SKIP() << "https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5965"; |
| #endif |
| |
| RETURN_IF_SKIP(Init()); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-recording"); |
| |
| // A pool we can reset in. |
| vkt::CommandPool pool(*m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); |
| vkt::CommandBuffer secondary(*m_device, pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| secondary.Begin(); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| |
| // rerecording of secondary |
| secondary.Reset(); // explicit reset here. |
| secondary.Begin(); |
| secondary.End(); |
| |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, RerecordedNoReset) { |
| #if defined(VVL_ENABLE_TSAN) |
| GTEST_SKIP() << "https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5965"; |
| #endif |
| |
| RETURN_IF_SKIP(Init()); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-recording"); |
| |
| // A pool we can reset in. |
| vkt::CommandPool pool(*m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); |
| vkt::CommandBuffer secondary(*m_device, pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| secondary.Begin(); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| |
| // rerecording of secondary |
| secondary.Begin(); // implicit reset in begin |
| secondary.End(); |
| |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CascadedInvalidation) { |
| RETURN_IF_SKIP(Init()); |
| |
| VkEventCreateInfo eci = vku::InitStructHelper(); |
| eci.flags = 0; |
| VkEvent event; |
| vk::CreateEvent(device(), &eci, nullptr, &event); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(); |
| vk::CmdSetEvent(secondary, event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_command_buffer.End(); |
| |
| // destroying the event should invalidate both primary and secondary CB |
| vk::DestroyEvent(device(), event, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070"); |
| m_default_queue->SubmitAndWait(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, ExecuteCommandsTo) { |
| TEST_DESCRIPTION("Attempt vkCmdExecuteCommands to a Secondary command buffer"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::CommandBuffer main_cb(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| vkt::CommandBuffer secondary_cb(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary_cb.Begin(); |
| secondary_cb.End(); |
| |
| main_cb.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-09375"); |
| vk::CmdExecuteCommands(main_cb.handle(), 1, &secondary_cb.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, SimultaneousUseTwoExecutes) { |
| RETURN_IF_SKIP(Init()); |
| |
| const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00092"; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceInfo inh = vku::InitStructHelper(); |
| VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh}; |
| |
| secondary.Begin(&cbbi); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->SetDesiredError(simultaneous_use_message); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, SimultaneousUseSingleExecute) { |
| RETURN_IF_SKIP(Init()); |
| |
| // variation on previous test executing the same CB twice in the same |
| // CmdExecuteCommands call |
| |
| const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00093"; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceInfo inh = vku::InitStructHelper(); |
| VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh}; |
| |
| secondary.Begin(&cbbi); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| VkCommandBuffer cbs[] = {secondary, secondary}; |
| m_errorMonitor->SetDesiredError(simultaneous_use_message); |
| vk::CmdExecuteCommands(m_command_buffer, 2, cbs); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, ExecuteDiffertQueueFlags) { |
| TEST_DESCRIPTION("Allocate a command buffer from two different queues and try to use a secondary command buffer"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| if (m_device->Physical().queue_properties_.size() < 2) { |
| GTEST_SKIP() << "Need 2 different queues for testing skipping."; |
| } |
| |
| // First two queue families |
| uint32_t queue_index_a = 0; |
| uint32_t queue_index_b = 1; |
| |
| VkCommandPoolCreateInfo pool_create_info = vku::InitStructHelper(); |
| pool_create_info.flags = 0; |
| |
| pool_create_info.queueFamilyIndex = queue_index_a; |
| vkt::CommandPool command_pool_a(*m_device, pool_create_info); |
| ASSERT_TRUE(command_pool_a.initialized()); |
| |
| pool_create_info.queueFamilyIndex = queue_index_b; |
| vkt::CommandPool command_pool_b(*m_device, pool_create_info); |
| ASSERT_TRUE(command_pool_b.initialized()); |
| |
| VkCommandBufferAllocateInfo command_buffer_allocate_info = vku::InitStructHelper(); |
| command_buffer_allocate_info.commandBufferCount = 1; |
| command_buffer_allocate_info.commandPool = command_pool_a; |
| command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; |
| vkt::CommandBuffer command_buffer_primary(*m_device, command_buffer_allocate_info); |
| ASSERT_TRUE(command_buffer_primary.initialized()); |
| |
| command_buffer_allocate_info.commandPool = command_pool_b; |
| command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; |
| vkt::CommandBuffer command_buffer_secondary(*m_device, command_buffer_allocate_info); |
| |
| VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(); |
| cmdbuff_ii.renderPass = m_renderPass; |
| cmdbuff_ii.subpass = 0; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.pInheritanceInfo = &cmdbuff_ii; |
| |
| // secondary |
| command_buffer_secondary.Begin(&begin_info); |
| command_buffer_secondary.End(); |
| |
| // Try using different pool's command buffer as secondary |
| command_buffer_primary.Begin(&begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-00094"); |
| vk::CmdExecuteCommands(command_buffer_primary, 1, &command_buffer_secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| command_buffer_primary.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, ExecuteUnrecorded) { |
| TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state"); |
| RETURN_IF_SKIP(Init()); |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| // never record secondary |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-00089"); |
| m_command_buffer.Begin(); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, ExecuteWithLayoutMismatch) { |
| TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB with incorrect initial layout."); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = vkt::Image::ImageCreateInfo2D( |
| 32, 1, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| |
| VkImageSubresourceRange image_sub_range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| |
| VkImageMemoryBarrier image_barrier = |
| image.ImageMemoryBarrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, image_sub_range); |
| |
| auto pipeline = [&image_barrier](const vkt::CommandBuffer &cb, VkImageLayout old_layout, VkImageLayout new_layout) { |
| image_barrier.oldLayout = old_layout; |
| image_barrier.newLayout = new_layout; |
| vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, |
| nullptr, 1, &image_barrier); |
| }; |
| |
| // Validate that mismatched use of image layout in secondary command buffer is caught at record time |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(); |
| pipeline(secondary, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| pipeline(m_command_buffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); |
| m_errorMonitor->SetDesiredError("UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.Reset(); |
| secondary.Reset(); |
| |
| // Validate that UNDEFINED doesn't false positive on us |
| secondary.Begin(); |
| pipeline(secondary, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| secondary.End(); |
| m_command_buffer.Begin(); |
| pipeline(m_command_buffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, ExecuteWithLayoutMismatchUseGenericLayout) { |
| // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7896 |
| TEST_DESCRIPTION("Check that generic layouts like VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL are reported correctly"); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| // Main command buffer transitions to READ_ONLY_OPTIMAL |
| VkImageMemoryBarrier2 layout_transition = vku::InitStructHelper(); |
| layout_transition.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; |
| layout_transition.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; |
| layout_transition.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| layout_transition.newLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL; |
| layout_transition.image = image; |
| layout_transition.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| |
| // Secondary command buffer expects sampled image to be in READ_ONLY_OPTIMAL |
| vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo()); |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}}); |
| descriptor_set.WriteDescriptorImageInfo(0, image_view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, |
| VK_IMAGE_LAYOUT_GENERAL); |
| descriptor_set.UpdateDescriptorSets(); |
| const char *cs_source = R"glsl( |
| #version 450 |
| layout(set=0, binding=0) uniform sampler2D color_image; |
| void main() { |
| vec4 data = texture(color_image, vec2(0)); |
| } |
| )glsl"; |
| CreateComputePipelineHelper cs_pipe(*this); |
| cs_pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT); |
| cs_pipe.pipeline_layout_ = vkt::PipelineLayout(*m_device, {&descriptor_set.layout_}); |
| cs_pipe.CreateComputePipeline(); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_COMPUTE, cs_pipe); |
| vk::CmdBindDescriptorSets(secondary, VK_PIPELINE_BIND_POINT_COMPUTE, cs_pipe.pipeline_layout_, 0, 1, &descriptor_set.set_, 0, |
| nullptr); |
| vk::CmdDispatch(secondary, 1, 1, 1); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.Barrier(layout_transition); |
| // Check that the error message reports image layout exactly as specified by the test (VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL) |
| // and not in the normalized form that is used by the implementation (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) |
| m_errorMonitor->SetDesiredErrorRegex("UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001", |
| "VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, RenderPassScope) { |
| TEST_DESCRIPTION( |
| "Test secondary buffers executed in wrong render pass scope wrt VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| vkt::CommandBuffer sec_cmdbuff_inside_rp(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| vkt::CommandBuffer sec_cmdbuff_outside_rp(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, // pNext |
| m_renderPass, |
| 0, // subpass |
| Framebuffer(), |
| }; |
| const VkCommandBufferBeginInfo cmdbuff_bi_tmpl = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| nullptr, // pNext |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii}; |
| |
| VkCommandBufferBeginInfo cmdbuff_inside_rp_bi = cmdbuff_bi_tmpl; |
| cmdbuff_inside_rp_bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| sec_cmdbuff_inside_rp.Begin(&cmdbuff_inside_rp_bi); |
| sec_cmdbuff_inside_rp.End(); |
| |
| VkCommandBufferBeginInfo cmdbuff_outside_rp_bi = cmdbuff_bi_tmpl; |
| cmdbuff_outside_rp_bi.flags &= ~VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| sec_cmdbuff_outside_rp.Begin(&cmdbuff_outside_rp_bi); |
| sec_cmdbuff_outside_rp.End(); |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-00100"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &sec_cmdbuff_inside_rp.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| VkRenderPassBeginInfo rp_bi = vku::InitStruct<VkRenderPassBeginInfo>( |
| nullptr, m_renderPass, Framebuffer(), VkRect2D{{0, 0}, {32u, 32u}}, static_cast<uint32_t>(m_renderPassClearValues.size()), |
| m_renderPassClearValues.data()); |
| vk::CmdBeginRenderPass(m_command_buffer, &rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-00096"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &sec_cmdbuff_outside_rp.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, ClearColorAttachmentsRenderArea) { |
| TEST_DESCRIPTION( |
| "Create a secondary command buffer with CmdClearAttachments call that has a rect outside of renderPass renderArea"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkCommandBufferAllocateInfo command_buffer_allocate_info = vku::InitStructHelper(); |
| command_buffer_allocate_info.commandPool = m_command_pool; |
| command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; |
| command_buffer_allocate_info.commandBufferCount = 1; |
| |
| vkt::CommandBuffer secondary_command_buffer(*m_device, command_buffer_allocate_info); |
| VkCommandBufferInheritanceInfo command_buffer_inheritance_info = vku::InitStructHelper(); |
| command_buffer_inheritance_info.renderPass = m_renderPass; |
| command_buffer_inheritance_info.framebuffer = Framebuffer(); |
| |
| VkCommandBufferBeginInfo command_buffer_begin_info = vku::InitStructHelper(); |
| command_buffer_begin_info.flags = |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info; |
| |
| secondary_command_buffer.Begin(&command_buffer_begin_info); |
| |
| VkClearAttachment color_attachment; |
| color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| color_attachment.clearValue.color.float32[0] = 0; |
| color_attachment.clearValue.color.float32[1] = 0; |
| color_attachment.clearValue.color.float32[2] = 0; |
| color_attachment.clearValue.color.float32[3] = 0; |
| color_attachment.colorAttachment = 0; |
| // x extent of 257 exceeds render area of 256 |
| VkClearRect clear_rect = {{{0, 0}, {257, 32}}, 0, 1}; |
| vk::CmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| secondary_command_buffer.End(); |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-pRects-00016"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_command_buffer.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, RenderPassContentsFirstSubpass) { |
| TEST_DESCRIPTION( |
| "Test CmdExecuteCommands inside a render pass begun with CmdBeginRenderPass that hasn't set " |
| "VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, // pNext |
| m_renderPass, |
| 0, // subpass |
| Framebuffer(), |
| }; |
| |
| VkCommandBufferBeginInfo cmdbuff__bi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| nullptr, // pNext |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii}; |
| cmdbuff__bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| secondary.Begin(&cmdbuff__bi); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPass, Framebuffer(), 32, 32, m_renderPassClearValues.size(), |
| m_renderPassClearValues.data()); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-contents-09680"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, RenderPassContentsNotFirstSubpass) { |
| TEST_DESCRIPTION( |
| "Test CmdExecuteCommands inside a render pass begun with vkCmdNextSubpass that hasn't set " |
| "VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS"); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkAttachmentDescription2 attach_desc = vku::InitStructHelper(); |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| std::array subpasses = {vku::InitStruct<VkSubpassDescription2>(), vku::InitStruct<VkSubpassDescription2>()}; |
| |
| VkRenderPassCreateInfo2 render_pass_ci = vku::InitStructHelper(); |
| render_pass_ci.subpassCount = subpasses.size(); |
| render_pass_ci.pSubpasses = subpasses.data(); |
| render_pass_ci.attachmentCount = 1; |
| render_pass_ci.pAttachments = &attach_desc; |
| |
| vkt::RenderPass rp(*m_device, render_pass_ci); |
| |
| // A compatible framebuffer. |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView view = image.CreateView(); |
| vkt::Framebuffer fb(*m_device, rp, 1, &view.handle()); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, // pNext |
| rp, |
| 1, // subpass |
| fb, |
| }; |
| |
| VkCommandBufferBeginInfo cmdbuff__bi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| nullptr, // pNext |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii}; |
| cmdbuff__bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| secondary.Begin(&cmdbuff__bi); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp, fb, 32, 32, m_renderPassClearValues.size(), m_renderPassClearValues.data()); |
| m_command_buffer.NextSubpass(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-None-09681"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, ExecuteCommandsSubpassIndices) { |
| TEST_DESCRIPTION("Test invalid subpass when calling CmdExecuteCommands"); |
| RETURN_IF_SKIP(Init()); |
| |
| // A renderpass with two subpasses, both writing the same attachment. |
| VkAttachmentDescription attach[] = { |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| VkSubpassDescription subpasses[] = { |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, |
| }; |
| |
| VkSubpassDependency dependencies = { |
| 0, // srcSubpass |
| 1, // dstSubpass |
| VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // srcStageMask |
| VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // dstStageMask |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask |
| 0, // dependencyFlags |
| }; |
| |
| VkRenderPassCreateInfo rpci = vku::InitStructHelper(); |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = attach; |
| rpci.subpassCount = 2; |
| rpci.pSubpasses = subpasses; |
| rpci.dependencyCount = 1; |
| rpci.pDependencies = &dependencies; |
| vkt::RenderPass render_pass(*m_device, rpci); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView imageView = image.CreateView(); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1, &imageView.handle()); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, // pNext |
| render_pass, |
| 1, // subpass |
| framebuffer, |
| }; |
| |
| VkCommandBufferBeginInfo cmdbuff__bi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| nullptr, // pNext |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii}; |
| cmdbuff__bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| secondary.Begin(&cmdbuff__bi); |
| secondary.End(); |
| |
| const auto rp_bi = vku::InitStruct<VkRenderPassBeginInfo>(nullptr, render_pass.handle(), framebuffer.handle(), |
| VkRect2D{{0, 0}, {32u, 32u}}, 0u, nullptr); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-06019"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, IncompatibleRenderPassesInExecuteCommands) { |
| TEST_DESCRIPTION("Test invalid subpass when calling CmdExecuteCommands"); |
| RETURN_IF_SKIP(Init()); |
| |
| // A renderpass with two subpasses, both writing the same attachment. |
| VkAttachmentDescription attach[] = { |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| VkSubpassDescription subpasses[] = { |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, |
| }; |
| |
| VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; |
| vkt::RenderPass render_pass_1(*m_device, rpci); |
| rpci.subpassCount = 2; |
| vkt::RenderPass render_pass_2(*m_device, rpci); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView imageView = image.CreateView(); |
| vkt::Framebuffer framebuffer(*m_device, render_pass_1, 1, &imageView.handle()); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, // pNext |
| render_pass_2, |
| 0, // subpass |
| VK_NULL_HANDLE, |
| }; |
| |
| VkCommandBufferBeginInfo cmdbuff_bi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| nullptr, // pNext |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii}; |
| cmdbuff_bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| secondary.Begin(&cmdbuff_bi); |
| secondary.End(); |
| |
| const auto rp_bi = vku::InitStruct<VkRenderPassBeginInfo>(nullptr, render_pass_1.handle(), framebuffer.handle(), |
| VkRect2D{{0, 0}, {32u, 32u}}, 0u, nullptr); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pBeginInfo-06020"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CommandBufferInheritanceInfo) { |
| TEST_DESCRIPTION("Test invalid command buffer begin inheritance info."); |
| AddRequiredFeature(vkt::Feature::inheritedQueries); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkBeginCommandBuffer-commandBuffer-00051"); |
| vk::BeginCommandBuffer(secondary, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(); |
| inheritance_info.queryFlags = VK_QUERY_CONTROL_PRECISE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkBeginCommandBuffer-commandBuffer-00052"); |
| vk::BeginCommandBuffer(secondary, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, NestedCommandBufferRendering) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::nestedCommandBuffer); |
| |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| vkt::CommandBuffer secondary1(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| vkt::CommandBuffer secondary2(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceRenderingInfo cbiri = vku::InitStructHelper(); |
| cbiri.colorAttachmentCount = 1; |
| cbiri.pColorAttachmentFormats = &m_render_target_fmt; |
| cbiri.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| |
| VkCommandBufferInheritanceInfo cbii = vku::InitStructHelper(&cbiri); |
| cbii.occlusionQueryEnable = VK_FALSE; |
| |
| VkCommandBufferBeginInfo cbbi = vku::InitStructHelper(); |
| cbbi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cbbi.pInheritanceInfo = &cbii; |
| |
| secondary1.Begin(&cbbi); |
| secondary1.End(); |
| |
| secondary2.Begin(&cbbi); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-nestedCommandBufferRendering-09377"); |
| vk::CmdExecuteCommands(secondary2, 1u, &secondary1.handle()); |
| m_errorMonitor->VerifyFound(); |
| secondary2.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, NestedCommandBufferSimultaneousUse) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::nestedCommandBuffer); |
| AddRequiredFeature(vkt::Feature::nestedCommandBufferRendering); |
| |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| vkt::CommandBuffer secondary1(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| vkt::CommandBuffer secondary2(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceRenderingInfo cbiri = vku::InitStructHelper(); |
| cbiri.colorAttachmentCount = 1; |
| cbiri.pColorAttachmentFormats = &m_render_target_fmt; |
| cbiri.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| |
| VkCommandBufferInheritanceInfo cbii = vku::InitStructHelper(&cbiri); |
| cbii.occlusionQueryEnable = VK_FALSE; |
| |
| VkCommandBufferBeginInfo cbbi = vku::InitStructHelper(); |
| cbbi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; |
| cbbi.pInheritanceInfo = &cbii; |
| |
| secondary1.Begin(&cbbi); |
| secondary1.End(); |
| |
| secondary2.Begin(&cbbi); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-nestedCommandBufferSimultaneousUse-09378"); |
| vk::CmdExecuteCommands(secondary2, 1u, &secondary1.handle()); |
| m_errorMonitor->VerifyFound(); |
| secondary2.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, MaxCommandBufferNestingLevel) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::nestedCommandBuffer); |
| AddRequiredFeature(vkt::Feature::nestedCommandBufferRendering); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkPhysicalDeviceNestedCommandBufferPropertiesEXT nested_cb_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(nested_cb_props); |
| if (nested_cb_props.maxCommandBufferNestingLevel != 2) { |
| GTEST_SKIP() << "needs maxCommandBufferNestingLevel to be 2"; |
| } |
| |
| vkt::CommandBuffer secondary1(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| vkt::CommandBuffer secondary2(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| vkt::CommandBuffer secondary3(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| vkt::CommandBuffer secondary4(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceRenderingInfo cbiri = vku::InitStructHelper(); |
| cbiri.colorAttachmentCount = 1; |
| cbiri.pColorAttachmentFormats = &m_render_target_fmt; |
| cbiri.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| |
| VkCommandBufferInheritanceInfo cbii = vku::InitStructHelper(&cbiri); |
| cbii.occlusionQueryEnable = VK_FALSE; |
| |
| VkCommandBufferBeginInfo cbbi = vku::InitStructHelper(); |
| cbbi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cbbi.pInheritanceInfo = &cbii; |
| |
| secondary1.Begin(&cbbi); |
| secondary1.End(); |
| |
| secondary2.Begin(&cbbi); |
| vk::CmdExecuteCommands(secondary2, 1u, &secondary1.handle()); |
| secondary2.End(); |
| |
| secondary3.Begin(&cbbi); |
| vk::CmdExecuteCommands(secondary3, 1u, &secondary2.handle()); |
| vk::CmdExecuteCommands(secondary3, 1u, &secondary1.handle()); |
| secondary3.End(); |
| |
| secondary4.Begin(&cbbi); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-nestedCommandBuffer-09376"); |
| vk::CmdExecuteCommands(secondary4, 1u, &secondary3.handle()); |
| m_errorMonitor->VerifyFound(); |
| secondary4.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, NestedDrawWithoutInline) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::nestedCommandBuffer); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(); |
| pipeline_rendering_info.colorAttachmentCount = 1; |
| pipeline_rendering_info.pColorAttachmentFormats = &color_format; |
| |
| CreatePipelineHelper pipe(*this, &pipeline_rendering_info); |
| pipe.CreateGraphicsPipeline(); |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| |
| vkt::Image color_image(*m_device, 32, 32, color_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = color_image_view; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT; |
| begin_rendering_info.colorAttachmentCount = 1; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.renderArea = {{0, 0}, {1, 1}}; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(&cmdbuff_bi); |
| secondary.BeginRendering(begin_rendering_info); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-flags-10582"); |
| vk::CmdDraw(secondary, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| secondary.EndRendering(); |
| secondary.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, MissingInheritedQueriesFeature) { |
| AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery); |
| RETURN_IF_SKIP(Init()); |
| |
| VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 1); |
| qpci.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT; |
| vkt::QueryPool query_pool(*m_device, qpci); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(); |
| inheritance_info.pipelineStatistics = qpci.pipelineStatistics; |
| |
| VkCommandBufferBeginInfo seconary_begin_info = vku::InitStructHelper(); |
| seconary_begin_info.pInheritanceInfo = &inheritance_info; |
| secondary.Begin(&seconary_begin_info); |
| secondary.End(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdResetQueryPool(m_command_buffer, query_pool, 0u, 1u); |
| vk::CmdBeginQuery(m_command_buffer, query_pool, 0u, 0u); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-00101"); |
| vk::CmdExecuteCommands(m_command_buffer, 1u, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndQuery(m_command_buffer, query_pool, 0u); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, MissingPipelineFormat) { |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::dynamicRenderingUnusedAttachments); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat undefined = VK_FORMAT_UNDEFINED; |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(); |
| pipeline_rendering_info.colorAttachmentCount = 1u; |
| pipeline_rendering_info.pColorAttachmentFormats = &undefined; |
| |
| VkPipelineColorBlendAttachmentState color_blend_attachment_state = DefaultColorBlendAttachmentState(); |
| color_blend_attachment_state.colorWriteMask = |
| VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; |
| |
| VkPipelineColorBlendStateCreateInfo color_blend_state = vku::InitStructHelper(); |
| color_blend_state.attachmentCount = 1u; |
| color_blend_state.pAttachments = &color_blend_attachment_state; |
| |
| CreatePipelineHelper pipe(*this, &pipeline_rendering_info); |
| pipe.cb_ci_ = color_blend_state; |
| pipe.CreateGraphicsPipeline(); |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(); |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(&cmdbuff_bi); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-pColorAttachments-08963"); |
| vk::CmdDraw(secondary, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| secondary.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, MissingPipelineFormatDepth) { |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::dynamicRenderingUnusedAttachments); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat undefined = VK_FORMAT_UNDEFINED; |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| VkFormat ds_format = FindSupportedDepthStencilFormat(Gpu()); |
| |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(); |
| pipeline_rendering_info.colorAttachmentCount = 1u; |
| pipeline_rendering_info.pColorAttachmentFormats = &color_format; |
| pipeline_rendering_info.depthAttachmentFormat = undefined; |
| pipeline_rendering_info.stencilAttachmentFormat = ds_format; |
| |
| VkPipelineDepthStencilStateCreateInfo ds_state = vku::InitStructHelper(); |
| ds_state.depthTestEnable = VK_TRUE; |
| ds_state.depthWriteEnable = VK_TRUE; |
| ds_state.stencilTestEnable = VK_FALSE; |
| |
| CreatePipelineHelper pipe(*this, &pipeline_rendering_info); |
| pipe.ds_ci_ = ds_state; |
| pipe.CreateGraphicsPipeline(); |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(); |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.depthAttachmentFormat = ds_format; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(&cmdbuff_bi); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-pDepthAttachment-08964"); |
| vk::CmdDraw(secondary, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| secondary.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, MissingPipelineFormatCount) { |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(); |
| pipeline_rendering_info.colorAttachmentCount = 1u; |
| pipeline_rendering_info.pColorAttachmentFormats = &color_format; |
| |
| CreatePipelineHelper pipe(*this, &pipeline_rendering_info); |
| pipe.CreateGraphicsPipeline(); |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(); |
| inheritance_rendering_info.colorAttachmentCount = 0; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(&cmdbuff_bi); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-colorAttachmentCount-06179"); |
| vk::CmdDraw(secondary, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| secondary.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, MissingSimultaniousUseBit) { |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(); |
| secondary.End(); |
| |
| vkt::CommandBuffer primary(*m_device, m_command_pool); |
| primary.Begin(VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT); |
| vk::CmdExecuteCommands(primary, 1u, &secondary.handle()); |
| primary.End(); |
| |
| m_command_buffer.Begin(VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT); |
| vk::CmdExecuteCommands(m_command_buffer, 1u, &secondary.handle()); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00073"); |
| m_default_queue->Submit(primary); |
| m_errorMonitor->VerifyFound(); |
| |
| m_default_queue->Wait(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CustomResolveCreateInfoFormats) { |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM; |
| VkCustomResolveCreateInfoEXT custom_resolve_info = vku::InitStructHelper(); |
| custom_resolve_info.customResolve = VK_TRUE; |
| custom_resolve_info.colorAttachmentCount = 1; |
| custom_resolve_info.pColorAttachmentFormats = &color_format; |
| custom_resolve_info.depthAttachmentFormat = VK_FORMAT_B8G8R8A8_UNORM; |
| custom_resolve_info.stencilAttachmentFormat = VK_FORMAT_B8G8R8A8_UNORM; |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(&custom_resolve_info); |
| inheritance_rendering_info.flags = VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCustomResolveCreateInfoEXT-depthAttachmentFormat-11508"); |
| m_errorMonitor->SetDesiredError("VUID-VkCustomResolveCreateInfoEXT-stencilAttachmentFormat-11511"); |
| vk::BeginCommandBuffer(secondary, &cmdbuff_bi); |
| m_errorMonitor->VerifyFound(); |
| |
| if (FormatIsSupported(Gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TILING_OPTIMAL)) { |
| color_format = VK_FORMAT_D24_UNORM_S8_UINT; |
| custom_resolve_info.depthAttachmentFormat = VK_FORMAT_D24_UNORM_S8_UINT; |
| custom_resolve_info.stencilAttachmentFormat = VK_FORMAT_D24_UNORM_S8_UINT; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferInheritanceRenderingInfo-pColorAttachmentFormats-06492"); |
| m_errorMonitor->SetDesiredError("VUID-VkCustomResolveCreateInfoEXT-pColorAttachmentFormats-11510"); |
| vk::BeginCommandBuffer(secondary, &cmdbuff_bi); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CustomResolveMaxColorAttachments) { |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| RETURN_IF_SKIP(Init()); |
| |
| const uint32_t limit = m_device->Physical().limits_.maxColorAttachments + 1; |
| std::vector<VkFormat> color_formats; |
| for (uint32_t i = 0; i < limit; i++) { |
| color_formats.push_back(VK_FORMAT_B8G8R8A8_UNORM); |
| } |
| VkCustomResolveCreateInfoEXT custom_resolve_info = vku::InitStructHelper(); |
| custom_resolve_info.customResolve = VK_TRUE; |
| custom_resolve_info.colorAttachmentCount = limit; |
| custom_resolve_info.pColorAttachmentFormats = color_formats.data(); |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(&custom_resolve_info); |
| inheritance_rendering_info.flags = VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = color_formats.data(); |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCustomResolveCreateInfoEXT-colorAttachmentCount-11507"); |
| vk::BeginCommandBuffer(secondary, &cmdbuff_bi); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CustomResolveExecuteCommands) { |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(); |
| inheritance_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT | VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| |
| vkt::CommandBuffer secondary_normal(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary_normal.Begin(&cmdbuff_bi); |
| secondary_normal.End(); |
| |
| VkCustomResolveCreateInfoEXT custom_resolve_info = vku::InitStructHelper(); |
| custom_resolve_info.customResolve = VK_FALSE; |
| custom_resolve_info.colorAttachmentCount = 1; |
| custom_resolve_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.pNext = &custom_resolve_info; |
| inheritance_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT; |
| |
| vkt::CommandBuffer secondary_custom(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary_custom.Begin(&cmdbuff_bi); |
| secondary_custom.End(); |
| |
| VkImageCreateInfo image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, color_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| vkt::Image color_image(*m_device, image_ci); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image resolve_image(*m_device, image_ci); |
| vkt::ImageView resolve_image_view = resolve_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = color_image_view; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_CUSTOM_BIT_EXT; |
| color_attachment.resolveImageView = resolve_image_view; |
| color_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT | VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| begin_rendering_info.colorAttachmentCount = 1; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.renderArea = {{0, 0}, {1, 1}}; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-11500"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_normal.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| |
| begin_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-11501"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_custom.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CustomResolveExecuteCommands2) { |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkCustomResolveCreateInfoEXT custom_resolve_info = vku::InitStructHelper(); |
| custom_resolve_info.customResolve = VK_FALSE; |
| custom_resolve_info.colorAttachmentCount = 1; |
| custom_resolve_info.pColorAttachmentFormats = &color_format; |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(&custom_resolve_info); |
| inheritance_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT | VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| |
| vkt::CommandBuffer secondary_false(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary_false.Begin(&cmdbuff_bi); |
| secondary_false.End(); |
| |
| custom_resolve_info.customResolve = VK_TRUE; |
| vkt::CommandBuffer secondary_true(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary_true.Begin(&cmdbuff_bi); |
| secondary_true.End(); |
| |
| VkImageCreateInfo image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, color_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| vkt::Image color_image(*m_device, image_ci); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image resolve_image(*m_device, image_ci); |
| vkt::ImageView resolve_image_view = resolve_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = color_image_view; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_CUSTOM_BIT_EXT; |
| color_attachment.resolveImageView = resolve_image_view; |
| color_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT | VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| begin_rendering_info.colorAttachmentCount = 1; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.renderArea = {{0, 0}, {1, 1}}; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-11503"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_true.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| VkBeginCustomResolveInfoEXT begin_resolve_info = vku::InitStructHelper(); |
| vk::CmdBeginCustomResolveEXT(m_command_buffer, &begin_resolve_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-resolveImageView-11526"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-11502"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_false.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CustomResolveDynamicRendering) { |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkCustomResolveCreateInfoEXT custom_resolve_info = vku::InitStructHelper(); |
| custom_resolve_info.customResolve = VK_TRUE; |
| custom_resolve_info.colorAttachmentCount = 1; |
| custom_resolve_info.pColorAttachmentFormats = &color_format; |
| |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(&custom_resolve_info); |
| pipeline_rendering_info.colorAttachmentCount = 1; |
| pipeline_rendering_info.pColorAttachmentFormats = &color_format; |
| |
| CreatePipelineHelper pipe(*this, &pipeline_rendering_info); |
| pipe.CreateGraphicsPipeline(); |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(&custom_resolve_info); |
| inheritance_rendering_info.flags = VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(&cmdbuff_bi); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| vk::CmdDraw(secondary, 3, 1, 0, 0); |
| secondary.End(); |
| |
| VkImageCreateInfo image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, color_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| vkt::Image color_image(*m_device, image_ci); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image resolve_image(*m_device, image_ci); |
| vkt::ImageView resolve_image_view = resolve_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = color_image_view; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_CUSTOM_BIT_EXT; |
| color_attachment.resolveImageView = resolve_image_view; |
| color_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT | VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| begin_rendering_info.colorAttachmentCount = 1; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.renderArea = {{0, 0}, {1, 1}}; |
| VkBeginCustomResolveInfoEXT begin_resolve_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| vk::CmdBeginCustomResolveEXT(m_command_buffer, &begin_resolve_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-resolveImageView-11526"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CustomResolveDraw) { |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkCustomResolveCreateInfoEXT custom_resolve_info = vku::InitStructHelper(); |
| custom_resolve_info.customResolve = VK_TRUE; |
| custom_resolve_info.colorAttachmentCount = 1; |
| custom_resolve_info.pColorAttachmentFormats = &color_format; |
| |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(&custom_resolve_info); |
| pipeline_rendering_info.colorAttachmentCount = 1; |
| pipeline_rendering_info.pColorAttachmentFormats = &color_format; |
| |
| CreatePipelineHelper pipe(*this, &pipeline_rendering_info); |
| pipe.CreateGraphicsPipeline(); |
| |
| custom_resolve_info.customResolve = VK_FALSE; |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(&custom_resolve_info); |
| inheritance_rendering_info.flags = VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| inheritance_rendering_info.colorAttachmentCount = 1; |
| inheritance_rendering_info.pColorAttachmentFormats = &color_format; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(&cmdbuff_bi); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-customResolve-11525"); |
| vk::CmdDraw(secondary, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| secondary.End(); |
| } |
| |
| TEST_F(NegativeSecondaryCommandBuffer, CustomResolveDynamicRenderingInputAttachmentIndex) { |
| TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/11099"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::dynamicRenderingLocalRead); |
| RETURN_IF_SKIP(Init()); |
| |
| const VkFormat depth_format = FindSupportedDepthOnlyFormat(Gpu()); |
| |
| VkCustomResolveCreateInfoEXT custom_resolve_info = vku::InitStructHelper(); |
| custom_resolve_info.customResolve = VK_TRUE; |
| custom_resolve_info.colorAttachmentCount = 0; |
| custom_resolve_info.pColorAttachmentFormats = nullptr; |
| custom_resolve_info.depthAttachmentFormat = depth_format; |
| custom_resolve_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED; |
| |
| uint32_t zero = 0; |
| VkRenderingInputAttachmentIndexInfo input_info = vku::InitStructHelper(&custom_resolve_info); |
| input_info.colorAttachmentCount = 0; |
| input_info.pColorAttachmentInputIndices = nullptr; |
| input_info.pDepthInputAttachmentIndex = &zero; |
| input_info.pStencilInputAttachmentIndex = nullptr; |
| |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(&input_info); |
| pipeline_rendering_info.colorAttachmentCount = 0; |
| pipeline_rendering_info.pColorAttachmentFormats = nullptr; |
| pipeline_rendering_info.depthAttachmentFormat = depth_format; |
| pipeline_rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED; |
| |
| CreatePipelineHelper pipe(*this, &pipeline_rendering_info); |
| pipe.ds_ci_ = vku::InitStructHelper(); |
| pipe.CreateGraphicsPipeline(); |
| |
| input_info.pDepthInputAttachmentIndex = nullptr; |
| |
| VkCommandBufferInheritanceRenderingInfo inheritance_rendering_info = vku::InitStructHelper(&input_info); |
| inheritance_rendering_info.flags = VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT; |
| inheritance_rendering_info.colorAttachmentCount = 0; |
| inheritance_rendering_info.pColorAttachmentFormats = nullptr; |
| inheritance_rendering_info.depthAttachmentFormat = depth_format; |
| inheritance_rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED; |
| inheritance_rendering_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
| |
| const VkCommandBufferInheritanceInfo cmdbuff_ii = vku::InitStructHelper(&inheritance_rendering_info); |
| VkCommandBufferBeginInfo cmdbuff_bi = vku::InitStructHelper(); |
| cmdbuff_bi.pInheritanceInfo = &cmdbuff_ii; |
| cmdbuff_bi.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| |
| vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| secondary.Begin(&cmdbuff_bi); |
| vk::CmdBindPipeline(secondary, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10927"); |
| vk::CmdDraw(secondary, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| secondary.End(); |
| } |