intel,layers,tests: move cmd_meta errors to validation

Add checks for alignment in DeviceLimits layer.
Add checks for type, format and sample count in Images layer.
Remove such checks from intel icd.
Add new validations to layer_validation_tests.
diff --git a/icd/intel/cmd_meta.c b/icd/intel/cmd_meta.c
index 84cca2c..2fca856 100644
--- a/icd/intel/cmd_meta.c
+++ b/icd/intel/cmd_meta.c
@@ -489,9 +489,6 @@
     bool raw_copy = false;
     uint32_t i;
 
-    /* TODOVV: verify validation */
-    assert((src->type == dst->type) && "Mismatched source and destination types");
-
     if (src->layout.format == dst->layout.format) {
         raw_copy = true;
         raw_format = cmd_meta_img_raw_format(cmd, src->layout.format);
@@ -726,10 +723,6 @@
     uint32_t *ptr;
     uint32_t offset;
 
-    /* TODOVV: Is this an API requirement or driver requirement? */
-    /* must be 4-byte aligned */
-    assert(!((destOffset | dataSize) & 3) && "Offset and Size must be 4-byte aligned");
-
     /* write to dynamic state writer first */
     offset = cmd_state_pointer(cmd, INTEL_CMD_ITEM_BLOB, 32,
             (dataSize + 3) / 4, &ptr);
@@ -770,10 +763,6 @@
     struct intel_cmd_meta meta;
     VkFormat format;
 
-    /* TODOVV: Is this an API requirement or driver requirement? */
-    /* must be 4-byte aligned */
-    assert(!((destOffset | fillSize) & 3) && "Offset and Size must be 4-byte aligned");
-
     memset(&meta, 0, sizeof(meta));
     meta.mode = INTEL_CMD_META_VS_POINTS;
 
@@ -1055,10 +1044,6 @@
     VkFormat format;
     uint32_t i;
 
-    /* TODOVV: Add validation */
-    assert(!(src->samples <= 1 || dst->samples > 1 ||
-        src->layout.format != dst->layout.format) && "Invalid vkCmdResolveImage");
-
     memset(&meta, 0, sizeof(meta));
     meta.mode = INTEL_CMD_META_FS_RECT;
 
diff --git a/layers/device_limits.cpp b/layers/device_limits.cpp
index b991a86..12ec483 100644
--- a/layers/device_limits.cpp
+++ b/layers/device_limits.cpp
@@ -552,6 +552,66 @@
     return result;
 }
 
+VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(
+    VkCmdBuffer cmdBuffer,
+    VkBuffer destBuffer,
+    VkDeviceSize destOffset,
+    VkDeviceSize dataSize,
+    const uint32_t* pData)
+{
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+
+    // destOffset is the byte offset into the buffer to start updating and must be a multiple of 4.
+    if (destOffset & 3) {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+        if (log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, 1, "DL",
+        "vkCmdUpdateBuffer parameter, VkDeviceSize destOffset, is not a multiple of 4")) {
+            return;
+        }
+    }
+
+    // dataSize is the number of bytes to update, which must be a multiple of 4.
+    if (dataSize & 3) {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+        if (log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, 1, "DL",
+        "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4")) {
+            return;
+        }
+    }
+
+    dev_data->device_dispatch_table->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
+}
+
+VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(
+    VkCmdBuffer cmdBuffer,
+    VkBuffer destBuffer,
+    VkDeviceSize destOffset,
+    VkDeviceSize fillSize,
+    uint32_t data)
+{
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+
+    // destOffset is the byte offset into the buffer to start filling and must be a multiple of 4.
+    if (destOffset & 3) {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+        if (log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, 1, "DL",
+        "vkCmdFillBuffer parameter, VkDeviceSize destOffset, is not a multiple of 4")) {
+            return;
+        }
+    }
+
+    // fillSize is the number of bytes to fill, which must be a multiple of 4.
+    if (fillSize & 3) {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+        if (log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, 1, "DL",
+        "vkCmdFillBuffer parameter, VkDeviceSize fillSize, is not a multiple of 4")) {
+            return;
+        }
+    }
+
+    dev_data->device_dispatch_table->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
+}
+
 VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
     VkInstance                          instance,
     VkFlags                             msgFlags,
@@ -610,6 +670,10 @@
         return (PFN_vkVoidFunction) vkCreateCommandBuffer;
     if (!strcmp(funcName, "vkDestroyCommandBuffer"))
         return (PFN_vkVoidFunction) vkDestroyCommandBuffer;
