layers: Add VK_KHR_dynamic_rendering

Add VU for VK_KHR_dynamic_rendering extension.
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp
index e918cc2..3e433dd 100644
--- a/layers/buffer_validation.cpp
+++ b/layers/buffer_validation.cpp
@@ -3307,18 +3307,9 @@
 }
 
 bool CoreChecks::ValidateClearAttachmentExtent(VkCommandBuffer command_buffer, uint32_t attachment_index,
-                                               const FRAMEBUFFER_STATE *framebuffer, uint32_t fb_attachment,
-                                               const VkRect2D &render_area, uint32_t rect_count, const VkClearRect *clear_rects,
-                                               const CMD_BUFFER_STATE *primary_cb_state) const {
+                                               const IMAGE_VIEW_STATE* image_view_state,
+                                               const VkRect2D &render_area, uint32_t rect_count, const VkClearRect *clear_rects) const {
     bool skip = false;
-    const IMAGE_VIEW_STATE *image_view_state = nullptr;
-    if (framebuffer && (fb_attachment != VK_ATTACHMENT_UNUSED) && (fb_attachment < framebuffer->createInfo.attachmentCount)) {
-        if (primary_cb_state) {
-            image_view_state = primary_cb_state->GetActiveAttachmentImageViewState(fb_attachment);
-        } else {
-            image_view_state = GetCBState(command_buffer)->GetActiveAttachmentImageViewState(fb_attachment);
-        }
-    }
 
     for (uint32_t j = 0; j < rect_count; j++) {
         if (!ContainsRect(render_area, clear_rects[j].rect)) {
@@ -3378,26 +3369,28 @@
                              attachment_index);
             } else if (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) {
                 uint32_t color_attachment = VK_ATTACHMENT_UNUSED;
-                if (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount) {
-                    color_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
-                    if ((color_attachment != VK_ATTACHMENT_UNUSED) && (color_attachment >= renderpass_attachment_count)) {
-                        skip |= LogError(
-                            commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
-                            "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u is not VK_ATTACHMENT_UNUSED "
-                            "and not a valid attachment for %s attachmentCount=%u. Subpass %u pColorAttachment[%u]=%u.",
-                            attachment_index, clear_desc->colorAttachment,
-                            report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(), cb_node->activeSubpass,
-                            clear_desc->colorAttachment, color_attachment, renderpass_attachment_count);
+                if (cb_node->activeRenderPass->use_dynamic_rendering == false) {
+                    if (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount) {
+                        color_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
+                        if ((color_attachment != VK_ATTACHMENT_UNUSED) && (color_attachment >= renderpass_attachment_count)) {
+                            skip |= LogError(
+                                commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
+                                "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u is not VK_ATTACHMENT_UNUSED "
+                                "and not a valid attachment for %s attachmentCount=%u. Subpass %u pColorAttachment[%u]=%u.",
+                                attachment_index, clear_desc->colorAttachment,
+                                report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(), cb_node->activeSubpass,
+                                clear_desc->colorAttachment, color_attachment, renderpass_attachment_count);
 
-                        color_attachment = VK_ATTACHMENT_UNUSED;  // Defensive, prevent lookup past end of renderpass attachment
+                            color_attachment = VK_ATTACHMENT_UNUSED;  // Defensive, prevent lookup past end of renderpass attachment
+                        }
+                    } else {
+                        skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
+                                         "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u out of range for %s"
+                                         " subpass %u. colorAttachmentCount=%u",
+                                         attachment_index, clear_desc->colorAttachment,
+                                         report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(),
+                                         cb_node->activeSubpass, subpass_desc->colorAttachmentCount);
                     }
-                } else {
-                    skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02501",
-                                     "vkCmdClearAttachments() pAttachments[%u].colorAttachment=%u out of range for %s"
-                                     " subpass %u. colorAttachmentCount=%u",
-                                     attachment_index, clear_desc->colorAttachment,
-                                     report_data->FormatHandle(cb_node->activeRenderPass->renderPass()).c_str(),
-                                     cb_node->activeSubpass, subpass_desc->colorAttachmentCount);
                 }
                 fb_attachment = color_attachment;
 
@@ -3411,38 +3404,44 @@
             } else {  // Must be depth and/or stencil
                 bool subpass_depth = false;
                 bool subpass_stencil = false;
-                if (subpass_desc->pDepthStencilAttachment &&
-                    (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
-                    auto index = subpass_desc->pDepthStencilAttachment->attachment;
-                    subpass_depth = FormatHasDepth(renderpass_create_info->pAttachments[index].format);
-                    subpass_stencil = FormatHasStencil(renderpass_create_info->pAttachments[index].format);
-                }
-                if (!subpass_desc->pDepthStencilAttachment ||
-                    (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
-                    if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && !subpass_depth) {
-                        skip |= LogError(
-                            commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02502",
-                            "vkCmdClearAttachments() pAttachments[%u] aspectMask has VK_IMAGE_ASPECT_DEPTH_BIT but there is no "
-                            "depth attachment in subpass",
-                            attachment_index);
+                if (subpass_desc) {
+                    if (subpass_desc->pDepthStencilAttachment &&
+                        (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
+                        auto index = subpass_desc->pDepthStencilAttachment->attachment;
+                        subpass_depth = FormatHasDepth(renderpass_create_info->pAttachments[index].format);
+                        subpass_stencil = FormatHasStencil(renderpass_create_info->pAttachments[index].format);
                     }
-                    if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && !subpass_stencil) {
+                    if (!subpass_desc->pDepthStencilAttachment ||
+                        (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
+                        if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && !subpass_depth) {
+                            skip |= LogError(
+                                commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02502",
+                                "vkCmdClearAttachments() pAttachments[%u] aspectMask has VK_IMAGE_ASPECT_DEPTH_BIT but there is no "
+                                "depth attachment in subpass",
+                                attachment_index);
+                        }
+                        if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && !subpass_stencil) {
                         skip |= LogError(
                             commandBuffer, "VUID-vkCmdClearAttachments-aspectMask-02503",
                             "vkCmdClearAttachments() pAttachments[%u] aspectMask has VK_IMAGE_ASPECT_STENCIL_BIT but there is no "
-                            "stencil attachment in subpass",
-                            attachment_index);
+                                             "stencil attachment in subpass",
+                                             attachment_index);
+                        }
+                    } else {
+                        fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
                     }
-                } else {
-                    fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
-                }
-                if (subpass_depth) {
-                    skip |= ValidateClearDepthStencilValue(commandBuffer, clear_desc->clearValue.depthStencil,
-                                                           "vkCmdClearAttachments()");
+                    if (subpass_depth) {
+                        skip |= ValidateClearDepthStencilValue(commandBuffer, clear_desc->clearValue.depthStencil,
+                                                               "vkCmdClearAttachments()");
+                    }
                 }
             }
             if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
-                skip |= ValidateClearAttachmentExtent(commandBuffer, attachment_index, framebuffer, fb_attachment, render_area,
+                const IMAGE_VIEW_STATE* image_view_state = nullptr;
+                if (framebuffer && (fb_attachment != VK_ATTACHMENT_UNUSED) && (fb_attachment < framebuffer->createInfo.attachmentCount)) {
+                    image_view_state = cb_node->GetActiveAttachmentImageViewState(fb_attachment);
+                }
+                skip |= ValidateClearAttachmentExtent(commandBuffer, attachment_index, image_view_state, render_area,
                                                       rectCount, pRects);
             }
 
@@ -3458,16 +3457,16 @@
                                                      "VUID-vkCmdClearAttachments-commandBuffer-02505");
                 }
             }
-        }
 
