layers: Avoid crashing if VK_KHR_dynamic_rendering is enabled

Handle null render pass handles in vkCreateGraphicsPipeline().
This is an error if the feature is not enabled. But it needs to
fail in any case until the pipeline creation code can be
updated to properly create state objects using the extension.
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index ab3de7f..7ebaa3a 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -5447,6 +5447,25 @@
     create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
 
     for (uint32_t i = 0; i < count; i++) {
+        if (pCreateInfos[i].renderPass == VK_NULL_HANDLE) {
+            if (!enabled_features.dynamic_rendering_features.dynamicRendering) {
+                skip |= LogError(device, "VUID-VkGraphicsPipelineCreateInfo-dynamicRendering-06052",
+                                 "vkCreateGraphicsPipeline: pCreateInfos[%" PRIu32
+                                 "].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;
+        }
+    }
+
+    for (uint32_t i = 0; i < count; i++) {
         skip |= ValidatePipelineLocked(cgpl_state->pipe_state, i);
     }
 
diff --git a/layers/device_state.h b/layers/device_state.h
index 11ec2b5..9cda05c 100644
--- a/layers/device_state.h
+++ b/layers/device_state.h
@@ -89,6 +89,7 @@
     VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroup_size_control_features;
     VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT rgba10x6_formats_features;
     VkPhysicalDeviceMaintenance4FeaturesKHR maintenance4_features;
+    VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamic_rendering_features;
     // If a new feature is added here that involves a SPIR-V capability add also in spirv_validation_generator.py
     // This is known by checking the table in the spec or if the struct is in a <spirvcapability> in vk.xml
 };
diff --git a/layers/state_tracker.cpp b/layers/state_tracker.cpp
index 3c3b692..489ab4f 100644
--- a/layers/state_tracker.cpp
+++ b/layers/state_tracker.cpp
@@ -958,6 +958,11 @@
         if (maintenance4_features) {
             state_tracker->enabled_features.maintenance4_features = *maintenance4_features;
         }
+
+        const auto *dynamic_rendering_features = LvlFindInChain<VkPhysicalDeviceDynamicRenderingFeaturesKHR>(pCreateInfo->pNext);
+        if (dynamic_rendering_features) {
+            state_tracker->enabled_features.dynamic_rendering_features = *dynamic_rendering_features;
+        }
     }
 
     const auto *subgroup_size_control_features = LvlFindInChain<VkPhysicalDeviceSubgroupSizeControlFeaturesEXT>(pCreateInfo->pNext);
@@ -1814,9 +1819,14 @@
     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++) {
-        cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i],
-                                                                          GetRenderPassShared(pCreateInfos[i].renderPass),
-                                                                          GetPipelineLayoutShared(pCreateInfos[i].layout)));
+        // 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>());
+        }
     }
     return false;
 }