+    if (!strcmp(funcName, "vkCmdUpdateBuffer"))
+        return (PFN_vkVoidFunction) vkCmdUpdateBuffer;
+    if (!strcmp(funcName, "vkCmdFillBuffer"))
+        return (PFN_vkVoidFunction) vkCmdFillBuffer;
 
     VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
     {
diff --git a/layers/image.cpp b/layers/image.cpp
index 912c23f..93579c7 100644
--- a/layers/image.cpp
+++ b/layers/image.cpp
@@ -43,6 +43,7 @@
 #include "vk_layer_table.h"
 #include "vk_layer_data.h"
 #include "vk_layer_extension_utils.h"
+#include "vk_layer_utils.h"
 
 using namespace std;
 
@@ -518,25 +519,51 @@
     const VkImageCopy *pRegions)
 {
     VkBool32 skipCall = VK_FALSE;
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+    auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
+    auto destImageEntry = device_data->imageMap.find(destImage.handle);
 
     // For each region, src aspect mask must match dest aspect mask
     // For each region, color aspects cannot be mixed with depth/stencil aspects
     for (uint32_t i = 0; i < regionCount; i++) {
         if (pRegions[i].srcSubresource.aspect != pRegions[i].destSubresource.aspect) {
-            layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
             char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
             skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
                                 (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
         }
         if ((pRegions[i].srcSubresource.aspect & VK_IMAGE_ASPECT_COLOR) &&
             (pRegions[i].srcSubresource.aspect & (VK_IMAGE_ASPECT_DEPTH | VK_IMAGE_ASPECT_STENCIL))) {
-            layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
             char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
             skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
                                 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
         }
     }
 
+    if ((srcImageEntry != device_data->imageMap.end())
+    && (destImageEntry != device_data->imageMap.end())) {
+        if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
+            char const str[] = "vkCmdCopyImage called with unmatched source and dest image types.";
+            skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
+                                (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
+        }
+        // Check that format is same size or exact stencil/depth
+        if (is_depth_format(srcImageEntry->second->format)) {
+            if (srcImageEntry->second->format != destImageEntry->second->format) {
+                char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
+                skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
+                                    (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
+            }
+        } else {
+            size_t srcSize = vk_format_get_size(srcImageEntry->second->format);
+            size_t destSize = vk_format_get_size(destImageEntry->second->format);
+            if (srcSize != destSize) {
+                char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
+                skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
+                                    (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
+            }
+        }
+    }
+
     if (VK_FALSE == skipCall) {
         get_dispatch_table(image_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage,
             srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
@@ -634,18 +661,44 @@
     const VkImageResolve *pRegions)
 {
     VkBool32 skipCall = VK_FALSE;
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
+    auto srcImageEntry = device_data->imageMap.find(srcImage.handle);
+    auto destImageEntry = device_data->imageMap.find(destImage.handle);
 
     // For each region, src and dest image aspect must be color only
     for (uint32_t i = 0; i < regionCount; i++) {
         if ((pRegions[i].srcSubresource.aspect  != VK_IMAGE_ASPECT_COLOR) ||
             (pRegions[i].destSubresource.aspect != VK_IMAGE_ASPECT_COLOR)) {
-            layer_data *device_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
             char const str[] = "vkCmdResolveImage: src and dest aspectMasks for each region must specify only VK_IMAGE_ASPECT_COLOR_BIT";
             skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
                                 (uint64_t)cmdBuffer, 0, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
         }
     }
 
+    if ((srcImageEntry != device_data->imageMap.end())
+    && (destImageEntry != device_data->imageMap.end())) {
+        if (srcImageEntry->second->format != destImageEntry->second->format) {
+            char const str[] =  "vkCmdResolveImage called with unmatched source and dest formats.";
+            skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
+                                (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
+        }
+        if (srcImageEntry->second->imageType != destImageEntry->second->imageType) {
+            char const str[] =  "vkCmdResolveImage called with unmatched source and dest image types.";
+            skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
+                                (uint64_t)cmdBuffer, 0, IMAGE_MISMATCHED_IMAGE_TYPE, "IMAGE", str);
+        }
+        if (srcImageEntry->second->samples <= 1) {
+            char const str[] =  "vkCmdResolveImage called with source sample count less than 2.";
+            skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
+                                (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES,  "IMAGE", str);
+        }
+        if (destImageEntry->second->samples > 1) {
+            char const str[] =  "vkCmdResolveImage called with dest sample count greater than 1.";
+            skipCall |= log_msg(device_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
+                                (uint64_t)cmdBuffer, 0, IMAGE_INVALID_RESOLVE_SAMPLES, "IMAGE", str);
+        }
+    }
+
     if (VK_FALSE == skipCall) {
         get_dispatch_table(image_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage,
             srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
diff --git a/layers/image.h b/layers/image.h
index 79c4928..e1738c8 100644
--- a/layers/image.h
+++ b/layers/image.h
@@ -27,7 +27,7 @@
 #include "vk_layer_config.h"
 #include "vk_layer_logging.h"
 
-// Draw State ERROR codes
+// Image ERROR codes
 typedef enum _IMAGE_ERROR
 {
     IMAGE_NONE,                             // Used for INFO & other non-error messages
@@ -37,14 +37,26 @@
     IMAGE_INVALID_IMAGE_ASPECT,             // Image aspect mask bits are invalid for this API call
     IMAGE_MISMATCHED_IMAGE_ASPECT,          // Image aspect masks for source and dest images do not match
     IMAGE_VIEW_CREATE_ERROR,                // Error occurred trying to create Image View
+    IMAGE_MISMATCHED_IMAGE_TYPE,            // Image types for source and dest images do not match
+    IMAGE_MISMATCHED_IMAGE_FORMAT,          // Image formats for source and dest images do not match
+    IMAGE_INVALID_RESOLVE_SAMPLES,          // Image resolve source samples less than two or dest samples greater than one
 } IMAGE_ERROR;
 
 typedef struct _IMAGE_STATE
 {
     uint32_t mipLevels;
     uint32_t arraySize;
-    _IMAGE_STATE():mipLevels(0), arraySize(0) {};
-    _IMAGE_STATE(const VkImageCreateInfo* pCreateInfo):mipLevels(pCreateInfo->mipLevels), arraySize(pCreateInfo->arraySize) {};
+    VkFormat format;
+    uint32_t samples;
+    VkImageType imageType;
+    _IMAGE_STATE():mipLevels(0), arraySize(0), format(VK_FORMAT_UNDEFINED), samples(0), imageType(VK_IMAGE_TYPE_NUM) {};
+    _IMAGE_STATE(const VkImageCreateInfo* pCreateInfo):
+        mipLevels(pCreateInfo->mipLevels),
+        arraySize(pCreateInfo->arraySize),
+        format(pCreateInfo->format),
+        samples(pCreateInfo->samples),
+        imageType(pCreateInfo->imageType)
+        {};
 } IMAGE_STATE;
 
 #endif // IMAGE_H
diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md
index e3d1d69..d40f52e 100644
--- a/layers/vk_validation_layer_details.md
+++ b/layers/vk_validation_layer_details.md
@@ -124,6 +124,9 @@
 | View Creation | Verify that requested Image View Creation parameters are reasonable for the image that the view is being created for | VIEW_CREATE_ERROR | vkCreateImageView | TBD | NA |
 | Image Aspects | Verify that Image commands are using valid Image Aspect flags | INVALID_IMAGE_ASPECT | vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdClearDepthStencilAttachment vkCmdCopyImage vkCmdCopyImageToBuffer vkCmdCopyBufferToImage vkCmdResolveImage | TBD | NA |
 | Image Aspect Mismatch | Verify that Image commands with source and dest images use matching aspect flags | MISMATCHED_IMAGE_ASPECT | vkCmdCopyImage | TBD | NA |
+| Image Type Mismatch | Verify that Image commands with source and dest images use matching types | MISMATCHED_IMAGE_TYPE | vkCmdCopyImage vkCmdResolveImage | CopyImageTypeMismatch ResolveImageTypeMismatch | NA |
+| Image Format Mismatch | Verify that Image commands with source and dest images use matching formats | MISMATCHED_IMAGE_FORMAT | vkCmdCopyImage vkCmdResolveImage | CopyImageDepthStencilFormatMismatch ResolveImageFormatMismatch | NA |
+| Resolve Sample Count | Verifies that source and dest images sample counts are valid | INVALID_RESOLVE_SAMPLES | vkCmdResolveImage | ResolveImageHighSampleCount ResolveImageLowSampleCount | NA |
 | NA | Enum used for informational messages | NONE | | NA | None |
 
 ### Image Pending Work
@@ -290,6 +293,8 @@
 | Feature Request | Attempting to vkCreateDevice with a feature that is not supported by the underlying physical device. | INVALID_FEATURE_REQUESTED | vkCreateDevice | NA | Add validation test |
 | Valid Image Extents | When creating an Image, ensure that image extents are within device limits for the specified format | LIMITS_VIOLATION | vkCreateImage | CreateImageLimitsViolationWidth | NA |
 | Valid Image Resource Size | When creating an image, ensure the the total image resource size is less than the queried device maximum resource size  | LIMITS_VIOLATION | vkCreateImage | CreateImageResourceSizeViolation | NA |
+| Alignment | When updating a buffer, data should be aligned on 4 byte boundaries  | LIMITS_VIOLATION | vkCmdUpdateBuffer | UpdateBufferAlignment | NA |
+| Alignment | When filling a buffer, data should be aligned on 4 byte boundaries  | LIMITS_VIOLATION | vkCmdFillBuffer | UpdateBufferAlignment | NA |
 | NA | Enum used for informational messages | NONE | | NA | None |
 
 ### Device Limitations Pending Work
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 5e8e509..188c35c 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -4117,6 +4117,65 @@
     }
 }
 
+TEST_F(VkLayerTest, UpdateBufferAlignment)
+{
+    VkFlags msgFlags;
+    std::string msgString;
+    uint32_t updateData[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+    vk_testing::Buffer buffer;
+    buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
+
+    BeginCommandBuffer();
+    // Introduce failure by using offset that is not multiple of 4
+    m_cmdBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData);
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an err after calling UpdateBuffer with bad offset";
+    if (!strstr(msgString.c_str(),"destOffset, is not a multiple of 4")) {
+        FAIL() << "Error received was not 'vkCmdUpdateBuffer parameter, VkDeviceSize destOffset, is not a multiple of 4'";
+    }
+    // Introduce failure by using size that is not multiple of 4
+    m_cmdBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData);
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an err after calling UpdateBuffer with bad size";
+    if (!strstr(msgString.c_str(),"dataSize, is not a multiple of 4")) {
+        FAIL() << "Error received was not 'vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4'";
+    }
+    EndCommandBuffer();
+}
+
+TEST_F(VkLayerTest, FillBufferAlignment)
+{
+    VkFlags msgFlags;
+    std::string msgString;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+    vk_testing::Buffer buffer;
+    buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
+
+    BeginCommandBuffer();
+    // Introduce failure by using offset that is not multiple of 4
+    m_cmdBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111);
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an err after calling FillBuffer with bad offset";
+    if (!strstr(msgString.c_str(),"destOffset, is not a multiple of 4")) {
+        FAIL() << "Error received was not 'vkCmdFillBuffer parameter, VkDeviceSize destOffset, is not a multiple of 4'";
+    }
+    // Introduce failure by using size that is not multiple of 4
+    m_cmdBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111);
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an err after calling FillBuffer with bad size";
+    if (!strstr(msgString.c_str(),"fillSize, is not a multiple of 4")) {
+        FAIL() << "Error received was not 'vkCmdFillBuffer parameter, VkDeviceSize fillSize, is not a multiple of 4'";
+    }
+    EndCommandBuffer();
+}
+
 #endif // DEVICE_LIMITS_TESTS
 
 #if IMAGE_TESTS
@@ -4129,7 +4188,7 @@
     ASSERT_NO_FATAL_FAILURE(InitState());
     m_errorMonitor->ClearState();
 
-    // Create an image, allocate memory, free it, and then try to bind it
+    // Create an image and try to create a view with bad baseMipLevel
     VkImage               image;
 
     const VkFormat tex_format      = VK_FORMAT_B8G8R8A8_UNORM;
@@ -4169,9 +4228,640 @@
     msgFlags = m_errorMonitor->GetState(&msgString);
     ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an error while creating an invalid ImageView";
     if (!strstr(msgString.c_str(),"vkCreateImageView called with baseMipLevel 10 ")) {
-        FAIL() << "Error received was not 'vkCreateImageView called with baseMipLevel 10...' but instaed '" << msgString.c_str() << "'";
+        FAIL() << "Error received was not 'vkCreateImageView called with baseMipLevel 10...' but instead '" << msgString.c_str() << "'";
     }
 }
+
+TEST_F(VkLayerTest, CopyImageTypeMismatch)
+{
+    VkFlags         msgFlags;
+    std::string     msgString;
+    VkResult        err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    m_errorMonitor->ClearState();
+
+    // Create two images of different types and try to copy between them
+    VkImage               srcImage;
+    VkImage               destImage;
+    VkDeviceMemory        srcMem;
+    VkDeviceMemory        destMem;
+    VkMemoryRequirements  memReqs;
+
+    VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
+        image_create_info.extent.width = 32;
+        image_create_info.extent.height = 32;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arraySize = 1;
+        image_create_info.samples = 1;
+        image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT;
+        image_create_info.flags = 0;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &srcImage);
+    ASSERT_VK_SUCCESS(err);
+
+        image_create_info.imageType = VK_IMAGE_TYPE_1D;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &destImage);
+    ASSERT_VK_SUCCESS(err);
+
+    // Allocate memory
+    VkMemoryAllocInfo memAlloc = {};
+        memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
+        memAlloc.pNext = NULL;
+        memAlloc.allocationSize = 0;
+        memAlloc.memoryTypeIndex = 0;
+
+    err = vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &srcMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkGetImageMemoryRequirements(m_device->device(), destImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &destMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), destImage, destMem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+    VkImageCopy copyRegion;
+    copyRegion.srcSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    copyRegion.srcSubresource.mipLevel = 0;
+    copyRegion.srcSubresource.arrayLayer = 0;
+    copyRegion.srcSubresource.arraySize = 0;
+    copyRegion.srcOffset.x = 0;
+    copyRegion.srcOffset.y = 0;
+    copyRegion.srcOffset.z = 0;
+    copyRegion.destSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    copyRegion.destSubresource.mipLevel = 0;
+    copyRegion.destSubresource.arrayLayer = 0;
+    copyRegion.destSubresource.arraySize = 0;
+    copyRegion.destOffset.x = 0;
+    copyRegion.destOffset.y = 0;
+    copyRegion.destOffset.z = 0;
+    copyRegion.extent.width = 1;
+    copyRegion.extent.height = 1;
+    copyRegion.extent.depth = 1;
+    m_cmdBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, destImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
+    EndCommandBuffer();
+
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an error from vkCmdCopyImage type mismatch";
+    if (!strstr(msgString.c_str(),"vkCmdCopyImage called with unmatched source and dest image types")) {
+        FAIL() << "Error received was not 'vkCmdCopyImage called with unmatched source and dest image types' but instead '" << msgString.c_str() << "'";
+    }
+
+    vkDestroyImage(m_device->device(), srcImage);
+    vkDestroyImage(m_device->device(), destImage);
+    vkFreeMemory(m_device->device(), srcMem);
+    vkFreeMemory(m_device->device(), destMem);
+}
+
+TEST_F(VkLayerTest, CopyImageFormatSizeMismatch)
+{
+    // TODO : Create two images with different format sizes and vkCmdCopyImage between them
+}
+
+TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch)
+{
+    VkFlags         msgFlags;
+    std::string     msgString;
+    VkResult        err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    m_errorMonitor->ClearState();
+
+    // Create two images of different types and try to copy between them
+    VkImage               srcImage;
+    VkImage               destImage;
+    VkDeviceMemory        srcMem;
+    VkDeviceMemory        destMem;
+    VkMemoryRequirements  memReqs;
+
+    VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
+        image_create_info.extent.width = 32;
+        image_create_info.extent.height = 32;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arraySize = 1;
+        image_create_info.samples = 1;
+        image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT;
+        image_create_info.flags = 0;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &srcImage);
+    ASSERT_VK_SUCCESS(err);
+
+        image_create_info.imageType = VK_IMAGE_TYPE_1D;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &destImage);
+    ASSERT_VK_SUCCESS(err);
+
+    // Allocate memory
+    VkMemoryAllocInfo memAlloc = {};
+        memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
+        memAlloc.pNext = NULL;
+        memAlloc.allocationSize = 0;
+        memAlloc.memoryTypeIndex = 0;
+
+    err = vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &srcMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkGetImageMemoryRequirements(m_device->device(), destImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &destMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), destImage, destMem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+    VkImageCopy copyRegion;
+    copyRegion.srcSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    copyRegion.srcSubresource.mipLevel = 0;
+    copyRegion.srcSubresource.arrayLayer = 0;
+    copyRegion.srcSubresource.arraySize = 0;
+    copyRegion.srcOffset.x = 0;
+    copyRegion.srcOffset.y = 0;
+    copyRegion.srcOffset.z = 0;
+    copyRegion.destSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    copyRegion.destSubresource.mipLevel = 0;
+    copyRegion.destSubresource.arrayLayer = 0;
+    copyRegion.destSubresource.arraySize = 0;
+    copyRegion.destOffset.x = 0;
+    copyRegion.destOffset.y = 0;
+    copyRegion.destOffset.z = 0;
+    copyRegion.extent.width = 1;
+    copyRegion.extent.height = 1;
+    copyRegion.extent.depth = 1;
+    m_cmdBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, destImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
+    EndCommandBuffer();
+
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an error from vkCmdCopyImage type mismatch";
+    if (!strstr(msgString.c_str(),"vkCmdCopyImage called with unmatched source and dest image types")) {
+        FAIL() << "Error received was not 'vkCmdCopyImage called with unmatched source and dest image types' but instead '" << msgString.c_str() << "'";
+    }
+
+    vkDestroyImage(m_device->device(), srcImage);
+    vkDestroyImage(m_device->device(), destImage);
+    vkFreeMemory(m_device->device(), srcMem);
+    vkFreeMemory(m_device->device(), destMem);
+}
+
+TEST_F(VkLayerTest, ResolveImageLowSampleCount)
+{
+    VkFlags         msgFlags;
+    std::string     msgString;
+    VkResult        err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    m_errorMonitor->ClearState();
+
+    // Create two images of sample count 1 and try to Resolve between them
+    VkImage               srcImage;
+    VkImage               destImage;
+    VkDeviceMemory        srcMem;
+    VkDeviceMemory        destMem;
+    VkMemoryRequirements  memReqs;
+
+    VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
+        image_create_info.extent.width = 32;
+        image_create_info.extent.height = 1;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arraySize = 1;
+        image_create_info.samples = 1;
+        image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT;
+        image_create_info.flags = 0;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &srcImage);
+    ASSERT_VK_SUCCESS(err);
+
+        image_create_info.imageType = VK_IMAGE_TYPE_1D;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &destImage);
+    ASSERT_VK_SUCCESS(err);
+
+    // Allocate memory
+    VkMemoryAllocInfo memAlloc = {};
+        memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
+        memAlloc.pNext = NULL;
+        memAlloc.allocationSize = 0;
+        memAlloc.memoryTypeIndex = 0;
+
+    err = vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &srcMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkGetImageMemoryRequirements(m_device->device(), destImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &destMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), destImage, destMem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+    // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
+    //VK_IMAGE_LAYOUT_UNDEFINED = 0,
+    //VK_IMAGE_LAYOUT_GENERAL = 1,
+    VkImageResolve resolveRegion;
+    resolveRegion.srcSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.srcSubresource.mipLevel = 0;
+    resolveRegion.srcSubresource.arrayLayer = 0;
+    resolveRegion.srcSubresource.arraySize = 0;
+    resolveRegion.srcOffset.x = 0;
+    resolveRegion.srcOffset.y = 0;
+    resolveRegion.srcOffset.z = 0;
+    resolveRegion.destSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.destSubresource.mipLevel = 0;
+    resolveRegion.destSubresource.arrayLayer = 0;
+    resolveRegion.destSubresource.arraySize = 0;
+    resolveRegion.destOffset.x = 0;
+    resolveRegion.destOffset.y = 0;
+    resolveRegion.destOffset.z = 0;
+    resolveRegion.extent.width = 1;
+    resolveRegion.extent.height = 1;
+    resolveRegion.extent.depth = 1;
+    m_cmdBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, destImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
+    EndCommandBuffer();
+
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an error from vkCmdResolveImage type mismatch";
+    if (!strstr(msgString.c_str(),"vkCmdResolveImage called with source sample count less than 2.")) {
+        FAIL() << "Error received was not 'vkCmdResolveImage called with source sample count less than 2.' but instead '" << msgString.c_str() << "'";
+    }
+
+    vkDestroyImage(m_device->device(), srcImage);
+    vkDestroyImage(m_device->device(), destImage);
+    vkFreeMemory(m_device->device(), srcMem);
+    vkFreeMemory(m_device->device(), destMem);
+}
+
+TEST_F(VkLayerTest, ResolveImageHighSampleCount)
+{
+    VkFlags         msgFlags;
+    std::string     msgString;
+    VkResult        err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    m_errorMonitor->ClearState();
+
+    // Create two images of sample count 2 and try to Resolve between them
+    VkImage               srcImage;
+    VkImage               destImage;
+    VkDeviceMemory        srcMem;
+    VkDeviceMemory        destMem;
+    VkMemoryRequirements  memReqs;
+
+    VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
+        image_create_info.extent.width = 32;
+        image_create_info.extent.height = 1;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arraySize = 1;
+        image_create_info.samples = 2;
+        image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT;
+        image_create_info.flags = 0;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &srcImage);
+    ASSERT_VK_SUCCESS(err);
+
+        image_create_info.imageType = VK_IMAGE_TYPE_1D;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &destImage);
+    ASSERT_VK_SUCCESS(err);
+
+    // Allocate memory
+    VkMemoryAllocInfo memAlloc = {};
+        memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
+        memAlloc.pNext = NULL;
+        memAlloc.allocationSize = 0;
+        memAlloc.memoryTypeIndex = 0;
+
+    err = vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &srcMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkGetImageMemoryRequirements(m_device->device(), destImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &destMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), destImage, destMem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+    // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
+    //VK_IMAGE_LAYOUT_UNDEFINED = 0,
+    //VK_IMAGE_LAYOUT_GENERAL = 1,
+    VkImageResolve resolveRegion;
+    resolveRegion.srcSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.srcSubresource.mipLevel = 0;
+    resolveRegion.srcSubresource.arrayLayer = 0;
+    resolveRegion.srcSubresource.arraySize = 0;
+    resolveRegion.srcOffset.x = 0;
+    resolveRegion.srcOffset.y = 0;
+    resolveRegion.srcOffset.z = 0;
+    resolveRegion.destSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.destSubresource.mipLevel = 0;
+    resolveRegion.destSubresource.arrayLayer = 0;
+    resolveRegion.destSubresource.arraySize = 0;
+    resolveRegion.destOffset.x = 0;
+    resolveRegion.destOffset.y = 0;
+    resolveRegion.destOffset.z = 0;
+    resolveRegion.extent.width = 1;
+    resolveRegion.extent.height = 1;
+    resolveRegion.extent.depth = 1;
+    m_cmdBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, destImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
+    EndCommandBuffer();
+
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an error from vkCmdResolveImage type mismatch";
+    if (!strstr(msgString.c_str(),"vkCmdResolveImage called with dest sample count greater than 1.")) {
+        FAIL() << "Error received was not 'vkCmdResolveImage called with dest sample count greater than 1.' but instead '" << msgString.c_str() << "'";
+    }
+
+    vkDestroyImage(m_device->device(), srcImage);
+    vkDestroyImage(m_device->device(), destImage);
+    vkFreeMemory(m_device->device(), srcMem);
+    vkFreeMemory(m_device->device(), destMem);
+}
+
+TEST_F(VkLayerTest, ResolveImageFormatMismatch)
+{
+    VkFlags         msgFlags;
+    std::string     msgString;
+    VkResult        err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    m_errorMonitor->ClearState();
+
+    // Create two images of different types and try to copy between them
+    VkImage               srcImage;
+    VkImage               destImage;
+    VkDeviceMemory        srcMem;
+    VkDeviceMemory        destMem;
+    VkMemoryRequirements  memReqs;
+
+    VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
+        image_create_info.extent.width = 32;
+        image_create_info.extent.height = 1;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arraySize = 1;
+        image_create_info.samples = 2;
+        image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT;
+        image_create_info.flags = 0;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &srcImage);
+    ASSERT_VK_SUCCESS(err);
+
+        image_create_info.format = VK_FORMAT_B8G8R8_SRGB;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;
+        image_create_info.samples = 1;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &destImage);
+    ASSERT_VK_SUCCESS(err);
+
+    // Allocate memory
+    VkMemoryAllocInfo memAlloc = {};
+        memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
+        memAlloc.pNext = NULL;
+        memAlloc.allocationSize = 0;
+        memAlloc.memoryTypeIndex = 0;
+
+    err = vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &srcMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkGetImageMemoryRequirements(m_device->device(), destImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &destMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), destImage, destMem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+    // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
+    //VK_IMAGE_LAYOUT_UNDEFINED = 0,
+    //VK_IMAGE_LAYOUT_GENERAL = 1,
+    VkImageResolve resolveRegion;
+    resolveRegion.srcSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.srcSubresource.mipLevel = 0;
+    resolveRegion.srcSubresource.arrayLayer = 0;
+    resolveRegion.srcSubresource.arraySize = 0;
+    resolveRegion.srcOffset.x = 0;
+    resolveRegion.srcOffset.y = 0;
+    resolveRegion.srcOffset.z = 0;
+    resolveRegion.destSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.destSubresource.mipLevel = 0;
+    resolveRegion.destSubresource.arrayLayer = 0;
+    resolveRegion.destSubresource.arraySize = 0;
+    resolveRegion.destOffset.x = 0;
+    resolveRegion.destOffset.y = 0;
+    resolveRegion.destOffset.z = 0;
+    resolveRegion.extent.width = 1;
+    resolveRegion.extent.height = 1;
+    resolveRegion.extent.depth = 1;
+    m_cmdBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, destImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
+    EndCommandBuffer();
+
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an error from vkCmdResolveImage format mismatch";
+    if (!strstr(msgString.c_str(),"vkCmdResolveImage called with unmatched source and dest formats.")) {
+        FAIL() << "Error received was not 'vkCmdResolveImage called with unmatched source and dest formats.' but instead '" << msgString.c_str() << "'";
+    }
+
+    vkDestroyImage(m_device->device(), srcImage);
+    vkDestroyImage(m_device->device(), destImage);
+    vkFreeMemory(m_device->device(), srcMem);
+    vkFreeMemory(m_device->device(), destMem);
+}
+
+TEST_F(VkLayerTest, ResolveImageTypeMismatch)
+{
+    VkFlags         msgFlags;
+    std::string     msgString;
+    VkResult        err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    m_errorMonitor->ClearState();
+
+    // Create two images of different types and try to copy between them
+    VkImage               srcImage;
+    VkImage               destImage;
+    VkDeviceMemory        srcMem;
+    VkDeviceMemory        destMem;
+    VkMemoryRequirements  memReqs;
+
+    VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
+        image_create_info.extent.width = 32;
+        image_create_info.extent.height = 1;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arraySize = 1;
+        image_create_info.samples = 2;
+        image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT;
+        image_create_info.flags = 0;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &srcImage);
+    ASSERT_VK_SUCCESS(err);
+
+        image_create_info.imageType = VK_IMAGE_TYPE_1D;
+        image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;
+        image_create_info.samples = 1;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, &destImage);
+    ASSERT_VK_SUCCESS(err);
+
+    // Allocate memory
+    VkMemoryAllocInfo memAlloc = {};
+        memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
+        memAlloc.pNext = NULL;
+        memAlloc.allocationSize = 0;
+        memAlloc.memoryTypeIndex = 0;
+
+    err = vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &srcMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkGetImageMemoryRequirements(m_device->device(), destImage, &memReqs);
+    ASSERT_VK_SUCCESS(err);
+    memAlloc.allocationSize = memReqs.size;
+    err = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocMemory(m_device->device(), &memAlloc, &destMem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), destImage, destMem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+    // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
+    //VK_IMAGE_LAYOUT_UNDEFINED = 0,
+    //VK_IMAGE_LAYOUT_GENERAL = 1,
+    VkImageResolve resolveRegion;
+    resolveRegion.srcSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.srcSubresource.mipLevel = 0;
+    resolveRegion.srcSubresource.arrayLayer = 0;
+    resolveRegion.srcSubresource.arraySize = 0;
+    resolveRegion.srcOffset.x = 0;
+    resolveRegion.srcOffset.y = 0;
+    resolveRegion.srcOffset.z = 0;
+    resolveRegion.destSubresource.aspect = VK_IMAGE_ASPECT_COLOR;
+    resolveRegion.destSubresource.mipLevel = 0;
+    resolveRegion.destSubresource.arrayLayer = 0;
+    resolveRegion.destSubresource.arraySize = 0;
+    resolveRegion.destOffset.x = 0;
+    resolveRegion.destOffset.y = 0;
+    resolveRegion.destOffset.z = 0;
+    resolveRegion.extent.width = 1;
+    resolveRegion.extent.height = 1;
+    resolveRegion.extent.depth = 1;
+    m_cmdBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, destImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
+    EndCommandBuffer();
+
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(0 != (msgFlags & VK_DBG_REPORT_ERROR_BIT)) << "Did not receive an error from vkCmdResolveImage type mismatch";
+    if (!strstr(msgString.c_str(),"vkCmdResolveImage called with unmatched source and dest image types.")) {
+        FAIL() << "Error received was not 'vkCmdResolveImage called with unmatched source and dest image types.' but instead '" << msgString.c_str() << "'";
+    }
+
+    vkDestroyImage(m_device->device(), srcImage);
+    vkDestroyImage(m_device->device(), destImage);
+    vkFreeMemory(m_device->device(), srcMem);
+    vkFreeMemory(m_device->device(), destMem);
+}
 #endif // IMAGE_TESTS
 
 int main(int argc, char **argv) {
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index 94c9774..13fff54 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -1450,6 +1450,21 @@
     vkCmdFillBuffer( handle(), buffer, offset, fill_size, data);
 }
 