-        // When a subpass uses a non-zero view mask, multiview functionality is considered to be enabled
-        if (subpass_desc->viewMask > 0) {
-            for (uint32_t i = 0; i < rectCount; ++i) {
-                if (pRects[i].baseArrayLayer != 0 || pRects[i].layerCount != 1) {
-                    skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-baseArrayLayer-00018",
-                                     "vkCmdClearAttachments(): pRects[%" PRIu32 "] baseArrayLayer is %" PRIu32
-                                     " and layerCount is %" PRIu32 ", but the render pass instance uses multiview.",
-                                     i, pRects[i].baseArrayLayer, pRects[i].layerCount);
+            // When a subpass uses a non-zero view mask, multiview functionality is considered to be enabled
+            if (subpass_desc && (subpass_desc->viewMask > 0)) {
+                for (uint32_t i = 0; i < rectCount; ++i) {
+                    if (pRects[i].baseArrayLayer != 0 || pRects[i].layerCount != 1) {
+                        skip |= LogError(commandBuffer, "VUID-vkCmdClearAttachments-baseArrayLayer-00018",
+                                         "vkCmdClearAttachments(): pRects[%" PRIu32 "] baseArrayLayer is %" PRIu32
+                                         " and layerCount is %" PRIu32 ", but the render pass instance uses multiview.",
+                                         i, pRects[i].baseArrayLayer, pRects[i].layerCount);
+                    }
                 }
             }
         }
@@ -3480,37 +3479,89 @@
                                                   const VkClearRect *pRects) {
     auto *cb_node = GetCBState(commandBuffer);
     if (cb_node->activeRenderPass && (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)) {
-        const VkRenderPassCreateInfo2 *renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr();
-        const VkSubpassDescription2 *subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass];
         std::shared_ptr<std::vector<VkClearRect>> clear_rect_copy;
-        for (uint32_t attachment_index = 0; attachment_index < attachmentCount; attachment_index++) {
-            const auto clear_desc = &pAttachments[attachment_index];
-            uint32_t fb_attachment = VK_ATTACHMENT_UNUSED;
-            if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
-                (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount)) {
-                fb_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
-            } else if ((clear_desc->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) &&
-                       subpass_desc->pDepthStencilAttachment) {
-                fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
-            }
-            if (fb_attachment != VK_ATTACHMENT_UNUSED) {
-                if (!clear_rect_copy) {
-                    // We need a copy of the clear rectangles that will persist until the last lambda executes
-                    // but we want to create it as lazily as possible
-                    clear_rect_copy.reset(new std::vector<VkClearRect>(pRects, pRects + rectCount));
+        if (cb_node->activeRenderPass->use_dynamic_rendering) {
+            if (cb_node->activeRenderPass->use_dynamic_rendering_inherited)
+            {
+                for (uint32_t attachment_index = 0; attachment_index < attachmentCount; attachment_index++) {
+                    const auto clear_desc = &pAttachments[attachment_index];
+                    auto colorAttachmentCount = cb_node->activeRenderPass->inheritance_rendering_info.colorAttachmentCount;
+                    int image_index = -1;
+                    if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
+                        (clear_desc->colorAttachment < colorAttachmentCount)) {
+                        image_index = cb_node->GetDynamicColorAttachmentImageIndex(clear_desc->colorAttachment);
+                    }
+                    else if (clear_desc->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT)) {
+                        image_index = cb_node->GetDynamicDepthAttachmentImageIndex();
+                    }
+                    else if (clear_desc->aspectMask & (VK_IMAGE_ASPECT_STENCIL_BIT)) {
+                        image_index = cb_node->GetDynamicStencilAttachmentImageIndex();
+                    }
+
+                    if (image_index != -1) {
+                        if (!clear_rect_copy) {
+                            // We need a copy of the clear rectangles that will persist until the last lambda executes
+                            // but we want to create it as lazily as possible
+                            clear_rect_copy.reset(new std::vector<VkClearRect>(pRects, pRects + rectCount));
+                        }
+                        // if a secondary level command buffer inherits the framebuffer from the primary command buffer
+                        // (see VkCommandBufferInheritanceInfo), this validation must be deferred until queue submit time
+                        auto val_fn = [this, commandBuffer, attachment_index, image_index, rectCount, clear_rect_copy](
+                            const CMD_BUFFER_STATE* prim_cb, const FRAMEBUFFER_STATE* fb) {
+                            assert(rectCount == clear_rect_copy->size());
+                            bool skip = false;
+                            const IMAGE_VIEW_STATE* image_view_state = nullptr;
+                            if (image_index != -1) {
+                                image_view_state = (*prim_cb->active_attachments)[image_index];
+                            }
+                            skip = ValidateClearAttachmentExtent(commandBuffer, attachment_index, image_view_state, prim_cb->activeRenderPass->dynamic_rendering_info.renderArea, rectCount,
+                                clear_rect_copy->data());
+                            return skip;
+                        };
+                        cb_node->cmd_execute_commands_functions.emplace_back(val_fn);
+                    }
                 }
-                // if a secondary level command buffer inherits the framebuffer from the primary command buffer
-                // (see VkCommandBufferInheritanceInfo), this validation must be deferred until queue submit time
-                auto val_fn = [this, commandBuffer, attachment_index, fb_attachment, rectCount, clear_rect_copy](
-                                  const CMD_BUFFER_STATE *prim_cb, const FRAMEBUFFER_STATE *fb) {
-                    assert(rectCount == clear_rect_copy->size());
-                    const auto &render_area = prim_cb->activeRenderPassBeginInfo.renderArea;
-                    bool skip = false;
-                    skip = ValidateClearAttachmentExtent(commandBuffer, attachment_index, fb, fb_attachment, render_area, rectCount,
-                                                         clear_rect_copy->data(), prim_cb);
-                    return skip;
-                };
-                cb_node->cmd_execute_commands_functions.emplace_back(val_fn);
+            }
+        }
+        else
+        {
+            const VkRenderPassCreateInfo2* renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr();
+            const VkSubpassDescription2* subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass];
+            
+            for (uint32_t attachment_index = 0; attachment_index < attachmentCount; attachment_index++) {
+                const auto clear_desc = &pAttachments[attachment_index];
+                uint32_t fb_attachment = VK_ATTACHMENT_UNUSED;
+                if ((clear_desc->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
+                    (clear_desc->colorAttachment < subpass_desc->colorAttachmentCount)) {
+                    fb_attachment = subpass_desc->pColorAttachments[clear_desc->colorAttachment].attachment;
+                }
+                else if ((clear_desc->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) &&
+                    subpass_desc->pDepthStencilAttachment) {
+                    fb_attachment = subpass_desc->pDepthStencilAttachment->attachment;
+                }
+                if (fb_attachment != VK_ATTACHMENT_UNUSED) {
+                    if (!clear_rect_copy) {
+                        // We need a copy of the clear rectangles that will persist until the last lambda executes
+                        // but we want to create it as lazily as possible
+                        clear_rect_copy.reset(new std::vector<VkClearRect>(pRects, pRects + rectCount));
+                    }
+                    // if a secondary level command buffer inherits the framebuffer from the primary command buffer
+                    // (see VkCommandBufferInheritanceInfo), this validation must be deferred until queue submit time
+                    auto val_fn = [this, commandBuffer, attachment_index, fb_attachment, rectCount, clear_rect_copy](
+                        const CMD_BUFFER_STATE* prim_cb, const FRAMEBUFFER_STATE* fb) {
+                        assert(rectCount == clear_rect_copy->size());
+                        const auto& render_area = prim_cb->activeRenderPassBeginInfo.renderArea;
+                        bool skip = false;
+                        const IMAGE_VIEW_STATE* image_view_state = nullptr;
+                        if (fb && (fb_attachment != VK_ATTACHMENT_UNUSED) && (fb_attachment < fb->createInfo.attachmentCount)) {
+                            image_view_state = prim_cb->GetActiveAttachmentImageViewState(fb_attachment);
+                        }
+                        skip = ValidateClearAttachmentExtent(commandBuffer, attachment_index, image_view_state, render_area, rectCount,
+                            clear_rect_copy->data());
+                        return skip;
+                    };
+                    cb_node->cmd_execute_commands_functions.emplace_back(val_fn);
+                }
             }
         }
     }
diff --git a/layers/cmd_buffer_state.cpp b/layers/cmd_buffer_state.cpp
index 1c77a16..44cec54 100644
--- a/layers/cmd_buffer_state.cpp
+++ b/layers/cmd_buffer_state.cpp
@@ -681,6 +681,74 @@
     activeFramebuffer = VK_NULL_HANDLE;
 }
 
