Skip to content

Commit 48f83e2

Browse files
layers: Improve multiview dynamic state
1 parent 8194419 commit 48f83e2

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

layers/state_tracker/cmd_buffer_state.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2208,6 +2208,9 @@ std::string CommandBuffer::DescribeInvalidatedState(CBDynamicState dynamic_state
22082208
ss << " that didn't have " << DynamicStateToString(dynamic_state) << " and invalidated the prior "
22092209
<< DescribeDynamicStateCommand(dynamic_state) << " call)";
22102210
}
2211+
if (GetActiveSubpass() != 0 && active_render_pass->has_multiview_enabled) {
2212+
ss << " (When multiview is enabled, vkCmdNextSubpass will invalidate all dynamic state)";
2213+
}
22112214
return ss.str();
22122215
}
22132216

tests/unit/dynamic_state.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6214,3 +6214,101 @@ TEST_F(NegativeDynamicState, LineRasterization) {
62146214
m_command_buffer.EndRenderPass();
62156215
m_command_buffer.End();
62166216
}
6217+
6218+
TEST_F(NegativeDynamicState, MultiviewInvalidate) {
6219+
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/10699");
6220+
SetTargetApiVersion(VK_API_VERSION_1_1);
6221+
AddRequiredExtensions(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
6222+
AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
6223+
AddRequiredFeature(vkt::Feature::extendedDynamicState);
6224+
AddRequiredFeature(vkt::Feature::multiview);
6225+
RETURN_IF_SKIP(Init());
6226+
6227+
vkt::Image color_image(*m_device, m_width, m_height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
6228+
vkt::ImageView color_image_view = color_image.CreateView();
6229+
6230+
VkAttachmentDescription2 attachment_description = vku::InitStructHelper();
6231+
attachment_description.flags = 0u;
6232+
attachment_description.format = VK_FORMAT_R8G8B8A8_UNORM;
6233+
attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
6234+
attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6235+
attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
6236+
attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
6237+
attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
6238+
attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
6239+
attachment_description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
6240+
6241+
VkAttachmentReference2 attachment_reference = vku::InitStructHelper();
6242+
attachment_reference.attachment = 0u;
6243+
attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
6244+
6245+
VkSubpassDescription2 subpass_descriptions[2];
6246+
subpass_descriptions[0] = vku::InitStructHelper();
6247+
subpass_descriptions[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
6248+
subpass_descriptions[0].colorAttachmentCount = 1u;
6249+
subpass_descriptions[0].pColorAttachments = &attachment_reference;
6250+
subpass_descriptions[0].viewMask = 0x1u;
6251+
subpass_descriptions[1] = vku::InitStructHelper();
6252+
subpass_descriptions[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
6253+
subpass_descriptions[1].colorAttachmentCount = 1u;
6254+
subpass_descriptions[1].pColorAttachments = &attachment_reference;
6255+
subpass_descriptions[1].viewMask = 0x1u;
6256+
6257+
VkRenderPassCreateInfo2 rpci = vku::InitStructHelper();
6258+
rpci.attachmentCount = 1;
6259+
rpci.pAttachments = &attachment_description;
6260+
rpci.subpassCount = 2u;
6261+
rpci.pSubpasses = subpass_descriptions;
6262+
6263+
vkt::RenderPass render_pass(*m_device, rpci);
6264+
vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &color_image_view.handle(), m_width, m_height);
6265+
6266+
VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
6267+
6268+
VkPipelineViewportStateCreateInfo viewport_state_ci = vku::InitStructHelper();
6269+
viewport_state_ci.viewportCount = 1u;
6270+
viewport_state_ci.pViewports = &viewport;
6271+
6272+
CreatePipelineHelper pipe1(*this);
6273+
pipe1.AddDynamicState(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
6274+
pipe1.gp_ci_.renderPass = render_pass;
6275+
pipe1.gp_ci_.pViewportState = &viewport_state_ci;
6276+
pipe1.CreateGraphicsPipeline();
6277+
6278+
CreatePipelineHelper pipe2(*this);
6279+
pipe2.AddDynamicState(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
6280+
pipe2.gp_ci_.renderPass = render_pass;
6281+
pipe2.gp_ci_.pViewportState = &viewport_state_ci;
6282+
pipe2.gp_ci_.subpass = 1u;
6283+
pipe2.CreateGraphicsPipeline();
6284+
6285+
VkClearValue clear_value = {};
6286+
clear_value.color.float32[0] = 0.0f;
6287+
clear_value.color.float32[1] = 0.0f;
6288+
clear_value.color.float32[2] = 0.0f;
6289+
clear_value.color.float32[3] = 1.0f;
6290+
6291+
VkRenderPassBeginInfo render_pass_bi = vku::InitStructHelper();
6292+
render_pass_bi.renderPass = render_pass;
6293+
render_pass_bi.framebuffer = framebuffer;
6294+
render_pass_bi.renderArea = {{0, 0}, {m_width, m_height}};
6295+
render_pass_bi.clearValueCount = 1u;
6296+
render_pass_bi.pClearValues = &clear_value;
6297+
6298+
VkRect2D scissor = {{0, 0}, {64, 64}};
6299+
6300+
m_command_buffer.Begin();
6301+
m_command_buffer.BeginRenderPass(render_pass_bi);
6302+
vk::CmdSetScissorWithCountEXT(m_command_buffer, 1u, &scissor);
6303+
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1);
6304+
vk::CmdDraw(m_command_buffer, 3u, 1u, 0u, 0u);
6305+
// invalidated with multiview
6306+
vk::CmdNextSubpass(m_command_buffer, VK_SUBPASS_CONTENTS_INLINE);
6307+
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2);
6308+
// VUID-vkCmdDraw-scissorCount-03418
6309+
m_errorMonitor->SetDesiredError("When multiview is enabled, vkCmdNextSubpass will invalidate all dynamic state");
6310+
vk::CmdDraw(m_command_buffer, 3u, 1u, 0u, 0u);
6311+
m_errorMonitor->VerifyFound();
6312+
m_command_buffer.EndRenderPass();
6313+
m_command_buffer.End();
6314+
}

0 commit comments

Comments
 (0)