Skip to content

Commit 5f28f2d

Browse files
layers: Add VK_QCOM_multiview_per_view_viewports
1 parent e4c6869 commit 5f28f2d

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 && rp_state->has_multiview_enabled) {
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
@@ -4268,6 +4272,47 @@ bool CoreChecks::ValidateMultiViewShaders(const vvl::Pipeline &pipeline, const L
42684272
return skip;
42694273
}
42704274

4275+
bool CoreChecks::ValidateMultiviewPerViewViewports(const vvl::Pipeline& pipeline, const vvl::RenderPass& rp_state,
4276+
const Location& create_info_loc) const {
4277+
bool skip = false;
4278+
const auto* viewport_state = pipeline.ViewportState();
4279+
if (!viewport_state) {
4280+
return skip;
4281+
}
4282+
4283+
if (!pipeline.IsDynamic(CB_DYNAMIC_STATE_VIEWPORT) && !pipeline.IsDynamic(CB_DYNAMIC_STATE_VIEWPORT_WITH_COUNT)) {
4284+
for (uint32_t i = 0; i < rp_state.create_info.subpassCount; i++) {
4285+
const uint32_t view_mask = rp_state.create_info.pSubpasses[i].viewMask;
4286+
const uint32_t msb = (uint32_t)MostSignificantBit(view_mask);
4287+
if (msb >= viewport_state->viewportCount) {
4288+
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07730", rp_state.Handle(),
4289+
create_info_loc.dot(Field::renderPass),
4290+
"was created with VkRenderPassMultiviewCreateInfo::pViewMask[%" PRIu32 "] of 0x%" PRIx32
4291+
" which most significant bit index (%" PRIu32
4292+
") is not less than pViewportState->viewportCount (%" PRIu32 ")",
4293+
i, view_mask, msb, viewport_state->viewportCount);
4294+
}
4295+
}
4296+
}
4297+
4298+
if (!pipeline.IsDynamic(CB_DYNAMIC_STATE_SCISSOR) && !pipeline.IsDynamic(CB_DYNAMIC_STATE_SCISSOR_WITH_COUNT)) {
4299+
for (uint32_t i = 0; i < rp_state.create_info.subpassCount; i++) {
4300+
const uint32_t view_mask = rp_state.create_info.pSubpasses[i].viewMask;
4301+
const uint32_t msb = (uint32_t)MostSignificantBit(view_mask);
4302+
if (msb >= viewport_state->scissorCount) {
4303+
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07731", rp_state.Handle(),
4304+
create_info_loc.dot(Field::renderPass),
4305+
"was created with VkRenderPassMultiviewCreateInfo::pViewMask[%" PRIu32 "] of 0x%" PRIx32
4306+
" which most significant bit index (%" PRIu32
4307+
") is not less than pViewportState->scissorCount (%" PRIu32 ")",
4308+
i, view_mask, msb, viewport_state->scissorCount);
4309+
}
4310+
}
4311+
}
4312+
4313+
return skip;
4314+
}
4315+
42714316
bool CoreChecks::ValidateDrawPipelineFramebuffer(const vvl::CommandBuffer &cb_state, const vvl::Pipeline &pipeline,
42724317
const vvl::DrawDispatchVuid &vuid) const {
42734318
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
@@ -1432,3 +1432,53 @@ TEST_F(NegativeMultiview, MeshShader) {
14321432
pipe.CreateGraphicsPipeline();
14331433
m_errorMonitor->VerifyFound();
14341434
}
1435+
1436+
TEST_F(NegativeMultiview, MultiviewPerViewViewports) {
1437+
SetTargetApiVersion(VK_API_VERSION_1_1);
1438+
AddRequiredExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME);
1439+
AddRequiredExtensions(VK_QCOM_MULTIVIEW_PER_VIEW_VIEWPORTS_EXTENSION_NAME);
1440+
AddRequiredFeature(vkt::Feature::multiview);
1441+
AddRequiredFeature(vkt::Feature::multiviewPerViewViewports);
1442+
RETURN_IF_SKIP(Init());
1443+
InitRenderTarget();
1444+
1445+
uint32_t view_mask = 0x2u;
1446+
VkRenderPassMultiviewCreateInfo rp_mv_ci = vku::InitStructHelper();
1447+
rp_mv_ci.subpassCount = 1;
1448+
rp_mv_ci.pViewMasks = &view_mask;
1449+
1450+
RenderPassSingleSubpass rp(*this);
1451+
rp.AddAttachmentDescription(VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED);
1452+
rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL});
1453+
rp.AddColorAttachment(0);
1454+
rp.CreateRenderPass(&rp_mv_ci);
1455+
1456+
VkImageCreateInfo image_create_info = vku::InitStructHelper();
1457+
image_create_info.flags = 0u;
1458+
image_create_info.imageType = VK_IMAGE_TYPE_2D;
1459+
image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
1460+
image_create_info.extent = {32u, 32u, 1u};
1461+
image_create_info.mipLevels = 1u;
1462+
image_create_info.arrayLayers = 2u;
1463+
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1464+
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1465+
image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1466+
vkt::Image image(*m_device, image_create_info, vkt::set_layout);
1467+
vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
1468+
1469+
vkt::Framebuffer framebuffer(*m_device, rp, 1, &image_view.handle());
1470+
1471+
VkRenderPassBeginInfo render_pass_bi = vku::InitStructHelper();
1472+
render_pass_bi.renderPass = rp;
1473+
render_pass_bi.framebuffer = framebuffer;
1474+
render_pass_bi.renderArea.extent = {32u, 32u};
1475+
render_pass_bi.clearValueCount = 1u;
1476+
render_pass_bi.pClearValues = m_renderPassClearValues.data();
1477+
1478+
CreatePipelineHelper pipe(*this);
1479+
pipe.gp_ci_.renderPass = rp;
1480+
m_errorMonitor->SetDesiredError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07730");
1481+
m_errorMonitor->SetDesiredError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-07731");
1482+
pipe.CreateGraphicsPipeline();
1483+
m_errorMonitor->VerifyFound();
1484+
}

0 commit comments

Comments
 (0)