+void CMD_BUFFER_STATE::BeginRendering(CMD_TYPE cmd_type, const VkRenderingInfoKHR *pRenderingInfo) {
+    RecordCmd(cmd_type);
+    activeRenderPass = std::make_shared<RENDER_PASS_STATE>(pRenderingInfo);
+
+    auto chained_device_group_struct = LvlFindInChain<VkDeviceGroupRenderPassBeginInfo>(pRenderingInfo->pNext);
+    if (chained_device_group_struct) {
+        active_render_pass_device_mask = chained_device_group_struct->deviceMask;
+    } else {
+        active_render_pass_device_mask = initial_device_mask;
+    }
+
+    activeSubpassContents = ((pRenderingInfo->flags & VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR) ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE);
+
+    active_attachments = nullptr;
+    uint32_t attachment_count = (pRenderingInfo->colorAttachmentCount + 2) * 2;
+
+    // Set cb_state->active_attachments & cb_state->attachments_view_states
+    active_attachments = std::make_shared<std::vector<IMAGE_VIEW_STATE *>>(attachment_count);
+    auto &attachments = *(active_attachments.get());
+
+    for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; ++i) {
+        auto& colorAttachment = attachments[GetDynamicColorAttachmentImageIndex(i)];
+        auto& colorResolveAttachment = attachments[GetDynamicColorResolveAttachmentImageIndex(i)];
+        colorAttachment = nullptr;
+        colorResolveAttachment = nullptr;
+
+        if (pRenderingInfo->pColorAttachments[i].imageView != VK_NULL_HANDLE) {
+            auto res = attachments_view_states.insert(
+                dev_data->GetShared<IMAGE_VIEW_STATE>(pRenderingInfo->pColorAttachments[i].imageView));
+            colorAttachment = res.first->get();
+            if (pRenderingInfo->pColorAttachments[i].resolveMode != VK_RESOLVE_MODE_NONE &&
+                pRenderingInfo->pColorAttachments[i].resolveImageView != VK_NULL_HANDLE) {
+                colorResolveAttachment = res.first->get();
+            }
+        }
+    }
+
+    if (pRenderingInfo->pDepthAttachment && pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
+        auto& depthAttachment = attachments[GetDynamicDepthAttachmentImageIndex()];
+        auto& depthResolveAttachment = attachments[GetDynamicDepthResolveAttachmentImageIndex()];
+        depthAttachment = nullptr;
+        depthResolveAttachment = nullptr;
+
+        auto res =
+            attachments_view_states.insert(dev_data->GetShared<IMAGE_VIEW_STATE>(pRenderingInfo->pDepthAttachment->imageView));
+        depthAttachment = res.first->get();
+        if (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE &&
+            pRenderingInfo->pDepthAttachment->resolveImageView != VK_NULL_HANDLE) {
+            depthResolveAttachment = res.first->get();
+        }
+    } 
+
+    if (pRenderingInfo->pStencilAttachment && pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+        auto& stencilAttachment = attachments[GetDynamicStencilAttachmentImageIndex()];
+        auto& stencilResolveAttachment = attachments[GetDynamicStencilResolveAttachmentImageIndex()];
+        stencilAttachment = nullptr;
+        stencilResolveAttachment = nullptr;
+
+        auto res =
+            attachments_view_states.insert(dev_data->GetShared<IMAGE_VIEW_STATE>(pRenderingInfo->pStencilAttachment->imageView));
+        stencilAttachment = res.first->get();
+        if (pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE &&
+            pRenderingInfo->pStencilAttachment->resolveImageView != VK_NULL_HANDLE) {
+            stencilResolveAttachment = res.first->get();
+        }
+    }
+}
+
 void CMD_BUFFER_STATE::Begin(const VkCommandBufferBeginInfo *pBeginInfo) {
     if (CB_RECORDED == state || CB_INVALID_COMPLETE == state) {
         Reset();
@@ -694,33 +762,42 @@
         // If we are a secondary command-buffer and inheriting.  Update the items we should inherit.
         if ((createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) &&
             (beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
-            activeRenderPass = dev_data->GetShared<RENDER_PASS_STATE>(beginInfo.pInheritanceInfo->renderPass);
-            activeSubpass = beginInfo.pInheritanceInfo->subpass;
+            if (beginInfo.pInheritanceInfo->renderPass) {
+                activeRenderPass = dev_data->GetShared<RENDER_PASS_STATE>(beginInfo.pInheritanceInfo->renderPass);
+                activeSubpass = beginInfo.pInheritanceInfo->subpass;
 
-            if (beginInfo.pInheritanceInfo->framebuffer) {
-                activeFramebuffer = dev_data->GetShared<FRAMEBUFFER_STATE>(beginInfo.pInheritanceInfo->framebuffer);
-                active_subpasses = nullptr;
-                active_attachments = nullptr;
+                if (beginInfo.pInheritanceInfo->framebuffer) {
+                    activeFramebuffer = dev_data->GetShared<FRAMEBUFFER_STATE>(beginInfo.pInheritanceInfo->framebuffer);
+                    active_subpasses = nullptr;
+                    active_attachments = nullptr;
 
-                if (activeFramebuffer) {
-                    framebuffers.insert(activeFramebuffer);
+                    if (activeFramebuffer) {
+                        framebuffers.insert(activeFramebuffer);
 
-                    // Set active_subpasses
-                    active_subpasses = std::make_shared<std::vector<SUBPASS_INFO>>(activeFramebuffer->createInfo.attachmentCount);
-                    const auto &subpass = activeRenderPass->createInfo.pSubpasses[activeSubpass];
-                    UpdateSubpassAttachments(subpass, *active_subpasses);
+                        // Set active_subpasses
+                        active_subpasses = std::make_shared<std::vector<SUBPASS_INFO>>(activeFramebuffer->createInfo.attachmentCount);
+                        const auto& subpass = activeRenderPass->createInfo.pSubpasses[activeSubpass];
+                        UpdateSubpassAttachments(subpass, *active_subpasses);
 
-                    // Set active_attachments & attachments_view_states
-                    active_attachments =
-                        std::make_shared<std::vector<IMAGE_VIEW_STATE *>>(activeFramebuffer->createInfo.attachmentCount);
-                    UpdateAttachmentsView(nullptr);
+                        // Set active_attachments & attachments_view_states
+                        active_attachments =
+                            std::make_shared<std::vector<IMAGE_VIEW_STATE*>>(activeFramebuffer->createInfo.attachmentCount);
+                        UpdateAttachmentsView(nullptr);
 
-                    // Connect this framebuffer and its children to this cmdBuffer
-                    if (!dev_data->disabled[command_buffer_state]) {
-                        AddChild(activeFramebuffer.get());
+                        // Connect this framebuffer and its children to this cmdBuffer
+                        if (!dev_data->disabled[command_buffer_state]) {
+                            AddChild(activeFramebuffer.get());
+                        }
                     }
                 }
             }
+            else
+            {
+                auto inheritance_rendering_info = lvl_find_in_chain<VkCommandBufferInheritanceRenderingInfoKHR>(beginInfo.pInheritanceInfo->pNext);
+                if (inheritance_rendering_info) {
+                    activeRenderPass = std::make_shared<RENDER_PASS_STATE>(inheritance_rendering_info);
+                }
+            }
 
             // Check for VkCommandBufferInheritanceViewportScissorInfoNV (VK_NV_inherited_viewport_scissor)
             auto p_inherited_viewport_scissor_info =
diff --git a/layers/cmd_buffer_state.h b/layers/cmd_buffer_state.h
index 40bff88..bd67f59 100644
--- a/layers/cmd_buffer_state.h
+++ b/layers/cmd_buffer_state.h
@@ -401,6 +401,8 @@
     void NextSubpass(CMD_TYPE cmd_type, VkSubpassContents contents);
     void EndRenderPass(CMD_TYPE cmd_type);
 
+    void BeginRendering(CMD_TYPE cmd_type, const VkRenderingInfoKHR *pRenderingInfo);
+
     void ExecuteCommands(uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers);
 
     void UpdateLastBoundDescriptorSets(VkPipelineBindPoint pipeline_bind_point, const PIPELINE_LAYOUT_STATE *pipeline_layout,
@@ -442,6 +444,24 @@
     void Submit(uint32_t perf_submit_pass);
     void Retire(uint32_t perf_submit_pass);
 
+    uint32_t GetDynamicColorAttachmentCount() {
+        if (activeRenderPass) {
+            if (activeRenderPass->use_dynamic_rendering_inherited) {
+                return activeRenderPass->inheritance_rendering_info.colorAttachmentCount;
+            }
+            if (activeRenderPass->use_dynamic_rendering) {
+                return activeRenderPass->dynamic_rendering_info.colorAttachmentCount;
+            }
+        }
+        return 0;
+    }
+    uint32_t GetDynamicColorAttachmentImageIndex(uint32_t index) { return index; }
+    uint32_t GetDynamicColorResolveAttachmentImageIndex(uint32_t index) { return index + GetDynamicColorAttachmentCount(); }
+    uint32_t GetDynamicDepthAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount(); }
+    uint32_t GetDynamicDepthResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 1; }
+    uint32_t GetDynamicStencilAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 2; }
+    uint32_t GetDynamicStencilResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 3; }
+
   protected:
     void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
     void UpdateAttachmentsView(const VkRenderPassBeginInfo *pRenderPassBegin);
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 7ebaa3a..119fe2d 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -851,48 +851,53 @@
     if (!create_info.pRasterizationState || (create_info.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
         VkSampleCountFlagBits pso_num_samples = GetNumSamples(pPipeline);
         if (pCB->activeRenderPass) {
-            const auto render_pass_info = pCB->activeRenderPass->createInfo.ptr();
-            const VkSubpassDescription2 *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
-            uint32_t i;
-            unsigned subpass_num_samples = 0;
+            if (pCB->activeRenderPass->use_dynamic_rendering) {
+                // TODO: Mirror the below VUs but using dynamic rendering
+                const auto dynamic_rendering_info = pCB->activeRenderPass->dynamic_rendering_info;
+            } else {
+                const auto render_pass_info = pCB->activeRenderPass->createInfo.ptr();
+                const VkSubpassDescription2 *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
+                uint32_t i;
+                unsigned subpass_num_samples = 0;
 
-            for (i = 0; i < subpass_desc->colorAttachmentCount; i++) {
-                const auto attachment = subpass_desc->pColorAttachments[i].attachment;
-                if (attachment != VK_ATTACHMENT_UNUSED) {
-                    subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
+                for (i = 0; i < subpass_desc->colorAttachmentCount; i++) {
+                    const auto attachment = subpass_desc->pColorAttachments[i].attachment;
+                    if (attachment != VK_ATTACHMENT_UNUSED) {
+                        subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
 
-                    const auto *imageview_state = pCB->GetActiveAttachmentImageViewState(attachment);
-                    if (imageview_state != nullptr &&
-                        attachment < pPipeline->create_info.graphics.pColorBlendState->attachmentCount) {
-                        if ((imageview_state->format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) == 0 &&
+                        const auto *imageview_state = pCB->GetActiveAttachmentImageViewState(attachment);
+                        if (imageview_state != nullptr &&
+                            attachment < pPipeline->create_info.graphics.pColorBlendState->attachmentCount) {
+                            if ((imageview_state->format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) == 0 &&
                             pPipeline->create_info.graphics.pColorBlendState->pAttachments[attachment].blendEnable != VK_FALSE) {
                             skip |= LogError(pPipeline->pipeline(), vuid.blend_enable,
                                              "%s: Image view's format features of the color attachment (%" PRIu32
                                              ") of the active subpass do not contain VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT "
                                              "bit, but active pipeline's pAttachments[%" PRIu32 "].blendEnable is not VK_FALSE.",
                                              caller, attachment, attachment);
+                            }
                         }
                     }
                 }
-            }
 
-            if (subpass_desc->pDepthStencilAttachment &&
-                subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
-                const auto attachment = subpass_desc->pDepthStencilAttachment->attachment;
-                subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
-            }
+                if (subpass_desc->pDepthStencilAttachment &&
+                    subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
+                    const auto attachment = subpass_desc->pDepthStencilAttachment->attachment;
+                    subpass_num_samples |= static_cast<unsigned>(render_pass_info->pAttachments[attachment].samples);
+                }
 
-            if (!(IsExtEnabled(device_extensions.vk_amd_mixed_attachment_samples) ||
-                  IsExtEnabled(device_extensions.vk_nv_framebuffer_mixed_samples)) &&
-                ((subpass_num_samples & static_cast<unsigned>(pso_num_samples)) != subpass_num_samples)) {
-                LogObjectList objlist(pPipeline->pipeline());
-                objlist.add(pCB->activeRenderPass->renderPass());
+                if (!(IsExtEnabled(device_extensions.vk_amd_mixed_attachment_samples) ||
+                      IsExtEnabled(device_extensions.vk_nv_framebuffer_mixed_samples)) &&
+                    ((subpass_num_samples & static_cast<unsigned>(pso_num_samples)) != subpass_num_samples)) {
+                    LogObjectList objlist(pPipeline->pipeline());
+                    objlist.add(pCB->activeRenderPass->renderPass());
                 skip |=
                     LogError(objlist, vuid.rasterization_samples,
                              "%s: In %s the sample count is %s while the current %s has %s and they need to be the same.", caller,
                              report_data->FormatHandle(pPipeline->pipeline()).c_str(), string_VkSampleCountFlagBits(pso_num_samples),
-                             report_data->FormatHandle(pCB->activeRenderPass->renderPass()).c_str(),
-                             string_VkSampleCountFlags(static_cast<VkSampleCountFlags>(subpass_num_samples)).c_str());
+                                     report_data->FormatHandle(pCB->activeRenderPass->renderPass()).c_str(),
+                                     string_VkSampleCountFlags(static_cast<VkSampleCountFlags>(subpass_num_samples)).c_str());
+                }
             }
         } else {
             skip |= LogError(pPipeline->pipeline(), kVUID_Core_DrawState_NoActiveRenderpass,
@@ -901,7 +906,7 @@
         }
     }
     // Verify that PSO creation renderPass is compatible with active renderPass
-    if (pCB->activeRenderPass) {
+    if (pCB->activeRenderPass && !pCB->activeRenderPass->use_dynamic_rendering) {
         // TODO: AMD extension codes are included here, but actual function entrypoints are not yet intercepted
         if (pCB->activeRenderPass->renderPass() != pPipeline->rp_state->renderPass()) {
             // renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with
@@ -1249,22 +1254,31 @@
     if (create_info.pColorBlendState) {
         const auto *subpass_desc = &pPipeline->rp_state->createInfo.pSubpasses[create_info.subpass];
 
-        for (uint32_t i = 0; i < pPipeline->attachments.size() && i < subpass_desc->colorAttachmentCount; ++i) {
-            const auto attachment = subpass_desc->pColorAttachments[i].attachment;
-            if (attachment == VK_ATTACHMENT_UNUSED) continue;
+        uint32_t numberColorAttachments = (pPipeline->rp_state->use_dynamic_rendering)
+                                              ? pPipeline->rp_state->rendering_create_info.colorAttachmentCount
+                                              : subpass_desc->colorAttachmentCount;
 
-            const auto attachment_desc = pPipeline->rp_state->createInfo.pAttachments[attachment];
-            const VkFormatFeatureFlags format_features = GetPotentialFormatFeatures(attachment_desc.format);
+        for (uint32_t i = 0; i < pPipeline->attachments.size() && i < numberColorAttachments; ++i) {
+            VkFormatFeatureFlags format_features;
 
-            if (create_info.pRasterizationState &&
-                !create_info.pRasterizationState->rasterizerDiscardEnable &&
-                pPipeline->attachments[i].blendEnable && !(format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) {
+            if (pPipeline->rp_state->use_dynamic_rendering) {
+                format_features = GetPotentialFormatFeatures(pPipeline->rp_state->rendering_create_info.pColorAttachmentFormats[i]);
+            } else {
+                const auto attachment = subpass_desc->pColorAttachments[i].attachment;
+                if (attachment == VK_ATTACHMENT_UNUSED) continue;
+
+                const auto attachment_desc = pPipeline->rp_state->createInfo.pAttachments[attachment];
+                format_features = GetPotentialFormatFeatures(attachment_desc.format);
+
+                if (create_info.pRasterizationState && !create_info.pRasterizationState->rasterizerDiscardEnable &&
+                    pPipeline->attachments[i].blendEnable && !(format_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) {
                 skip |=
                     LogError(device, "VUID-VkGraphicsPipelineCreateInfo-blendEnable-04717",
-                             "vkCreateGraphicsPipelines(): pipeline.pColorBlendState.pAttachments[%" PRIu32
-                             "].blendEnable is VK_TRUE but format %s of the corresponding attachment description (subpass %" PRIu32
-                             ", attachment %" PRIu32 ") does not support VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.",
-                             i, string_VkFormat(attachment_desc.format), create_info.subpass, attachment);
+                        "vkCreateGraphicsPipelines(): pipeline.pColorBlendState.pAttachments[%" PRIu32
+                        "].blendEnable is VK_TRUE but format %s of the corresponding attachment description (subpass %" PRIu32
+                        ", attachment %" PRIu32 ") does not support VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.",
+                        i, string_VkFormat(attachment_desc.format), create_info.subpass, attachment);
+                }
             }
         }
     }
@@ -1363,16 +1377,20 @@
     bool skip = false;
     const auto &create_info = pPipeline->create_info.graphics;
 
-    // Ensure the subpass index is valid. If not, then ValidateGraphicsPipelineShaderState
-    // produces nonsense errors that confuse users. Other layers should already
-    // emit errors for renderpass being invalid.
-    auto subpass_desc = &pPipeline->rp_state->createInfo.pSubpasses[create_info.subpass];
-    if (create_info.subpass >= pPipeline->rp_state->createInfo.subpassCount) {
-        skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-subpass-00759",
-                         "Invalid Pipeline CreateInfo[%" PRIu32
-                         "] State: Subpass index %u is out of range for this renderpass (0..%u).",
-                         pipelineIndex, create_info.subpass, pPipeline->rp_state->createInfo.subpassCount - 1);
-        subpass_desc = nullptr;
+    safe_VkSubpassDescription2 *subpass_desc = nullptr;
+
+    if (!pPipeline->rp_state->use_dynamic_rendering) {
+        // Ensure the subpass index is valid. If not, then ValidateGraphicsPipelineShaderState
+        // produces nonsense errors that confuse users. Other layers should already
+        // emit errors for renderpass being invalid.
+        subpass_desc = &pPipeline->rp_state->createInfo.pSubpasses[create_info.subpass];
+        if (create_info.subpass >= pPipeline->rp_state->createInfo.subpassCount) {
+            skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-subpass-00759",
+                             "Invalid Pipeline CreateInfo[%" PRIu32
+                             "] State: Subpass index %u is out of range for this renderpass (0..%u).",
+                             pipelineIndex, create_info.subpass, pPipeline->rp_state->createInfo.subpassCount - 1);
+            subpass_desc = nullptr;
+        }
     }
 
     if (create_info.pColorBlendState != NULL) {
@@ -1781,28 +1799,28 @@
                                      "subpass uses color attachments.",
                                      pipelineIndex);
                 }
-            }
 
-            constexpr int num_bits = sizeof(subpass_desc->viewMask) * CHAR_BIT;
-            std::bitset<num_bits> view_bits(subpass_desc->viewMask);
-            uint32_t view_bits_count = static_cast<uint32_t>(view_bits.count());
-            if (view_bits_count > 1) {
-                if (!enabled_features.multiview_features.multiviewTessellationShader &&
-                    (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
-                     pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) {
-                    skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00760",
-                                     "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
-                                     " bits set in viewMask and pStages includes tessellation shaders, but the "
-                                     "VkPhysicalDeviceMultiviewFeatures::multiviewTessellationShader features is not enabled.",
-                                     pipelineIndex, view_bits_count);
-                }
-                if (!enabled_features.multiview_features.multiviewGeometryShader &&
-                    pPipeline->active_shaders & VK_SHADER_STAGE_GEOMETRY_BIT) {
-                    skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00761",
-                                     "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
-                                     " bits set in viewMask and pStages includes geometry shader, but the "
-                                     "VkPhysicalDeviceMultiviewFeatures::multiviewGeometryShader features is not enabled.",
-                                     pipelineIndex, view_bits_count);
+                constexpr int num_bits = sizeof(subpass_desc->viewMask) * CHAR_BIT;
+                std::bitset<num_bits> view_bits(subpass_desc->viewMask);
+                uint32_t view_bits_count = static_cast<uint32_t>(view_bits.count());
+                if (view_bits_count > 1) {
+                    if (!enabled_features.multiview_features.multiviewTessellationShader &&
+                        (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
+                         pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) {
+                        skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00760",
+                                         "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
+                                         " bits set in viewMask and pStages includes tessellation shaders, but the "
+                                         "VkPhysicalDeviceMultiviewFeatures::multiviewTessellationShader features is not enabled.",
+                                         pipelineIndex, view_bits_count);
+                    }
+                    if (!enabled_features.multiview_features.multiviewGeometryShader &&
+                        pPipeline->active_shaders & VK_SHADER_STAGE_GEOMETRY_BIT) {
+                        skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-renderPass-00761",
+                                         "Invalid Pipeline CreateInfo[%" PRIu32 "] State: subpass has %" PRIu32
+                                         " bits set in viewMask and pStages includes geometry shader, but the "
+                                         "VkPhysicalDeviceMultiviewFeatures::multiviewGeometryShader features is not enabled.",
+                                         pipelineIndex, view_bits_count);
+                    }
                 }
             }
         }
@@ -2433,12 +2451,14 @@
 bool CoreChecks::ValidateCmdSubpassState(const CMD_BUFFER_STATE *pCB, const CMD_TYPE cmd_type) const {
     if (!pCB->activeRenderPass) return false;
     bool skip = false;
-    if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS &&
+    if (pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY &&
+        pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS &&
         (cmd_type != CMD_EXECUTECOMMANDS && cmd_type != CMD_NEXTSUBPASS && cmd_type != CMD_ENDRENDERPASS &&
          cmd_type != CMD_NEXTSUBPASS2 && cmd_type != CMD_NEXTSUBPASS2KHR && cmd_type != CMD_ENDRENDERPASS2 &&
          cmd_type != CMD_ENDRENDERPASS2KHR)) {
         skip |= LogError(pCB->commandBuffer(), kVUID_Core_DrawState_InvalidCommandBuffer,
-                         "Commands cannot be called in a subpass using secondary command buffers.");
+                         "%s() cannot be called in a subpass using secondary command buffers.",
+                          kGeneratedCommandNameList[cmd_type]);
     } else if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_INLINE && cmd_type == CMD_EXECUTECOMMANDS) {
         skip |= LogError(pCB->commandBuffer(), kVUID_Core_DrawState_InvalidCommandBuffer,
                          "vkCmdExecuteCommands() cannot be called in a subpass using inline commands.");
@@ -5454,14 +5474,8 @@
                                  "].renderPass is VK_NULL_HANDLE but dynamicRendering is not enabled.",
                                  i);
 
-            } else {
-                skip |= LogError(device, "UNASSIGNED-VkGraphicsPipelineCreateInfo-dynamicRendering-not-supported",
-                                 "vkCreateGraphicsPipeline: pCreateInfos[%" PRIu32
-                                 "].renderPass is VK_NULL_HANDLE. VK_KHR_dynamic_rendering is currently unsupported",
-                                 i);
-            }
-            // it is unsafe to continue validating so we need to always fail creation of the pipeline.
-            return true;
+                return true;
+            } 
         }
     }
 
@@ -6392,6 +6406,475 @@
                                         "vkUpdateDescriptorSets()");
 }
 
+bool CoreChecks::PreCallValidateCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
+                                                     const VkRenderingInfoKHR *pRenderingInfo) const {
+    const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
+    if (!cb_state) return false;
+    bool skip = false;
+
+    if (pRenderingInfo->viewMask != 0 && pRenderingInfo->layerCount == 0) {
+        skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-viewMask-06069",
+                         "vkCmdBeginRenderingKHR(): If viewMask is not 0 (%u), layerCount must not be 0 (%u)",
+                         pRenderingInfo->viewMask, pRenderingInfo->layerCount);
+    }
+
+    if (!(IsExtEnabled(device_extensions.vk_amd_mixed_attachment_samples) ||
+          IsExtEnabled(device_extensions.vk_nv_framebuffer_mixed_samples))) {
+        uint32_t first_sample_count_attachment = VK_ATTACHMENT_UNUSED;
+        for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+            auto image_view = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+            first_sample_count_attachment = (j == 0u) ? static_cast<uint32_t>(image_view->samples) : first_sample_count_attachment;
+
+            if (first_sample_count_attachment != image_view->samples) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-imageView-06070",
+                    "vkCmdBeginRenderingKHR(): Color attachment ref %u has sample count %s, whereas first color attachment ref has "
+                    "sample count %u.",
+                    j, string_VkSampleCountFlagBits(image_view->samples), (first_sample_count_attachment));
+            }
+        }
+    }
+
+    if (!(pRenderingInfo->colorAttachmentCount <= phys_dev_props.limits.maxColorAttachments)) {
+        skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06106",
+                         "vkCmdBeginRenderingKHR(): colorAttachmentCount (%u) must be less than or equal to "
+                         "VkPhysicalDeviceLimits::maxColorAttachments (%u)",
+                         pRenderingInfo->colorAttachmentCount, phys_dev_props.limits.maxColorAttachments);
+    }
+
+    if ((enabled_features.core11.multiview == VK_FALSE) && (pRenderingInfo->viewMask != 0)) {
+        skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-multiview-06127",
+                         "vkCmdBeginRenderingKHR(): If the multiview feature is not enabled, viewMask must be 0 (%u)",
+                         pRenderingInfo->viewMask);
+    }
+
+    auto chained_device_group_struct = LvlFindInChain<VkDeviceGroupRenderPassBeginInfo>(pRenderingInfo->pNext);
+    if (!chained_device_group_struct || (chained_device_group_struct && chained_device_group_struct->deviceRenderAreaCount == 0)) {
+        if (pRenderingInfo->renderArea.offset.x < 0) {
+            skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06077",
+                             "vkCmdBeginRenderingKHR(): renderArea.offset.x is %d and must be greater than 0",
+                             pRenderingInfo->renderArea.offset.x);
+        }
+
+        if (pRenderingInfo->renderArea.offset.y < 0) {
+            skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06078",
+                             "vkCmdBeginRenderingKHR(): renderArea.offset.y is %d and must be greater than 0",
+                             pRenderingInfo->renderArea.offset.y);
+        }
+
+        for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+            if (pRenderingInfo->pColorAttachments[j].imageView != VK_NULL_HANDLE) {
+                auto image_view_state = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+                IMAGE_STATE *image_state = image_view_state->image_state.get();
+                if (!(image_state->createInfo.extent.width >=
+                      pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width)) {
+                    skip |=
+                        LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06079",
+                                 "vkCmdBeginRenderingKHR(): width of the pColorAttachments[%u].imageView: %u must be greater than"
+                                 "renderArea.offset.x +  renderArea.extent.width",
+                                 j, image_state->createInfo.extent.width);
+                }
+                if (!(image_state->createInfo.extent.height >=
+                      pRenderingInfo->renderArea.offset.y + pRenderingInfo->renderArea.extent.height)) {
+                    skip |=
+                        LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06080",
+                                 "vkCmdBeginRenderingKHR(): height of the pColorAttachments[%u].imageView: %u must be greater than"
+                                 "renderArea.offset.y +  renderArea.extent.height",
+                                 j, image_state->createInfo.extent.height);
+                }
+            }
+        }
+
+        if (pRenderingInfo->pDepthAttachment != VK_NULL_HANDLE && pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
+            auto depth_view_state = GetImageViewState(pRenderingInfo->pDepthAttachment->imageView);
+            IMAGE_STATE *image_state = depth_view_state->image_state.get();
+            if (!(image_state->createInfo.extent.width >=
+                  pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06079",
+                                 "vkCmdBeginRenderingKHR(): width of the pDepthAttachment->imageView: %u must be greater than"
+                                 "renderArea.offset.x +  renderArea.extent.width",
+                                 image_state->createInfo.extent.width);
+            }
+            if (!(image_state->createInfo.extent.height >=
+                  pRenderingInfo->renderArea.offset.y + pRenderingInfo->renderArea.extent.height)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06080",
+                                 "vkCmdBeginRenderingKHR(): height of the pDepthAttachment->imageView: %u must be greater than"
+                                 "renderArea.offset.y +  renderArea.extent.height",
+                                 image_state->createInfo.extent.height);
+            }
+        }
+
+        if (pRenderingInfo->pStencilAttachment != VK_NULL_HANDLE && pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+            auto stencil_view_state = GetImageViewState(pRenderingInfo->pStencilAttachment->imageView);
+            IMAGE_STATE *image_state = stencil_view_state->image_state.get();
+            if (!(image_state->createInfo.extent.width >=
+                  pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06079",
+                                 "vkCmdBeginRenderingKHR(): width of the pStencilAttachment->imageView: %u must be greater than"
+                                 "renderArea.offset.x +  renderArea.extent.width",
+                                 image_state->createInfo.extent.width);
+            }
+            if (!(image_state->createInfo.extent.height >=
+                  pRenderingInfo->renderArea.offset.y + pRenderingInfo->renderArea.extent.height)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06080",
+                                 "vkCmdBeginRenderingKHR(): height of the pStencilAttachment->imageView: %u must be greater than"
+                                 "renderArea.offset.y +  renderArea.extent.height",
+                                 image_state->createInfo.extent.height);
+            }
+        }
+    }
+
+    if (chained_device_group_struct) {
+        for (uint32_t deviceRenderAreaIndex = 0; deviceRenderAreaIndex < chained_device_group_struct->deviceRenderAreaCount;
+             ++deviceRenderAreaIndex) {
+            auto offset_x = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].offset.x;
+            auto width = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].extent.width;
+            if (!(offset_x >= 0)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06081",
+                                 "vkCmdBeginRenderingKHR(): pDeviceRenderAreas[%u].offset.x: %d must be greater than or equal to 0",
+                                 deviceRenderAreaIndex, offset_x);
+            }
+            auto offset_y = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].offset.y;
+            auto height = chained_device_group_struct->pDeviceRenderAreas[deviceRenderAreaIndex].extent.height;
+            if (!(offset_y >= 0)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06082",
+                                 "vkCmdBeginRenderingKHR(): pDeviceRenderAreas[%u].offset.y: %d must be greater than or equal to 0",
+                                 deviceRenderAreaIndex, offset_y);
+            }
+
+            for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+                if (pRenderingInfo->pColorAttachments[j].imageView != VK_NULL_HANDLE) {
+                    auto image_view_state = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+                    IMAGE_STATE *image_state = image_view_state->image_state.get();
+                    if (!(image_state->createInfo.extent.width >= offset_x + width)) {
+                        skip |= LogError(
+                            commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06083",
+                            "vkCmdBeginRenderingKHR(): width of the pColorAttachments[%u].imageView: %u must be greater than"
+                            "renderArea.offset.x +  renderArea.extent.width",
+                            j, image_state->createInfo.extent.width);
+                    }
+                    if (!(image_state->createInfo.extent.height >= offset_y + height)) {
+                        skip |= LogError(
+                            commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06084",
+                            "vkCmdBeginRenderingKHR(): height of the pColorAttachments[%u].imageView: %u must be greater than"
+                            "renderArea.offset.y +  renderArea.extent.height",
+                            j, image_state->createInfo.extent.height);
+                    }
+                }
+            }
+
+            if (pRenderingInfo->pDepthAttachment != VK_NULL_HANDLE) {
+                auto depth_view_state = GetImageViewState(pRenderingInfo->pDepthAttachment->imageView);
+                IMAGE_STATE *image_state = depth_view_state->image_state.get();
+                if (!(image_state->createInfo.extent.width >= offset_x + width)) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06083",
+                                     "vkCmdBeginRenderingKHR(): width of the pDepthAttachment->imageView: %u must be greater than"
+                                     "renderArea.offset.x +  renderArea.extent.width",
+                                     image_state->createInfo.extent.width);
+                }
+                if (!(image_state->createInfo.extent.height >= offset_y + height)) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06084",
+                                     "vkCmdBeginRenderingKHR(): height of the pDepthAttachment->imageView: %u must be greater than"
+                                     "renderArea.offset.y +  renderArea.extent.height",
+                                     image_state->createInfo.extent.height);
+                }
+            }
+
+            if (pRenderingInfo->pStencilAttachment != VK_NULL_HANDLE) {
+                auto stencil_view_state = GetImageViewState(pRenderingInfo->pStencilAttachment->imageView);
+                IMAGE_STATE *image_state = stencil_view_state->image_state.get();
+                if (!(image_state->createInfo.extent.width >= offset_x + width)) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06083",
+                                     "vkCmdBeginRenderingKHR(): width of the pStencilAttachment->imageView: %u must be greater than"
+                                     "renderArea.offset.x +  renderArea.extent.width",
+                                     image_state->createInfo.extent.width);
+                }
+                if (!(image_state->createInfo.extent.height >= offset_y + height)) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pNext-06084",
+                                     "vkCmdBeginRenderingKHR(): height of the pStencilAttachment->imageView: %u must be greater than"
+                                     "renderArea.offset.y +  renderArea.extent.height",
+                                     image_state->createInfo.extent.height);
+                }
+            }
+        }
+    }
+
+    if (pRenderingInfo->pDepthAttachment != NULL && pRenderingInfo->pStencilAttachment != NULL) {
+        if (pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE &&
+            pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+            if (!(pRenderingInfo->pDepthAttachment->imageView == pRenderingInfo->pStencilAttachment->imageView)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06085",
+                                 "vkCmdBeginRenderingKHR(): imageView of pDepthAttachment and pStencilAttachment must be the same");
+            }
+
+            if ((phys_dev_props_core12.independentResolveNone == VK_FALSE) &&
+                (pRenderingInfo->pDepthAttachment->resolveMode != pRenderingInfo->pStencilAttachment->resolveMode)) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06104",
+                    "vkCmdBeginRenderingKHR(): The values of depthResolveMode (%u) and stencilResolveMode (%u) must be identical.",
+                    pRenderingInfo->pDepthAttachment->resolveMode, pRenderingInfo->pStencilAttachment->resolveMode);
+            }
+
+            if ((phys_dev_props_core12.independentResolve == VK_FALSE) &&
+                (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE) &&
+                (pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE) &&
+                (pRenderingInfo->pStencilAttachment->resolveMode != pRenderingInfo->pDepthAttachment->resolveMode)) {
+                skip |= LogError(device, "VUID-VkRenderingInfoKHR-pDepthAttachment-06105",
+                                 "vkCmdBeginRenderingKHR(): The values of depthResolveMode (%u) and stencilResolveMode (%u) must "
+                                 "be identical, or "
+                                 "one of them must be %u.",
+                                 pRenderingInfo->pDepthAttachment->resolveMode, pRenderingInfo->pStencilAttachment->resolveMode,
+                                 VK_RESOLVE_MODE_NONE);
+            }
+        }
+
+        if (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE &&
+            pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE) {
+            if (!(pRenderingInfo->pDepthAttachment->resolveImageView == pRenderingInfo->pStencilAttachment->resolveImageView)) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06086",
+                    "vkCmdBeginRenderingKHR(): resolveImageView of pDepthAttachment and pStencilAttachment must be the same");
+            }
+        }
+    }
+
+    for (uint32_t j = 0; j < pRenderingInfo->colorAttachmentCount; ++j) {
+        skip |= ValidateRenderingAttachmentInfoKHR(commandBuffer, &pRenderingInfo->pColorAttachments[j]);
+
+        if (pRenderingInfo->pColorAttachments[j].imageView != VK_NULL_HANDLE) {
+            auto image_view_state = GetImageViewState(pRenderingInfo->pColorAttachments[j].imageView);
+            IMAGE_STATE *image_state = image_view_state->image_state.get();
+            if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06087",
+                                 "vkCmdBeginRenderingKHR(): image must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT");
+            }
+
+            if (pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+                pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06090",
+                                 "vkCmdBeginRenderingKHR(): imageLayout must not be "
+                                 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or "
+                                 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
+            }
+
+            if (pRenderingInfo->pColorAttachments[j].resolveMode != VK_RESOLVE_MODE_NONE) {
+                if (pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+                    pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06091",
+                                     "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+                                     "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or "
+                                     "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
+                }
+            }
+
+            if (pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
+                pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06096",
+                                 "vkCmdBeginRenderingKHR(): imageLayout must not be "
+                                 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL "
+                                 "or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+            }
+
+            if (pRenderingInfo->pColorAttachments[j].resolveMode != VK_RESOLVE_MODE_NONE) {
+                if (pRenderingInfo->pColorAttachments[j].resolveImageLayout ==
+                        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
+                    pRenderingInfo->pColorAttachments[j].resolveImageLayout ==
+                        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06097",
+                                     "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+                                     "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL or "
+                                     "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+                }
+            }
+
+            if (pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
+                pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
+                pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL ||
+                pRenderingInfo->pColorAttachments[j].imageLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06100",
+                    "vkCmdBeginRenderingKHR(): imageLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL"
+                    " or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"
+                    " or VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL"
+                    " or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+            }
+
+            if (pRenderingInfo->pColorAttachments[j].resolveMode != VK_RESOLVE_MODE_NONE) {
+                if (pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ||
+                    pRenderingInfo->pColorAttachments[j].resolveImageLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL) {
+                    skip |= LogError(
+                        commandBuffer, "VUID-VkRenderingInfoKHR-colorAttachmentCount-06101",
+                        "vkCmdBeginRenderingKHR(): resolveImageLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL or "
+                        "VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL");
+                }
+            }
+        }
+    }
+
+    if (pRenderingInfo->pDepthAttachment != NULL) {
+        skip |= ValidateRenderingAttachmentInfoKHR(commandBuffer, pRenderingInfo->pDepthAttachment);
+
+        if (pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
+            auto depth_view_state = GetImageViewState(pRenderingInfo->pDepthAttachment->imageView);
+            IMAGE_STATE *image_state = depth_view_state->image_state.get();
+            if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06088",
+                    "vkCmdBeginRenderingKHR(): image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT");
+            }
+
+            if (pRenderingInfo->pDepthAttachment->imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06092",
+                    "vkCmdBeginRenderingKHR(): image must not have been created with VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+            }
+
+            if (pRenderingInfo->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE) {
+                if (pRenderingInfo->pDepthAttachment->resolveImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+                    skip |= LogError(
+                        commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06093",
+                        "vkCmdBeginRenderingKHR(): resolveImageLayout must not be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+                }
+
+                if (pRenderingInfo->pDepthAttachment->resolveImageLayout ==
+                    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pDepthAttachment-06098",
+                                     "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+                                     "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL");
+                }
+
+                if (!(pRenderingInfo->pDepthAttachment->resolveMode & phys_dev_props_core12.supportedDepthResolveModes)) {
+                    skip |= LogError(device, "VUID-VkRenderingInfoKHR-pDepthAttachment-06102",
+                        "vkCmdBeginRenderingKHR(): Includes a resolveMode structure with invalid mode=%u.",
+                        pRenderingInfo->pDepthAttachment->resolveMode);
+                }
+            }
+
+        }
+    }
+
+    if (pRenderingInfo->pStencilAttachment != NULL) {
+        skip |= ValidateRenderingAttachmentInfoKHR(commandBuffer, pRenderingInfo->pStencilAttachment);
+
+        if (pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
+            auto stencil_view_state = GetImageViewState(pRenderingInfo->pStencilAttachment->imageView);
+            IMAGE_STATE *image_state = stencil_view_state->image_state.get();
+            if (!(image_state->createInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06089",
+                    "vkCmdBeginRenderingKHR(): image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT");
+            }
+
+            if (pRenderingInfo->pStencilAttachment->imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06094",
+                    "vkCmdBeginRenderingKHR(): imageLayout must not be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+            }
+
+            if (pRenderingInfo->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE) {
+                if (pRenderingInfo->pStencilAttachment->resolveImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+                    skip |= LogError(
+                        commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06095",
+                        "vkCmdBeginRenderingKHR(): resolveImageLayout must not be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
+                }
+                if (pRenderingInfo->pStencilAttachment->resolveImageLayout ==
+                    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) {
+                    skip |= LogError(commandBuffer, "VUID-VkRenderingInfoKHR-pStencilAttachment-06099",
+                                     "vkCmdBeginRenderingKHR(): resolveImageLayout must not be "
+                                     "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL");
+                }
+                if (!(pRenderingInfo->pStencilAttachment->resolveMode & phys_dev_props_core12.supportedStencilResolveModes)) {
+                    skip |= LogError(device, "VUID-VkRenderingInfoKHR-pStencilAttachment-06103",
+                        "vkCmdBeginRenderingKHR(): Includes a resolveMode structure with invalid mode (%s).",
+                        string_VkResolveModeFlagBits(pRenderingInfo->pStencilAttachment->resolveMode));
+                }
+            }
+
+        }
+    }
+
+    return skip;
+}
+
+bool CoreChecks::ValidateRenderingAttachmentInfoKHR(VkCommandBuffer commandBuffer,
+                                                    const VkRenderingAttachmentInfoKHR *pAttachments) const {
+    const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
+    if (!cb_state) return false;
+    bool skip = false;
+
+    if (pAttachments->imageView != VK_NULL_HANDLE) {
+        auto image_view_state = GetImageViewState(pAttachments->imageView);
+        if (pAttachments->resolveMode != VK_RESOLVE_MODE_NONE && image_view_state->samples == VK_SAMPLE_COUNT_1_BIT) {
+            skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06132",
+                             "Image sample count must not have a VK_SAMPLE_COUNT_1_BIT for Resolve Mode %s",
+                             string_VkResolveModeFlags(pAttachments->resolveMode).c_str());
+        }
+
+        auto resolve_view_state = GetImageViewState(pAttachments->resolveImageView);
+        if (pAttachments->resolveMode != VK_RESOLVE_MODE_NONE && resolve_view_state->samples != VK_SAMPLE_COUNT_1_BIT) {
+            skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06133",
+                             "resolveImageView sample count must have a VK_SAMPLE_COUNT_1_BIT for Resolve Mode %s",
+                             string_VkResolveModeFlags(pAttachments->resolveMode).c_str());
+        }
+
+        if (pAttachments->resolveMode != VK_RESOLVE_MODE_NONE) {
+            if (image_view_state->create_info.format != resolve_view_state->create_info.format) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06134",
+                                 "resolveImageView format (%u) and ImageView format (%u) must have the same VkFormat",
+                                 resolve_view_state->create_info.format, image_view_state->create_info.format);
+            }
+
+            if (((pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_UNDEFINED) ||
+                 (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) ||
+                 (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) ||
+                 (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) ||
+                 (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) ||
+                 (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_PREINITIALIZED))) {
+                skip |= LogError(
+                    commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06136",
+                    "resolveImageLayout (%s) must not be VK_IMAGE_LAYOUT_UNDEFINED, "
+                    "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "
+                    "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, or VK_IMAGE_LAYOUT_PREINITIALIZED",
+                    string_VkImageLayout(pAttachments->resolveImageLayout));
+            }
+
+            if (((pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL) ||
+                 (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL))) {
+                skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06137",
+                                 "resolveImageLayout (%s) must not be VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, "
+                                 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL",
+                                 string_VkImageLayout(pAttachments->resolveImageLayout));
+            }
+        }
+
+        if ((pAttachments->imageLayout == VK_IMAGE_LAYOUT_UNDEFINED) ||
+            (pAttachments->imageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) ||
+            (pAttachments->imageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) ||
+            (pAttachments->imageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) ||
+            (pAttachments->imageLayout == VK_IMAGE_LAYOUT_PREINITIALIZED)) {
+            skip |= LogError(
+                commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06135",
+                "layout (%s) must not be VK_IMAGE_LAYOUT_UNDEFINED VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "
+                "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, or VK_IMAGE_LAYOUT_PREINITIALIZED",
+                string_VkImageLayout(pAttachments->imageLayout));
+        }
+
+        if (pAttachments->imageLayout == VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV) {
+            skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06138",
+                             "layout (%s) must not be VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV",
+                             string_VkImageLayout(pAttachments->imageLayout));
+        }
+
+        if (pAttachments->resolveImageLayout == VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV) {
+            skip |= LogError(commandBuffer, "VUID-VkRenderingAttachmentInfoKHR-imageView-06139",
+                             "layout (%s) must not be VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV",
+                             string_VkImageLayout(pAttachments->resolveImageLayout));
+        }
+    }
+
+    return skip;
+}
+
 bool CoreChecks::PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer,
                                                    const VkCommandBufferBeginInfo *pBeginInfo) const {
     const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
@@ -6422,7 +6905,6 @@
                              report_data->FormatHandle(commandBuffer).c_str());
         } else {
             if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
-                assert(info->renderPass);
                 const auto *framebuffer = GetFramebufferState(info->framebuffer);
                 if (framebuffer) {
                     if (framebuffer->createInfo.renderPass != info->renderPass) {
@@ -6433,6 +6915,22 @@
                                                                 "VUID-VkCommandBufferBeginInfo-flags-00055");
                     }
                 }
