Skip to content

Commit 5d9b634

Browse files
layers: Add VK_QCOM_multiview_per_view_viewports
1 parent 6dbf6cf commit 5d9b634

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

layers/core_checks/cc_pipeline_graphics.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ bool CoreChecks::ValidateGraphicsPipeline(const vvl::Pipeline &pipeline, const v
106106
}
107107
}
108108

109+
if (enabled_features.multiviewPerViewViewports) {
110+
skip |= ValidateMultiviewPerViewViewports(pipeline, *rp_state, create_info_loc);
111+
}
112+
109113
// Check for portability errors
110114
// Issue raised in https://gitlab.khronos.org/vulkan/vulkan/-/issues/3436
111115
// The combination of GPL/DynamicRendering and Portability has spec issues that need to be clarified
@@ -4269,6 +4273,47 @@ bool CoreChecks::ValidateMultiViewShaders(const vvl::Pipeline &pipeline, const L
42694273
return skip;
42704274
}
42714275

4276+
bool CoreChecks::ValidateMultiviewPerViewViewports(const vvl::Pipeline& pipeline, const vvl::RenderPass& rp_state,
4277+
const Location& create_info_loc) const {
4278+
bool skip = false;
4279+
const auto* viewport_state = pipeline.ViewportState();
4280+
if (!viewport_state) {
4281+
return skip;
4282+
}
4283+
4284+
if (!pipeline.IsDynamic(CB_DYNAMIC_STATE_VIEWPORT) && !pipeline.IsDynamic(CB_DYNAMIC_STATE_VIEWPORT_WITH_COUNT)) {
4285+
for (uint32_t i = 0; i < rp_state.create_info.subpassCount; i++) {
4286+
const uint32_t view_mask = rp_state.create_info.pSubpasses[i].viewMask;
4287+
const uint32_t msb = (uint32_t)MostSignificantBit(view_mask);
4288+
if (msb >= viewport_state->viewportCount) {
4289+
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07730", rp_state.Handle(),
4290+
create_info_loc.dot(Field::renderPass),
4291+
"was created with VkRenderPassMultiviewCreateInfo::pViewMask[%" PRIu32 "] of 0x%" PRIx32
4292+
" which most significant bit index (%" PRIu32
4293+
") is not less than pViewportState->viewportCount (%" PRIu32 ")",
4294+
i, view_mask, msb, viewport_state->viewportCount);
4295+
}
4296+
}
4297+
}
4298+
4299+
if (!pipeline.IsDynamic(CB_DYNAMIC_STATE_SCISSOR) && !pipeline.IsDynamic(CB_DYNAMIC_STATE_SCISSOR_WITH_COUNT)) {
4300+
for (uint32_t i = 0; i < rp_state.create_info.subpassCount; i++) {
4301+
const uint32_t view_mask = rp_state.create_info.pSubpasses[i].viewMask;
4302+
const uint32_t msb = (uint32_t)MostSignificantBit(view_mask);
4303+
if (msb >= viewport_state->scissorCount) {
4304+
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07731", rp_state.Handle(),
4305+
create_info_loc.dot(Field::renderPass),
4306+
"was created with VkRenderPassMultiviewCreateInfo::pViewMask[%" PRIu32 "] of 0x%" PRIx32
4307+
" which most significant bit index (%" PRIu32
4308+
") is not less than pViewportState->scissorCount (%" PRIu32 ")",
4309+
i, view_mask, msb, viewport_state->scissorCount);
4310+
}
4311+
}
4312+
}
4313+
4314+
return skip;
4315+
}
4316+
42724317
bool CoreChecks::ValidateDrawPipelineFramebuffer(const vvl::CommandBuffer &cb_state, const vvl::Pipeline &pipeline,
42734318
const vvl::DrawDispatchVuid &vuid) const {
42744319
bool skip = false;

layers/core_checks/core_validation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ class CoreChecks : public vvl::DeviceProxy {
244244
bool ValidateComputePipelineDerivatives(PipelineStates& pipeline_states, uint32_t pipe_index, const Location& loc) const;
245245
bool ValidateMultiViewShaders(const vvl::Pipeline& pipeline, const Location& multiview_loc, uint32_t view_mask,
246246
bool dynamic_rendering) const;
247+
bool ValidateMultiviewPerViewViewports(const vvl::Pipeline& pipeline, const vvl::RenderPass& rp_state,
248+
const Location& create_info_loc) const;
247249
bool ValidateGraphicsPipeline(const vvl::Pipeline& pipeline, const void* pipeline_ci_pnext,
248250
const Location& create_info_loc) const;
249251
bool ValidImageBufferQueue(const vvl::CommandBuffer& cb_state, const VulkanTypedHandle& object, uint32_t queueFamilyIndex,

tests/unit/multiview.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,3 +1340,53 @@ TEST_F(NegativeMultiview, MeshShader) {
13401340
pipe.CreateGraphicsPipeline();
13411341
m_errorMonitor->VerifyFound();
13421342
}
1343+
1344+
TEST_F(NegativeMultiview, MultiviewPerViewViewports) {
1345+
SetTargetApiVersion(VK_API_VERSION_1_1);
1346+
AddRequiredExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME);
1347+
AddRequiredExtensions(VK_QCOM_MULTIVIEW_PER_VIEW_VIEWPORTS_EXTENSION_NAME);
1348+
AddRequiredFeature(vkt::Feature::multiview);
1349+
AddRequiredFeature(vkt::Feature::multiviewPerViewViewports);
1350+
RETURN_IF_SKIP(Init());
1351+
InitRenderTarget();
1352+
1353+
uint32_t view_mask = 0x2u;
1354+
VkRenderPassMultiviewCreateInfo rp_mv_ci = vku::InitStructHelper();
1355+
rp_mv_ci.subpassCount = 1;
1356+
rp_mv_ci.pViewMasks = &view_mask;
1357+
1358+
RenderPassSingleSubpass rp(*this);
1359+
rp.AddAttachmentDescription(VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED);
1360+
rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL});
1361+
rp.AddColorAttachment(0);
1362+
rp.CreateRenderPass(&rp_mv_ci);
1363+
1364+
VkImageCreateInfo image_create_info = vku::InitStructHelper();
1365+
image_create_info.flags = 0u;
1366+
image_create_info.imageType = VK_IMAGE_TYPE_2D;
1367+
image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
1368+
image_create_info.extent = {32u, 32u, 1u};
1369+
image_create_info.mipLevels = 1u;
1370+
image_create_info.arrayLayers = 2u;
1371+
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1372+
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1373+
image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1374+
vkt::Image image(*m_device, image_create_info, vkt::set_layout);
1375+
vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
1376+
1377+
vkt::Framebuffer framebuffer(*m_device, rp, 1, &image_view.handle());
1378+
1379+
VkRenderPassBeginInfo render_pass_bi = vku::InitStructHelper();
1380+
render_pass_bi.renderPass = rp;
1381+
render_pass_bi.framebuffer = framebuffer;
1382+
render_pass_bi.renderArea.extent = {32u, 32u};
1383+
render_pass_bi.clearValueCount = 1u;
1384+
render_pass_bi.pClearValues = m_renderPassClearValues.data();
1385+
1386+
CreatePipelineHelper pipe(*this);
1387+
pipe.gp_ci_.renderPass = rp;
1388+
m_errorMonitor->SetDesiredError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07730");
1389+
m_errorMonitor->SetDesiredError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07731");
1390+
pipe.CreateGraphicsPipeline();
1391+
m_errorMonitor->VerifyFound();
1392+
}

0 commit comments

Comments
 (0)