corechecks: Add some BufferImageCopy VUs

Change-Id: I081cc8bf78ed7b42104ecb15ac7ee67511d55cd2
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp
index 86dc053..df6f3df 100644
--- a/layers/buffer_validation.cpp
+++ b/layers/buffer_validation.cpp
@@ -4530,6 +4530,41 @@
                 function, i, pRegions[i].bufferImageHeight, pRegions[i].imageExtent.height);
         }
 
+        // Calculate adjusted image extent, accounting for multiplane image factors
+        VkExtent3D adusted_image_extent = GetImageSubresourceExtent(image_state, &pRegions[i].imageSubresource);
+        // imageOffset.x and (imageExtent.width + imageOffset.x) must both be >= 0 and <= image subresource width
+        if ((pRegions[i].imageOffset.x < 0) || (pRegions[i].imageOffset.x > static_cast<int32_t>(adusted_image_extent.width)) ||
+            ((pRegions[i].imageOffset.x + pRegions[i].imageExtent.width) > static_cast<int32_t>(adusted_image_extent.width))) {
+            skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                            HandleToUint64(image_state->image), "VUID-VkBufferImageCopy-imageOffset-00197",
+                            "%s(): Both pRegion[%d] imageoffset.x (%d) and (imageExtent.width + imageOffset.x) (%d) must be >= "
+                            "zero or <= image subresource width (%d).",
+                            function, i, pRegions[i].imageOffset.x, (pRegions[i].imageOffset.x + pRegions[i].imageExtent.width),
+                            adusted_image_extent.width);
+        }
+
+        // imageOffset.y and (imageExtent.height + imageOffset.y) must both be >= 0 and <= image subresource height
+        if ((pRegions[i].imageOffset.y < 0) || (pRegions[i].imageOffset.y > static_cast<int32_t>(adusted_image_extent.height)) ||
+            ((pRegions[i].imageOffset.y + pRegions[i].imageExtent.height) > static_cast<int32_t>(adusted_image_extent.height))) {
+            skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                            HandleToUint64(image_state->image), "VUID-VkBufferImageCopy-imageOffset-00198",
+                            "%s(): Both pRegion[%d] imageoffset.y (%d) and (imageExtent.height + imageOffset.y) (%d) must be >= "
+                            "zero or <= image subresource height (%d).",
+                            function, i, pRegions[i].imageOffset.y, (pRegions[i].imageOffset.y + pRegions[i].imageExtent.height),
+                            adusted_image_extent.height);
+        }
+
+        // imageOffset.z and (imageExtent.depth + imageOffset.z) must both be >= 0 and <= image subresource depth
+        if ((pRegions[i].imageOffset.z < 0) || (pRegions[i].imageOffset.z > static_cast<int32_t>(adusted_image_extent.depth)) ||
+            ((pRegions[i].imageOffset.z + pRegions[i].imageExtent.depth) > static_cast<int32_t>(adusted_image_extent.depth))) {
+            skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                            HandleToUint64(image_state->image), "VUID-VkBufferImageCopy-imageOffset-00200",
+                            "%s(): Both pRegion[%d] imageoffset.z (%d) and (imageExtent.depth + imageOffset.z) (%d) must be >= "
+                            "zero or <= image subresource depth (%d).",
+                            function, i, pRegions[i].imageOffset.z, (pRegions[i].imageOffset.z + pRegions[i].imageExtent.depth),
+                            adusted_image_extent.depth);
+        }
+
         // subresource aspectMask must have exactly 1 bit set
         const int num_bits = sizeof(VkFlags) * CHAR_BIT;
         std::bitset<num_bits> aspect_mask_bits(pRegions[i].imageSubresource.aspectMask);