+
+                if (info->renderPass != VK_NULL_HANDLE) {
+                    const auto* render_pass = GetRenderPassState(info->renderPass);
+                    if (!render_pass) {
+                        skip |= LogError(commandBuffer, "VUID-VkCommandBufferBeginInfo-flags-06000",
+                            "Renderpass must be a valid VkRenderPass");
+                    }
+                } else {
+                    auto p_inherited_rendering_info = LvlFindInChain<VkCommandBufferInheritanceRenderingInfoKHR>(info->pNext);
+                    if (!p_inherited_rendering_info) {
+                        // The pNext chain of pInheritanceInfo must include a VkCommandBufferInheritanceRenderingInfoKHR structure
+                        skip |= LogError(commandBuffer, "VUID-VkCommandBufferBeginInfo-flags-06002",
+                                         "The pNext chain of pInheritanceInfo must include a "
+                                         "VkCommandBufferInheritanceRenderingInfoKHR structure");
+                    }
+                }
             }
             if ((info->occlusionQueryEnable == VK_FALSE || enabled_features.core.occlusionQueryPrecise == VK_FALSE) &&
                 (info->queryFlags & VK_QUERY_CONTROL_PRECISE_BIT)) {
@@ -6441,8 +6939,7 @@
                                  "occulusionQuery is disabled or the device does not support precise occlusion queries.",
                                  report_data->FormatHandle(commandBuffer).c_str());
             }
