layers:Add image layout validation for descriptors

This change adds validation to make sure that an image layout at the
time the image is used in a descriptor matches the layout that was
given when the descriptor was updated.

Because image view covers a range of mip levels, loop over each level
and verify layouts one at a time.

Also Updated a number of validate functions to use cont ptr params for
data that they aren't changing.
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp
index 84663c4..de34945 100644
--- a/layers/descriptor_sets.cpp
+++ b/layers/descriptor_sets.cpp
@@ -24,6 +24,7 @@
 #include "descriptor_sets.h"
 #include "vk_enum_string_helper.h"
 #include "vk_safe_struct.h"
+#include "buffer_validation.h"
 #include <sstream>
 #include <algorithm>
 
@@ -395,7 +396,8 @@
 //  that any update buffers are valid, and that any dynamic offsets are within the bounds of their buffers.
 // Return true if state is acceptable, or false and write an error message into error string
 bool cvdescriptorset::DescriptorSet::ValidateDrawState(const std::map<uint32_t, descriptor_req> &bindings,
-                                                       const std::vector<uint32_t> &dynamic_offsets, std::string *error) const {
+                                                       const std::vector<uint32_t> &dynamic_offsets, const GLOBAL_CB_NODE *cb_node,
+                                                       const char *caller, std::string *error) const {
     for (auto binding_pair : bindings) {
         auto binding = binding_pair.first;
         if (!p_layout_->HasBinding(binding)) {
@@ -472,9 +474,15 @@
                             }
                         }
                     } else if (descriptor_class == ImageSampler || descriptor_class == Image) {
-                        auto image_view = (descriptor_class == ImageSampler)
-                                              ? static_cast<ImageSamplerDescriptor *>(descriptors_[i].get())->GetImageView()
-                                              : static_cast<ImageDescriptor *>(descriptors_[i].get())->GetImageView();
+                        VkImageView image_view;
+                        VkImageLayout image_layout;
+                        if (descriptor_class == ImageSampler) {
+                            image_view = static_cast<ImageSamplerDescriptor *>(descriptors_[i].get())->GetImageView();
+                            image_layout = static_cast<ImageSamplerDescriptor *>(descriptors_[i].get())->GetImageLayout();
+                        } else {
+                            image_view = static_cast<ImageDescriptor *>(descriptors_[i].get())->GetImageView();
+                            image_layout = static_cast<ImageDescriptor *>(descriptors_[i].get())->GetImageLayout();
+                        }
                         auto reqs = binding_pair.second;
 
                         auto image_view_state = GetImageViewState(device_data_, image_view);
@@ -493,7 +501,30 @@
 
                         auto image_node = GetImageState(device_data_, image_view_ci.image);
                         assert(image_node);
-
+                        // Verify Image Layout
+                        // TODO: VALIDATION_ERROR_02981 is the error physically closest to the spec language of interest, however
+                        //  there is no VUID for the actual spec language. Need to file a spec MR to add VU language for:
+                        // imageLayout is the layout that the image subresources accessible from imageView will be in at the time
+                        // this descriptor is accessed.
+                        // Copy first mip level into sub_layers and loop over each mip level to verify layout
+                        VkImageSubresourceLayers sub_layers;
+                        sub_layers.aspectMask = image_view_ci.subresourceRange.aspectMask;
+                        sub_layers.baseArrayLayer = image_view_ci.subresourceRange.baseArrayLayer;
+                        sub_layers.layerCount = image_view_ci.subresourceRange.layerCount;
+                        bool hit_error = false;
+                        for (auto cur_level = image_view_ci.subresourceRange.baseMipLevel;
+                             cur_level < image_view_ci.subresourceRange.levelCount; ++cur_level) {
+                            sub_layers.mipLevel = cur_level;
+                            VerifyImageLayout(device_data_, cb_node, image_node, sub_layers, image_layout,
+                                              VK_IMAGE_LAYOUT_UNDEFINED, caller, VALIDATION_ERROR_02981, &hit_error);
+                            if (hit_error) {
+                                *error =
+                                    "Image layout specified at vkUpdateDescriptorSets() time doesn't match actual image layout at "
+                                    "time descriptor is used. See previous error callback for specific details.";
+                                return false;
+                            }
+                        }
+                        // Verify Sample counts
                         if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) && image_node->createInfo.samples != VK_SAMPLE_COUNT_1_BIT) {
                             std::stringstream error_str;
                             error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
@@ -502,7 +533,6 @@
                             *error = error_str.str();
                             return false;
                         }
-
                         if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) && image_node->createInfo.samples == VK_SAMPLE_COUNT_1_BIT) {
                             std::stringstream error_str;
                             error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i