+void VkCommandBufferObj::UpdateBuffer(VkBuffer buffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t *pData)
+{
+    vkCmdUpdateBuffer(handle(), buffer, destOffset, dataSize, pData);
+}
+
+void VkCommandBufferObj::CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageCopy* pRegions)
+{
+    vkCmdCopyImage(handle(), srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
+}
+
+void VkCommandBufferObj::ResolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageResolve* pRegions)
+{
+    vkCmdResolveImage(handle(), srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
+}
+
 void VkCommandBufferObj::PrepareAttachments()
 {
     uint32_t i;
diff --git a/tests/vkrenderframework.h b/tests/vkrenderframework.h
index 18c2b32..79a047e 100644
--- a/tests/vkrenderframework.h
+++ b/tests/vkrenderframework.h
@@ -198,6 +198,9 @@
     void SetStencilReadMask(VkStencilFaceFlags faceMask, uint32_t stencilCompareMask);
     void SetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t stencilWriteMask);
     void SetStencilReference(VkStencilFaceFlags faceMask, uint32_t stencilReference);
+    void UpdateBuffer(VkBuffer buffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t *pData);
+    void CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageCopy* pRegions);
+    void ResolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageResolve* pRegions);
 
 protected:
     VkDeviceObj                        *m_device;