-            auto p_inherited_viewport_scissor_info =
-                    LvlFindInChain<VkCommandBufferInheritanceViewportScissorInfoNV>(info->pNext);
+            auto p_inherited_viewport_scissor_info = LvlFindInChain<VkCommandBufferInheritanceViewportScissorInfoNV>(info->pNext);
             if (p_inherited_viewport_scissor_info != nullptr && p_inherited_viewport_scissor_info->viewportScissor2D) {
                 if (!enabled_features.inherited_viewport_scissor_features.inheritedViewportScissor2D)
                 {
@@ -8487,9 +8984,8 @@
 
     skip |= ValidatePipelineStage(objects, loc.dot(Field::srcStageMask), queue_flags, srcStageMask);
     skip |= ValidatePipelineStage(objects, loc.dot(Field::dstStageMask), queue_flags, dstStageMask);
-
     skip |= ValidateCmd(cb_state, CMD_PIPELINEBARRIER);
-    if (cb_state->activeRenderPass) {
+    if (cb_state->activeRenderPass && !cb_state->activeRenderPass->use_dynamic_rendering) {
         skip |= ValidateRenderPassPipelineBarriers(loc, cb_state, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
                                                    pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                                    imageMemoryBarrierCount, pImageMemoryBarriers);
@@ -12487,7 +12983,7 @@
                                      "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT set in VkCommandBufferBeginInfo::flags when "
                                      "the vkBeginCommandBuffer() was called.",
                                      report_data->FormatHandle(pCommandBuffers[i]).c_str());
-                } else if (cb_state->activeRenderPass &&
+                } else if (cb_state->activeRenderPass && (cb_state->activeRenderPass->use_dynamic_rendering == false) &&
                            (sub_cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
                     // Make sure render pass is compatible with parent command buffer pass if has continue
                     if (cb_state->activeRenderPass->renderPass() != secondary_rp_state->renderPass()) {
diff --git a/layers/core_validation.h b/layers/core_validation.h
index 170b6b2..5579f78 100644
--- a/layers/core_validation.h
+++ b/layers/core_validation.h
@@ -621,9 +621,8 @@
                                  const char* param_name) const;
 
     bool ValidateClearAttachmentExtent(VkCommandBuffer command_buffer, uint32_t attachment_index,
-                                       const FRAMEBUFFER_STATE* framebuffer, uint32_t fb_attachment, const VkRect2D& render_area,
-                                       uint32_t rect_count, const VkClearRect* clear_rects,
-                                       const CMD_BUFFER_STATE* primary_cb_state = nullptr) const;
+                                       const IMAGE_VIEW_STATE *image_view_state, const VkRect2D& render_area,
+                                       uint32_t rect_count, const VkClearRect* clear_rects) const;
 
     template <typename ImageCopyRegionType>
     bool ValidateImageCopyData(const uint32_t regionCount, const ImageCopyRegionType* ic_regions, const IMAGE_STATE* src_state,
@@ -1085,6 +1084,9 @@
                                              const VkCopyDescriptorSet* pDescriptorCopies) const override;
     bool PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer,
                                            const VkCommandBufferBeginInfo* pBeginInfo) const override;
+    bool PreCallValidateCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
+                                             const VkRenderingInfoKHR* pRenderingInfo) const override;
+    bool ValidateRenderingAttachmentInfoKHR(VkCommandBuffer commandBuffer, const VkRenderingAttachmentInfoKHR* pAttachments) const;
     bool PreCallValidateEndCommandBuffer(VkCommandBuffer commandBuffer) const override;
     bool PreCallValidateResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) const override;
     bool PreCallValidateCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
