2424#include " utils/math_utils.h"
2525#include " utils/image_utils.h"
2626#include " utils/sync_utils.h"
27+ #include " utils/vk_api_utils.h"
2728
2829namespace stateless {
2930
@@ -579,6 +580,82 @@ bool Device::ValidateRenderPassStripeBeginInfo(VkCommandBuffer commandBuffer, co
579580 return skip;
580581}
581582
583+ bool Device::ValidateMultiviewPerViewRenderAreasRenderPassBeginInfo (
584+ VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* rp_begin_info, const VkRenderingInfo* rendering_info,
585+ const VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM& multiview_per_view_info, const Location& loc) const {
586+ bool skip = false ;
587+ if (multiview_per_view_info.perViewRenderAreaCount != 0 && !enabled_features.multiviewPerViewRenderAreas ) {
588+ const char * vuid = rp_begin_info ? " VUID-VkRenderPassBeginInfo-perViewRenderAreaCount-07859"
589+ : " VUID-VkRenderingInfo-perViewRenderAreaCount-07857" ;
590+ skip |= LogError (vuid, commandBuffer,
591+ loc.pNext (Struct::VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM).dot (Field::perViewRenderAreaCount),
592+ " is %" PRIu32 " but the multiviewPerViewRenderAreas feature was not enabled." ,
593+ multiview_per_view_info.perViewRenderAreaCount );
594+ }
595+
596+ if (rendering_info) {
597+ const uint32_t msb = (uint32_t )MostSignificantBit (rendering_info->viewMask );
598+ if (multiview_per_view_info.perViewRenderAreaCount != msb + 1 ) {
599+ skip |= LogError (
600+ " VUID-VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM-pNext-07866" , commandBuffer,
601+ loc.pNext (Struct::VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM).dot (Field::perViewRenderAreaCount),
602+ " (%" PRIu32 " ) must be VkRenderingInfo::viewMask (0x%" PRIx32 " ) most significant bit index (%" PRIu32 " ) + 1" ,
603+ multiview_per_view_info.perViewRenderAreaCount , rendering_info->viewMask , msb);
604+ }
605+ }
606+
607+ const VkRect2D full_render_area = rendering_info ? rendering_info->renderArea : rp_begin_info->renderArea ;
608+
609+ for (uint32_t i = 0 ; i < multiview_per_view_info.perViewRenderAreaCount ; i++) {
610+ const VkRect2D view_rect = multiview_per_view_info.pPerViewRenderAreas [i];
611+ if (view_rect.offset .x < 0 ) {
612+ skip |= LogError (" VUID-VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM-offset-07861" , commandBuffer,
613+ loc.pNext (Struct::VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM)
614+ .dot (Field::pPerViewRenderAreas, i)
615+ .dot (Field::offset)
616+ .dot (Field::x),
617+ " (%" PRId32 " ) is less than zero." , view_rect.offset .x );
618+ }
619+ if (view_rect.offset .y < 0 ) {
620+ skip |= LogError (" VUID-VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM-offset-07862" , commandBuffer,
621+ loc.pNext (Struct::VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM)
622+ .dot (Field::pPerViewRenderAreas, i)
623+ .dot (Field::offset)
624+ .dot (Field::y),
625+ " (%" PRId32 " ) is less than zero." , view_rect.offset .y );
626+ }
627+ if ((view_rect.offset .x + view_rect.extent .width ) > phys_dev_props.limits .maxFramebufferWidth ) {
628+ skip |= LogError (" VUID-VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM-offset-07863" , commandBuffer,
629+ loc.pNext (Struct::VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM)
630+ .dot (Field::pPerViewRenderAreas, i)
631+ .dot (Field::offset)
632+ .dot (Field::x),
633+ " %" PRId32 " + extent.width (%" PRIu32 " ) greater than maxFramebufferWidth (%" PRIu32 " )." ,
634+ view_rect.offset .x , view_rect.extent .width , phys_dev_props.limits .maxFramebufferWidth );
635+ }
636+ if ((view_rect.offset .y + view_rect.extent .height ) > phys_dev_props.limits .maxFramebufferHeight ) {
637+ skip |= LogError (" VUID-VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM-offset-07864" , commandBuffer,
638+ loc.pNext (Struct::VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM)
639+ .dot (Field::pPerViewRenderAreas, i)
640+ .dot (Field::offset)
641+ .dot (Field::y),
642+ " %" PRId32 " + extent.height (%" PRIu32 " ) greater than maxFramebufferHeight (%" PRIu32 " )." ,
643+ view_rect.offset .y , view_rect.extent .height , phys_dev_props.limits .maxFramebufferHeight );
644+ }
645+
646+ if (!ContainsRect (full_render_area, view_rect)) {
647+ const char * vuid = rp_begin_info ? " VUID-VkRenderPassBeginInfo-perViewRenderAreaCount-07860"
648+ : " VUID-VkRenderingInfo-perViewRenderAreaCount-07858" ;
649+ skip |=
650+ LogError (vuid, commandBuffer,
651+ loc.pNext (Struct::VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM).dot (Field::pPerViewRenderAreas, i),
652+ " (%s) is not contained in %s::renderArea (%s)" , string_VkRect2D (view_rect).c_str (),
653+ rendering_info ? " VkRenderingInfo" : " VkRenderPassBeginInfo" , string_VkRect2D (full_render_area).c_str ());
654+ }
655+ }
656+ return skip;
657+ }
658+
582659bool Device::ValidateCmdBeginRenderPass (VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *const rp_begin,
583660 const ErrorObject &error_obj) const {
584661 bool skip = false ;
@@ -592,6 +669,12 @@ bool Device::ValidateCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkR
592669 const Location loc = error_obj.location .dot (Field::pRenderPassBegin);
593670 skip |= ValidateRenderPassStripeBeginInfo (commandBuffer, rp_begin->pNext , rp_begin->renderArea , loc);
594671
672+ if (const auto multiview_per_view_info =
673+ vku::FindStructInPNextChain<VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM>(rp_begin->pNext )) {
674+ skip |=
675+ ValidateMultiviewPerViewRenderAreasRenderPassBeginInfo (commandBuffer, rp_begin, nullptr , *multiview_per_view_info, loc);
676+ }
677+
595678 return skip;
596679}
597680
@@ -735,6 +818,12 @@ bool Device::manual_PreCallValidateCmdBeginRendering(VkCommandBuffer commandBuff
735818 }
736819 }
737820
821+ if (const auto multiview_per_view_info =
822+ vku::FindStructInPNextChain<VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM>(pRenderingInfo->pNext )) {
823+ skip |= ValidateMultiviewPerViewRenderAreasRenderPassBeginInfo (commandBuffer, nullptr , pRenderingInfo,
824+ *multiview_per_view_info, rendering_info_loc);
825+ }
826+
738827 skip |= ValidateRenderPassStripeBeginInfo (commandBuffer, pRenderingInfo->pNext , pRenderingInfo->renderArea , rendering_info_loc);
739828 skip |= ValidateBeginRenderingColorAttachment (commandBuffer, *pRenderingInfo, rendering_info_loc);
740829 skip |= ValidateBeginRenderingDepthAttachment (commandBuffer, *pRenderingInfo, rendering_info_loc);
0 commit comments