aboutsummaryrefslogtreecommitdiff
path: root/layers/core_validation.cpp
diff options
context:
space:
mode:
authorTobin Ehlis <tobine@google.com>2016-08-04 10:17:19 -0600
committerTobin Ehlis <tobine@google.com>2016-08-09 10:21:19 -0600
commitd6cea516e7588d9e251a8f2713fb458044a751eb (patch)
tree25f4b5ebdea08b0a0f71046fd3df8a75cb10f029 /layers/core_validation.cpp
parentccdd8237b8b62d7648cefcc6df16d62e5c684451 (diff)
downloadusermoji-d6cea516e7588d9e251a8f2713fb458044a751eb.tar.xz
layers: Fix MapMem image layout validation
When mapping memory, check all of the bound image ranges and for any that overlap with the map range, make sure that the image layout is either PREINITIALIZED or GENERAL.
Diffstat (limited to 'layers/core_validation.cpp')
-rw-r--r--layers/core_validation.cpp54
1 files changed, 32 insertions, 22 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 837a69a7..1702721a 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -10035,32 +10035,42 @@ CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
if (!skip_call)
dev_data->device_dispatch_table->CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers);
}
+// Return true if given range intersects with offset and size, else false
+// Prereq : size > 0 and range->end - range->start > 0. Both of these cases should have already resulted
+// in an error (During MapMemory and AllocateMemory respectively) so not checking them here
+static bool rangesIntersect(MEMORY_RANGE const *range, VkDeviceSize offset, VkDeviceSize size) {
+ auto range2_end = offset + size - 1;
+ if ((range->start >= offset && range->start <= (range2_end)) || (range->end >= offset && range->end <= range2_end)) {
+ return true;
+ }
+ return false;
+}
-static bool ValidateMapImageLayouts(VkDevice device, VkDeviceMemory mem) {
+// For any image objects that overlap mapped memory, verify that their layouts are PREINIT or GENERAL
+static bool ValidateMapImageLayouts(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) {
bool skip_call = false;
layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
auto mem_info = getMemObjInfo(dev_data, mem);
if (mem_info) {
- // TODO : Update this code to only check images that overlap given map range
- // for (auto bound_object : mem_info->obj_bindings) {
- // if (bound_object.type == VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT) {
- // std::vector<VkImageLayout> layouts;
- // if (FindLayouts(dev_data, VkImage(bound_object.handle), layouts)) {
- // for (auto layout : layouts) {
- // if (layout != VK_IMAGE_LAYOUT_PREINITIALIZED && layout != VK_IMAGE_LAYOUT_GENERAL) {
- // skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
- // (VkDebugReportObjectTypeEXT)0, 0,
- // __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", "Cannot map an image with
- // layout %s. Only "
- // "GENERAL or
- // PREINITIALIZED are
- // supported.",
- // string_VkImageLayout(layout));
- // }
- // }
- // }
- // }
- // }
+ // Iterate over all bound image ranges and verify that for any that overlap the
+ // map ranges, the layouts are VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERAL
+ // TODO : This can be optimized if we store ranges based on starting address and early exit when we pass our range
+ for (auto range : mem_info->image_ranges) {
+ if (rangesIntersect(&range, offset, size)) {
+ std::vector<VkImageLayout> layouts;
+ if (FindLayouts(dev_data, VkImage(range.handle), layouts)) {
+ for (auto layout : layouts) {
+ if (layout != VK_IMAGE_LAYOUT_PREINITIALIZED && layout != VK_IMAGE_LAYOUT_GENERAL) {
+ skip_call |=
+ log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+ __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", "Cannot map an image with layout %s. Only "
+ "GENERAL or PREINITIALIZED are supported.",
+ string_VkImageLayout(layout));
+ }
+ }
+ }
+ }
+ }
}
return skip_call;
}
@@ -10086,7 +10096,7 @@ MapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize
}
skip_call |= ValidateMapMemRange(dev_data, mem, offset, size);
#endif
- skip_call |= ValidateMapImageLayouts(device, mem);
+ skip_call |= ValidateMapImageLayouts(device, mem, offset, size);
lock.unlock();
if (!skip_call) {