@@ -1630,4 +1632,4 @@
     bool PreCallValidateGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
                                                                     Display* dpy, VisualID visualID) const override;
 #endif  // VK_USE_PLATFORM_XLIB_KHR
-};  // Class CoreChecks
+};      // Class CoreChecks
diff --git a/layers/generated/layer_chassis_dispatch.cpp b/layers/generated/layer_chassis_dispatch.cpp
index 26c3a0a..1c10fc9 100644
--- a/layers/generated/layer_chassis_dispatch.cpp
+++ b/layers/generated/layer_chassis_dispatch.cpp
@@ -264,6 +264,12 @@
                 }
             }
 
+            auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(pCreateInfos[idx0].pNext);
+            if (dynamic_rendering) {
+                uses_color_attachment        = (dynamic_rendering->colorAttachmentCount > 0);
+                uses_depthstencil_attachment = (dynamic_rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED);
+            }
+
             local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0], uses_color_attachment, uses_depthstencil_attachment);
 
             if (pCreateInfos[idx0].basePipelineHandle) {
diff --git a/layers/object_tracker_utils.cpp b/layers/object_tracker_utils.cpp
index 649454a..55b0890 100644
--- a/layers/object_tracker_utils.cpp
+++ b/layers/object_tracker_utils.cpp
@@ -495,8 +495,8 @@
                     ValidateObject(begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
                                    "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
                 skip |=
-                    ValidateObject(begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
-                                   "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
+                    ValidateObject(begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, true,
+                                   "VUID-VkCommandBufferBeginInfo-flags-06000", "VUID-VkCommandBufferInheritanceInfo-commonparent");
             }
         }
     }
diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp
index f78a39d..0f1f39d 100644
--- a/layers/parameter_validation_utils.cpp
+++ b/layers/parameter_validation_utils.cpp
@@ -4126,6 +4126,8 @@
         if (info) {
             const VkStructureType allowed_structs_vk_command_buffer_inheritance_info[] = {
                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT,
+                VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,
+                VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD,
                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV};
             skip |= validate_struct_pnext(
                 cmd_name, "pBeginInfo->pInheritanceInfo->pNext", "VkCommandBufferInheritanceConditionalRenderingInfoEXT",
diff --git a/layers/pipeline_state.cpp b/layers/pipeline_state.cpp
index 84b2eb6..4669859 100644
--- a/layers/pipeline_state.cpp
+++ b/layers/pipeline_state.cpp
@@ -28,7 +28,6 @@
 #include "pipeline_state.h"
 #include "descriptor_sets.h"
 #include "cmd_buffer_state.h"
-#include "render_pass_state.h"
 #include "state_tracker.h"
 #include "shader_module.h"
 
@@ -360,8 +359,7 @@
                                std::shared_ptr<const RENDER_PASS_STATE> &&rpstate,
                                std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
     : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
-      create_info(pCreateInfo, rpstate->UsesColorAttachment(pCreateInfo->subpass),
-                  rpstate->UsesDepthStencilAttachment(pCreateInfo->subpass)),
+      create_info(pCreateInfo, rpstate),
       pipeline_layout(std::move(layout)),
       rp_state(rpstate),
       stage_state(GetStageStates(state_data, create_info.graphics.pStages, create_info.graphics.stageCount)),
diff --git a/layers/pipeline_state.h b/layers/pipeline_state.h
index 4397db3..b4e5eee 100644
--- a/layers/pipeline_state.h
+++ b/layers/pipeline_state.h
@@ -30,6 +30,7 @@
 #include "base_node.h"
 #include "sampler_state.h"
 #include "ray_tracing_state.h"
+#include "render_pass_state.h"
 #include "shader_module.h"
 
 // Fwd declarations -- including descriptor_set.h creates an ugly include loop
@@ -163,8 +164,24 @@
 class PIPELINE_STATE : public BASE_NODE {
   public:
     union CreateInfo {
-        CreateInfo(const VkGraphicsPipelineCreateInfo *ci, bool uses_color, bool uses_depth_stencil)
-            : graphics(ci, uses_color, uses_depth_stencil) {}
+        CreateInfo(const VkGraphicsPipelineCreateInfo *ci, std::shared_ptr<const RENDER_PASS_STATE> rpstate) {
+            bool use_color = false;
+            bool use_depth = false;
+
+            
+            if (ci->renderPass == VK_NULL_HANDLE) {
+                auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(ci->pNext);
+                if (dynamic_rendering) {
+                    use_color = (dynamic_rendering->colorAttachmentCount > 0);
+                    use_depth = (dynamic_rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED);
+                }
+            } else {
+                use_color = rpstate->UsesColorAttachment(ci->subpass);
+                use_depth = rpstate->UsesDepthStencilAttachment(ci->subpass);
+            }
+
+            graphics.initialize(ci, use_color, use_depth);
+        }
         CreateInfo(const VkComputePipelineCreateInfo *ci) : compute(ci) {}
         CreateInfo(const VkRayTracingPipelineCreateInfoKHR *ci) : raytracing(ci) {}
         CreateInfo(const VkRayTracingPipelineCreateInfoNV *ci) : raytracing(ci) {}
diff --git a/layers/render_pass_state.cpp b/layers/render_pass_state.cpp
index db0d71e..f372cef 100644
--- a/layers/render_pass_state.cpp
+++ b/layers/render_pass_state.cpp
@@ -239,7 +239,7 @@
 }
 
 RENDER_PASS_STATE::RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo2 const *pCreateInfo)
-    : BASE_NODE(rp, kVulkanObjectTypeRenderPass), createInfo(pCreateInfo) {
+    : BASE_NODE(rp, kVulkanObjectTypeRenderPass), use_dynamic_rendering(false), use_dynamic_rendering_inherited(false), createInfo(pCreateInfo) {
     InitRenderPassState(this);
 }
 
@@ -250,10 +250,26 @@
 }
 
 RENDER_PASS_STATE::RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo const *pCreateInfo)
-    : BASE_NODE(rp, kVulkanObjectTypeRenderPass), createInfo(ConvertCreateInfo(*pCreateInfo)) {
+    : BASE_NODE(rp, kVulkanObjectTypeRenderPass), use_dynamic_rendering(false), use_dynamic_rendering_inherited(false), createInfo(ConvertCreateInfo(*pCreateInfo)) {
     InitRenderPassState(this);
 }
 
+const VkPipelineRenderingCreateInfoKHR VkPipelineRenderingCreateInfoKHR_default = {
+    VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
+    nullptr,
+    0,
+    0,
+    nullptr,
+    VK_FORMAT_UNDEFINED,
+    VK_FORMAT_UNDEFINED
+};
+
+RENDER_PASS_STATE::RENDER_PASS_STATE(VkPipelineRenderingCreateInfoKHR const *pPipelineRenderingCreateInfo)
+    : BASE_NODE(static_cast<VkRenderPass>(VK_NULL_HANDLE), kVulkanObjectTypeRenderPass),
+      use_dynamic_rendering(true),
+      use_dynamic_rendering_inherited(false),
+      rendering_create_info(pPipelineRenderingCreateInfo ? pPipelineRenderingCreateInfo : &VkPipelineRenderingCreateInfoKHR_default) {}
+
 bool RENDER_PASS_STATE::UsesColorAttachment(uint32_t subpass_num) const {
     bool result = false;
 
@@ -281,6 +297,18 @@
     return result;
 }
 
+RENDER_PASS_STATE::RENDER_PASS_STATE(VkRenderingInfoKHR const *pRenderingInfo)
+    : BASE_NODE(static_cast<VkRenderPass>(VK_NULL_HANDLE), kVulkanObjectTypeRenderPass),
+      use_dynamic_rendering(true),
+      use_dynamic_rendering_inherited(false),
+      dynamic_rendering_info(pRenderingInfo) {}
+
+RENDER_PASS_STATE::RENDER_PASS_STATE(VkCommandBufferInheritanceRenderingInfoKHR const* pInheritanceRenderingInfo)
+    : BASE_NODE(static_cast<VkRenderPass>(VK_NULL_HANDLE), kVulkanObjectTypeRenderPass),
+    use_dynamic_rendering(true),
+    use_dynamic_rendering_inherited(true),
+    inheritance_rendering_info(pInheritanceRenderingInfo) {}
+
 FRAMEBUFFER_STATE::FRAMEBUFFER_STATE(VkFramebuffer fb, const VkFramebufferCreateInfo *pCreateInfo,
                                      std::shared_ptr<RENDER_PASS_STATE> &&rpstate,
                                      std::vector<std::shared_ptr<IMAGE_VIEW_STATE>> &&attachments)
@@ -294,10 +322,9 @@
 }
 
 void FRAMEBUFFER_STATE::Destroy() {
-    for (auto& view: attachments_view_state) {
+    for (auto &view : attachments_view_state) {
         view->RemoveParent(this);
     }
     attachments_view_state.clear();
     BASE_NODE::Destroy();
 }
-
diff --git a/layers/render_pass_state.h b/layers/render_pass_state.h
index f094469..502a7d5 100644
--- a/layers/render_pass_state.h
+++ b/layers/render_pass_state.h
@@ -88,6 +88,11 @@
         AttachmentTransition(uint32_t prev_pass_, uint32_t attachment_, VkImageLayout old_layout_, VkImageLayout new_layout_)
             : prev_pass(prev_pass_), attachment(attachment_), old_layout(old_layout_), new_layout(new_layout_) {}
     };
+    const bool use_dynamic_rendering;
+    const bool use_dynamic_rendering_inherited;
+    safe_VkRenderingInfoKHR dynamic_rendering_info;
+    const safe_VkPipelineRenderingCreateInfoKHR rendering_create_info;
+    const safe_VkCommandBufferInheritanceRenderingInfoKHR inheritance_rendering_info;
     const safe_VkRenderPassCreateInfo2 createInfo;
     using SubpassVec = std::vector<uint32_t>;
     using SelfDepVec = std::vector<SubpassVec>;
@@ -108,6 +113,10 @@
     RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo2 const *pCreateInfo);
     RENDER_PASS_STATE(VkRenderPass rp, VkRenderPassCreateInfo const *pCreateInfo);
 
+    RENDER_PASS_STATE(VkPipelineRenderingCreateInfoKHR const *pPipelineRenderingCreateInfo);
+    RENDER_PASS_STATE(VkRenderingInfoKHR const *pRenderingInfo);
+    RENDER_PASS_STATE(VkCommandBufferInheritanceRenderingInfoKHR const *pInheritanceRenderingInfo);
+
     VkRenderPass renderPass() const { return handle_.Cast<VkRenderPass>(); }
 
     bool UsesColorAttachment(uint32_t subpass) const;
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index fca93d5..87a045e 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -200,8 +200,6 @@
                                                     PIPELINE_STATE const *pipeline, uint32_t subpass_index) const {
     bool skip = false;
 
-    const auto rpci = pipeline->rp_state->createInfo.ptr();
-
     struct Attachment {
         const VkAttachmentReference2 *reference = nullptr;
         const VkAttachmentDescription2 *attachment = nullptr;
@@ -209,13 +207,16 @@
     };
     std::map<uint32_t, Attachment> location_map;
 
-    const auto subpass = rpci->pSubpasses[subpass_index];
-    for (uint32_t i = 0; i < subpass.colorAttachmentCount; ++i) {
-        auto const &reference = subpass.pColorAttachments[i];
-        location_map[i].reference = &reference;
-        if (reference.attachment != VK_ATTACHMENT_UNUSED &&
-            rpci->pAttachments[reference.attachment].format != VK_FORMAT_UNDEFINED) {
-            location_map[i].attachment = &rpci->pAttachments[reference.attachment];
+    if (pipeline->rp_state && !pipeline->rp_state->use_dynamic_rendering) {
+        const auto rpci = pipeline->rp_state->createInfo.ptr();
+        const auto subpass = rpci->pSubpasses[subpass_index];
+        for (uint32_t i = 0; i < subpass.colorAttachmentCount; ++i) {
+            auto const &reference = subpass.pColorAttachments[i];
+            location_map[i].reference = &reference;
+            if (reference.attachment != VK_ATTACHMENT_UNUSED &&
+                rpci->pAttachments[reference.attachment].format != VK_FORMAT_UNDEFINED) {
+                location_map[i].attachment = &rpci->pAttachments[reference.attachment];
+            }
         }
     }
 
@@ -1054,7 +1055,6 @@
                 }
                 break;
             }
-
         }
     }
 
@@ -1109,8 +1109,13 @@
     }
 
     if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
-        // "For the fragment shader stage the framebuffer color attachments also count against this limit"
-        total_resources += pipeline->rp_state->createInfo.pSubpasses[pipeline->create_info.graphics.subpass].colorAttachmentCount;
+        if (pipeline->rp_state->use_dynamic_rendering) {
+            total_resources += pipeline->rp_state->rendering_create_info.colorAttachmentCount;
+        } else {
+            // "For the fragment shader stage the framebuffer color attachments also count against this limit"
+            total_resources +=
+                pipeline->rp_state->createInfo.pSubpasses[pipeline->create_info.graphics.subpass].colorAttachmentCount;
+        }
     }
 
     // TODO: This reuses a lot of GetDescriptorCountMaxPerStage but currently would need to make it agnostic in a way to handle
@@ -2546,23 +2551,25 @@
     if (pStage->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
         auto input_attachment_uses = module->CollectInterfaceByInputAttachmentIndex(accessible_ids);
 
-        auto rpci = pipeline->rp_state->createInfo.ptr();
-        auto subpass = pipeline->create_info.graphics.subpass;
+        if (!pipeline->rp_state->use_dynamic_rendering) {
+            auto rpci = pipeline->rp_state->createInfo.ptr();
+            auto subpass = pipeline->create_info.graphics.subpass;
+            for (auto use : input_attachment_uses) {
+                auto input_attachments = rpci->pSubpasses[subpass].pInputAttachments;
+                auto index = (input_attachments && use.first < rpci->pSubpasses[subpass].inputAttachmentCount)
+                    ? input_attachments[use.first].attachment
+                    : VK_ATTACHMENT_UNUSED;
 
-        for (auto use : input_attachment_uses) {
-            auto input_attachments = rpci->pSubpasses[subpass].pInputAttachments;
-            auto index = (input_attachments && use.first < rpci->pSubpasses[subpass].inputAttachmentCount)
-                             ? input_attachments[use.first].attachment
-                             : VK_ATTACHMENT_UNUSED;
-
-            if (index == VK_ATTACHMENT_UNUSED) {
-                skip |= LogError(device, kVUID_Core_Shader_MissingInputAttachment,
-                                 "Shader consumes input attachment index %d but not provided in subpass", use.first);
-            } else if (!(GetFormatType(rpci->pAttachments[index].format) & module->GetFundamentalType(use.second.type_id))) {
-                skip |=
-                    LogError(device, kVUID_Core_Shader_InputAttachmentTypeMismatch,
-                             "Subpass input attachment %u format of %s does not match type used in shader `%s`", use.first,
-                             string_VkFormat(rpci->pAttachments[index].format), module->DescribeType(use.second.type_id).c_str());
+                if (index == VK_ATTACHMENT_UNUSED) {
+                    skip |= LogError(device, kVUID_Core_Shader_MissingInputAttachment,
+                        "Shader consumes input attachment index %d but not provided in subpass", use.first);
+                }
+                else if (!(GetFormatType(rpci->pAttachments[index].format) & module->GetFundamentalType(use.second.type_id))) {
+                    skip |=
+                        LogError(device, kVUID_Core_Shader_InputAttachmentTypeMismatch,
+                            "Subpass input attachment %u format of %s does not match type used in shader `%s`", use.first,
+                            string_VkFormat(rpci->pAttachments[index].format), module->DescribeType(use.second.type_id).c_str());
+                }
             }
         }
     }
@@ -2766,7 +2773,6 @@
                     ValidateInterfaceBetweenStages(producer.module.get(), producer.entrypoint, &shader_stage_attribs[producer_id],
                                                    consumer.module.get(), consumer.entrypoint, &shader_stage_attribs[consumer_id]);
             }
-
         }
     }
 
diff --git a/layers/state_tracker.cpp b/layers/state_tracker.cpp
index 489ab4f..0ff3a29 100644
--- a/layers/state_tracker.cpp
+++ b/layers/state_tracker.cpp
@@ -182,7 +182,6 @@
 void ValidationStateTracker::PreCallRecordCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
                                                              VkImageLayout imageLayout, const VkClearColorValue *pColor,
                                                              uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
-
     if (disabled[command_buffer_state]) return;
 
     auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
@@ -392,7 +391,6 @@
 
 void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
                                                                    const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) {
-
     if (disabled[command_buffer_state]) return;
 
     auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
@@ -1819,13 +1817,15 @@
     cgpl_state->pCreateInfos = pCreateInfos;  // GPU validation can alter this, so we have to set a default value for the Chassis
     cgpl_state->pipe_state.reserve(count);
     for (uint32_t i = 0; i < count; i++) {
-        // Avoid crashes if VK_KHR_dynamic_rendering is in use.
         if (pCreateInfos[i].renderPass != VK_NULL_HANDLE) {
             cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i],
                                                                               GetRenderPassShared(pCreateInfos[i].renderPass),
                                                                               GetPipelineLayoutShared(pCreateInfos[i].layout)));
-        } else {
-            cgpl_state->pipe_state.push_back(std::shared_ptr<PIPELINE_STATE>());
+        } else if (enabled_features.dynamic_rendering_features.dynamicRendering) {
+            auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(pCreateInfos[i].pNext);
+            cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i],
+                                                                              std::make_shared<RENDER_PASS_STATE>(dynamic_rendering),
+                                                                              GetPipelineLayoutShared(pCreateInfos[i].layout)));
         }
     }
     return false;
@@ -2427,7 +2427,6 @@
     cb_state->RecordStateCmd(CMD_SETSTENCILREFERENCE, CBSTATUS_STENCIL_REFERENCE_SET);
 }
 
-
 // Update the bound state for the bind point, including the effects of incompatible pipeline layouts
 void ValidationStateTracker::PreCallRecordCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
                                                                 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
@@ -2793,6 +2792,28 @@
     cb_state->conditional_rendering_subpass = 0;
 }
 
+void ValidationStateTracker::RecordCmdBeginRenderingRenderPassState(VkCommandBuffer commandBuffer,
+                                                                    const VkRenderingInfoKHR *pRenderingInfo) {
+    auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
+    cb_state->activeRenderPass = std::make_shared<RENDER_PASS_STATE>(pRenderingInfo);
+}
+
+void ValidationStateTracker::RecordCmdEndRenderingRenderPassState(VkCommandBuffer commandBuffer) {
+    auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
+    cb_state->activeRenderPass = nullptr;
+}
+
+void ValidationStateTracker::PreCallRecordCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
+                                                               const VkRenderingInfoKHR *pRenderingInfo) {
+    RecordCmdBeginRenderingRenderPassState(commandBuffer, pRenderingInfo);
+    CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
+    cb_state->BeginRendering(CMD_BEGINRENDERINGKHR, pRenderingInfo);
+}
+
+void ValidationStateTracker::PreCallRecordCmdEndRenderingKHR(VkCommandBuffer commandBuffer) {
+    RecordCmdEndRenderingRenderPassState(commandBuffer);
+}
+
 void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
                                                               const VkRenderPassBeginInfo *pRenderPassBegin,
                                                               const VkSubpassBeginInfo *pSubpassBeginInfo) {
@@ -2800,7 +2821,6 @@
     cb_state->BeginRenderPass(CMD_BEGINRENDERPASS2, pRenderPassBegin, pSubpassBeginInfo->contents);
 }
 
-
 void ValidationStateTracker::PostCallRecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
     CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
     cb_state->NextSubpass(CMD_NEXTSUBPASS, contents);
@@ -3847,7 +3867,6 @@
     cb_state->hasTraceRaysCmd = true;
 }
 
-
 void ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
                                                const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
                                                const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
diff --git a/layers/state_tracker.h b/layers/state_tracker.h
index 535e224..1d57bd9 100644
--- a/layers/state_tracker.h
+++ b/layers/state_tracker.h
@@ -414,6 +414,7 @@
     std::shared_ptr<RENDER_PASS_STATE> GetRenderPassShared(VkRenderPass renderpass) {
         return GetShared<RENDER_PASS_STATE>(renderpass);
     }
+
     const RENDER_PASS_STATE* GetRenderPassState(VkRenderPass renderpass) const { return Get<RENDER_PASS_STATE>(renderpass); }
     RENDER_PASS_STATE* GetRenderPassState(VkRenderPass renderpass) { return Get<RENDER_PASS_STATE>(renderpass); }
 
@@ -909,6 +910,8 @@
                                                VkQueryControlFlags flags, uint32_t index) override;
     void PreCallRecordCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
                                          VkSubpassContents contents) override;
+    void PreCallRecordCmdBeginRenderingKHR(VkCommandBuffer commandBuffer, const VkRenderingInfoKHR* pRenderingInfo) override;
+    void PreCallRecordCmdEndRenderingKHR(VkCommandBuffer commandBuffer) override;
     void PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
                                           const VkSubpassBeginInfo* pSubpassBeginInfo) override;
     void PreCallRecordCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
@@ -1197,6 +1200,8 @@
     void RecordCreateDescriptorUpdateTemplateState(const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
                                                    VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate);
     void RecordMappedMemory(VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, void** ppData);
+    void RecordCmdBeginRenderingRenderPassState(VkCommandBuffer commandBuffer, const VkRenderingInfoKHR* pRenderingInfo);
+    void RecordCmdEndRenderingRenderPassState(VkCommandBuffer commandBuffer);
     void RecordVulkanSurface(VkSurfaceKHR* pSurface);
     void RecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout, VkResult result);
     void RecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t* pValue, VkResult result);
diff --git a/scripts/layer_chassis_dispatch_generator.py b/scripts/layer_chassis_dispatch_generator.py
index 5508a05..cb9fdc7 100644
--- a/scripts/layer_chassis_dispatch_generator.py
+++ b/scripts/layer_chassis_dispatch_generator.py
@@ -190,6 +190,12 @@
                 }
             }
 
+            auto dynamic_rendering = LvlFindInChain<VkPipelineRenderingCreateInfoKHR>(pCreateInfos[idx0].pNext);
+            if (dynamic_rendering) {
+                uses_color_attachment        = (dynamic_rendering->colorAttachmentCount > 0);
+                uses_depthstencil_attachment = (dynamic_rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED);
+            }
+
             local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0], uses_color_attachment, uses_depthstencil_attachment);
 
             if (pCreateInfos[idx0].basePipelineHandle) {
diff --git a/tests/vklayertests_command.cpp b/tests/vklayertests_command.cpp
index 2de98c1..bffd23d 100644
--- a/tests/vklayertests_command.cpp
+++ b/tests/vklayertests_command.cpp
@@ -703,7 +703,7 @@
     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
 
-    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferBeginInfo-flags-00053");
+    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferBeginInfo-flags-06002");
     vk::BeginCommandBuffer(cb.handle(), &cmd_buf_info);
     m_errorMonitor->VerifyFound();
 }