blob: dfa5e146eadc632d4fd87798c7dd9e1d47073b71 [file] [log] [blame]
Dave Houltonb817a872018-06-26 13:22:01 -06001/* Copyright (c) 2015-2018 The Khronos Group Inc.
2 * Copyright (c) 2015-2018 Valve Corporation
3 * Copyright (c) 2015-2018 LunarG, Inc.
4 * Copyright (C) 2015-2018 Google Inc.
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -06005 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Mark Lobodzinski <mark@lunarg.com>
19 * Author: Jon Ashburn <jon@lunarg.com>
20 * Author: Tobin Ehlis <tobin@lunarg.com>
21 */
22
Mark Lobodzinski0c668462018-09-27 10:13:19 -060023#include "chassis.h"
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060024
Mark Lobodzinski63902f02018-09-21 10:36:44 -060025#include "object_lifetime_validation.h"
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060026
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060027uint64_t object_track_index = 0;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060028
29// Add new queue to head of global queue list
Mark Lobodzinski0c668462018-09-27 10:13:19 -060030void ObjectLifetimes::AddQueueInfo(VkDevice device, uint32_t queue_node_index, VkQueue queue) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060031 auto queueItem = queue_info_map.find(queue);
32 if (queueItem == queue_info_map.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060033 ObjTrackQueueInfo *p_queue_info = new ObjTrackQueueInfo;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060034 if (p_queue_info != NULL) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060035 memset(p_queue_info, 0, sizeof(ObjTrackQueueInfo));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060036 p_queue_info->queue = queue;
37 p_queue_info->queue_node_index = queue_node_index;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060038 queue_info_map[queue] = p_queue_info;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060039 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060040 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, HandleToUint64(queue),
41 kVUID_ObjectTracker_InternalError,
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060042 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
43 }
44 }
45}
46
47// Destroy memRef lists and free all memory
Mark Lobodzinski0c668462018-09-27 10:13:19 -060048void ObjectLifetimes::DestroyQueueDataStructures(VkDevice device) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060049 for (auto queue_item : queue_info_map) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060050 delete queue_item.second;
51 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060052 queue_info_map.clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060053
54 // Destroy the items in the queue map
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060055 auto queue = object_map[kVulkanObjectTypeQueue].begin();
56 while (queue != object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060057 uint32_t obj_index = queue->second->object_type;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060058 assert(num_total_objects > 0);
59 num_total_objects--;
60 assert(num_objects[obj_index] > 0);
61 num_objects[obj_index]--;
62 log_msg(report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, queue->second->handle,
63 kVUID_ObjectTracker_Info,
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060064 "OBJ_STAT Destroy Queue obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " Queue objs).",
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060065 queue->second->handle, num_total_objects, num_objects[obj_index]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060066 delete queue->second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060067 queue = object_map[kVulkanObjectTypeQueue].erase(queue);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060068 }
69}
70
71// Check Queue type flags for selected queue operations
Mark Lobodzinski0c668462018-09-27 10:13:19 -060072void ObjectLifetimes::ValidateQueueFlags(VkQueue queue, const char *function) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060073 auto queue_item = queue_info_map.find(queue);
74 if (queue_item != queue_info_map.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060075 ObjTrackQueueInfo *pQueueInfo = queue_item->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060076 if (pQueueInfo != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060077 if ((queue_family_properties[pQueueInfo->queue_node_index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
78 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, HandleToUint64(queue),
79 "VUID-vkQueueBindSparse-queuetype",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060080 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set.", function);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060081 }
82 }
83 }
84}
85
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070086// Look for this device object in any of the instance child devices lists.
87// NOTE: This is of dubious value. In most circumstances Vulkan will die a flaming death if a dispatchable object is invalid.
88// However, if this layer is loaded first and GetProcAddress is used to make API calls, it will detect bad DOs.
Mark Lobodzinski0c668462018-09-27 10:13:19 -060089bool ObjectLifetimes::ValidateDeviceObject(uint64_t device_handle, const std::string &invalid_handle_code,
90 const std::string &wrong_device_code) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060091 auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
92 auto instance_object_lifetime_data = GetObjectLifetimeData(instance_data->object_dispatch);
93 for (auto object : instance_object_lifetime_data->object_map[kVulkanObjectTypeDevice]) {
94 if (object.second->handle == device_handle) return false;
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070095 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060096 return log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device_handle,
Mark Lobodzinski88529492018-04-01 10:38:15 -060097 invalid_handle_code, "Invalid Device Object 0x%" PRIxLEAST64 ".", device_handle);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070098}
99
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600100void ObjectLifetimes::AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
101 VkCommandBufferLevel level) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600102 log_msg(report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -0600103 HandleToUint64(command_buffer), kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600104 object_track_index++, "VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT", HandleToUint64(command_buffer));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600105
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600106 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600107 pNewObjNode->object_type = kVulkanObjectTypeCommandBuffer;
108 pNewObjNode->handle = HandleToUint64(command_buffer);
109 pNewObjNode->parent_object = HandleToUint64(command_pool);
110 if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
111 pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
112 } else {
113 pNewObjNode->status = OBJSTATUS_NONE;
114 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600115 object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)] = pNewObjNode;
116 num_objects[kVulkanObjectTypeCommandBuffer]++;
117 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600118}
119
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600120bool ObjectLifetimes::ValidateCommandBuffer(VkDevice device, VkCommandPool command_pool, VkCommandBuffer command_buffer) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600121 bool skip = false;
122 uint64_t object_handle = HandleToUint64(command_buffer);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600123 if (object_map[kVulkanObjectTypeCommandBuffer].find(object_handle) != object_map[kVulkanObjectTypeCommandBuffer].end()) {
124 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600125
126 if (pNode->parent_object != HandleToUint64(command_pool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600127 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton57ae22f2018-05-18 16:20:52 -0600128 object_handle, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent",
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600129 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600130 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
131 HandleToUint64(command_buffer), pNode->parent_object, HandleToUint64(command_pool));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600132 }
133 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600134 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, object_handle,
135 "VUID-vkFreeCommandBuffers-pCommandBuffers-00048", "Invalid %s Object 0x%" PRIxLEAST64 ".",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600136 object_string[kVulkanObjectTypeCommandBuffer], object_handle);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600137 }
138 return skip;
139}
140
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600141void ObjectLifetimes::AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600142 log_msg(report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -0600143 HandleToUint64(descriptor_set), kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600144 object_track_index++, "VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT", HandleToUint64(descriptor_set));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600145
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600146 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600147 pNewObjNode->object_type = kVulkanObjectTypeDescriptorSet;
148 pNewObjNode->status = OBJSTATUS_NONE;
149 pNewObjNode->handle = HandleToUint64(descriptor_set);
150 pNewObjNode->parent_object = HandleToUint64(descriptor_pool);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600151 object_map[kVulkanObjectTypeDescriptorSet][HandleToUint64(descriptor_set)] = pNewObjNode;
152 num_objects[kVulkanObjectTypeDescriptorSet]++;
153 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600154}
155
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600156bool ObjectLifetimes::ValidateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600157 bool skip = false;
158 uint64_t object_handle = HandleToUint64(descriptor_set);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600159 auto dsItem = object_map[kVulkanObjectTypeDescriptorSet].find(object_handle);
160 if (dsItem != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600161 ObjTrackState *pNode = dsItem->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600162
163 if (pNode->parent_object != HandleToUint64(descriptor_pool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600164 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
Dave Houlton57ae22f2018-05-18 16:20:52 -0600165 object_handle, "VUID-vkFreeDescriptorSets-pDescriptorSets-parent",
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600166 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600167 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
168 HandleToUint64(descriptor_set), pNode->parent_object, HandleToUint64(descriptor_pool));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600169 }
170 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600171 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, object_handle,
172 "VUID-vkFreeDescriptorSets-pDescriptorSets-00310", "Invalid %s Object 0x%" PRIxLEAST64 ".",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600173 object_string[kVulkanObjectTypeDescriptorSet], object_handle);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600174 }
175 return skip;
176}
177
Dave Houltona9df0ce2018-02-07 10:51:23 -0700178template <typename DispObj>
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600179bool ObjectLifetimes::ValidateDescriptorWrite(DispObj disp, VkWriteDescriptorSet const *desc, bool isPush) {
Chris Forbes2c600e92017-10-20 11:13:20 -0700180 bool skip = false;
181
182 if (!isPush && desc->dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600183 skip |= ValidateObject(disp, desc->dstSet, kVulkanObjectTypeDescriptorSet, false, "VUID-VkWriteDescriptorSet-dstSet-00320",
184 "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700185 }
186
187 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
188 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
189 for (uint32_t idx2 = 0; idx2 < desc->descriptorCount; ++idx2) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600190 skip |= ValidateObject(disp, desc->pTexelBufferView[idx2], kVulkanObjectTypeBufferView, false,
191 "VUID-VkWriteDescriptorSet-descriptorType-00323", "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700192 }
193 }
194
195 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
Dave Houltona9df0ce2018-02-07 10:51:23 -0700196 (desc->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
Chris Forbes2c600e92017-10-20 11:13:20 -0700197 (desc->descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
198 for (uint32_t idx3 = 0; idx3 < desc->descriptorCount; ++idx3) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600199 skip |= ValidateObject(disp, desc->pImageInfo[idx3].imageView, kVulkanObjectTypeImageView, false,
200 "VUID-VkWriteDescriptorSet-descriptorType-00326", "VUID-VkDescriptorImageInfo-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700201 }
202 }
203
204 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
205 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
206 (desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
207 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
208 for (uint32_t idx4 = 0; idx4 < desc->descriptorCount; ++idx4) {
209 if (desc->pBufferInfo[idx4].buffer) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600210 skip |= ValidateObject(disp, desc->pBufferInfo[idx4].buffer, kVulkanObjectTypeBuffer, false,
211 "VUID-VkDescriptorBufferInfo-buffer-parameter", kVUIDUndefined);
Chris Forbes2c600e92017-10-20 11:13:20 -0700212 }
213 }
214 }
215
216 return skip;
217}
218
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600219bool ObjectLifetimes::PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
220 VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
221 const VkWriteDescriptorSet *pDescriptorWrites) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600222 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600223 skip |= ValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false,
224 "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
225 skip |= ValidateObject(commandBuffer, layout, kVulkanObjectTypePipelineLayout, false,
226 "VUID-vkCmdPushDescriptorSetKHR-layout-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600227 if (pDescriptorWrites) {
228 for (uint32_t index0 = 0; index0 < descriptorWriteCount; ++index0) {
229 skip |= ValidateDescriptorWrite(commandBuffer, &pDescriptorWrites[index0], true);
230 }
231 }
232 return skip;
233}
234
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600235void ObjectLifetimes::CreateQueue(VkDevice device, VkQueue vkObj) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600236 log_msg(report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, HandleToUint64(vkObj),
237 kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
238 "VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT", HandleToUint64(vkObj));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600239
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600240 ObjTrackState *p_obj_node = NULL;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600241 auto queue_item = object_map[kVulkanObjectTypeQueue].find(HandleToUint64(vkObj));
242 if (queue_item == object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600243 p_obj_node = new ObjTrackState;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600244 object_map[kVulkanObjectTypeQueue][HandleToUint64(vkObj)] = p_obj_node;
245 num_objects[kVulkanObjectTypeQueue]++;
246 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600247 } else {
248 p_obj_node = queue_item->second;
249 }
250 p_obj_node->object_type = kVulkanObjectTypeQueue;
251 p_obj_node->status = OBJSTATUS_NONE;
252 p_obj_node->handle = HandleToUint64(vkObj);
253}
254
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600255void ObjectLifetimes::CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600256 log_msg(report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -0600257 HandleToUint64(swapchain_image), kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600258 object_track_index++, "SwapchainImage", HandleToUint64(swapchain_image));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600259
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600260 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600261 pNewObjNode->object_type = kVulkanObjectTypeImage;
262 pNewObjNode->status = OBJSTATUS_NONE;
263 pNewObjNode->handle = HandleToUint64(swapchain_image);
264 pNewObjNode->parent_object = HandleToUint64(swapchain);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600265 swapchainImageMap[HandleToUint64(swapchain_image)] = pNewObjNode;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600266}
267
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600268bool ObjectLifetimes::DeviceReportUndestroyedObjects(VkDevice device, VulkanObjectType object_type, const std::string &error_code) {
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600269 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600270 for (const auto &item : object_map[object_type]) {
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000271 const ObjTrackState *object_info = item.second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600272 skip |=
273 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type], object_info->handle, error_code,
274 "OBJ ERROR : For device 0x%" PRIxLEAST64 ", %s object 0x%" PRIxLEAST64 " has not been destroyed.",
275 HandleToUint64(device), object_string[object_type], object_info->handle);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000276 }
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600277 return skip;
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000278}
279
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600280void ObjectLifetimes::DeviceDestroyUndestroyedObjects(VkDevice device, VulkanObjectType object_type) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600281 while (!object_map[object_type].empty()) {
282 auto item = object_map[object_type].begin();
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000283
284 ObjTrackState *object_info = item->second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600285 DestroyObjectSilently(object_info->handle, object_type);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600286 }
287}
288
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600289bool ObjectLifetimes::PreCallValidateDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600290 bool skip = false;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600291
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600292 // We validate here for coverage, though we'd not have made it this for with a bad instance.
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600293 skip |= ValidateObject(instance, instance, kVulkanObjectTypeInstance, true, "VUID-vkDestroyInstance-instance-parameter",
294 kVUIDUndefined);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600295
296 // Validate that child devices have been destroyed
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600297 for (const auto &iit : object_map[kVulkanObjectTypeDevice]) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600298 ObjTrackState *pNode = iit.second;
299
300 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
301 VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[pNode->object_type];
302
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600303 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, pNode->handle,
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600304 kVUID_ObjectTracker_ObjectLeak, "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.",
305 string_VkDebugReportObjectTypeEXT(debug_object_type), pNode->handle);
306
307 // Report any remaining objects in LL
308 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyInstance-instance-00629");
309
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600310 skip |= ValidateDestroyObject(instance, device, kVulkanObjectTypeDevice, pAllocator,
311 "VUID-vkDestroyInstance-instance-00630", "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600312 }
313
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600314 ValidateDestroyObject(instance, instance, kVulkanObjectTypeInstance, pAllocator, "VUID-vkDestroyInstance-instance-00630",
315 "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600316
317 return skip;
318}
319
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600320bool ObjectLifetimes::PreCallValidateEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
321 VkPhysicalDevice *pPhysicalDevices) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600322 bool skip = ValidateObject(instance, instance, kVulkanObjectTypeInstance, false,
323 "VUID-vkEnumeratePhysicalDevices-instance-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600324 return skip;
325}
326
327void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
328 VkPhysicalDevice *pPhysicalDevices) {
329 if (pPhysicalDevices) {
330 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600331 CreateObject(instance, pPhysicalDevices[i], kVulkanObjectTypePhysicalDevice, nullptr);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600332 }
333 }
334}
335
336void ObjectLifetimes::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600337 // Destroy physical devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600338 for (auto iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
339 iit != object_map[kVulkanObjectTypePhysicalDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600340 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600341 VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(pNode->handle);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600342 RecordDestroyObject(instance, physical_device, kVulkanObjectTypePhysicalDevice);
343 iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600344 }
345
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700346 // Destroy child devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600347 for (auto iit = object_map[kVulkanObjectTypeDevice].begin(); iit != object_map[kVulkanObjectTypeDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600348 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600349 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000350 DestroyUndestroyedObjects(device);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700351
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600352 RecordDestroyObject(instance, device, kVulkanObjectTypeDevice);
353 iit = object_map[kVulkanObjectTypeDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600354 }
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700355
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600356 object_map[kVulkanObjectTypeDevice].clear();
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600357}
358
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600359void ObjectLifetimes::PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600360 RecordDestroyObject(instance, instance, kVulkanObjectTypeInstance);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600361}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600362
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600363bool ObjectLifetimes::PreCallValidateDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600364 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600365 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, true, "VUID-vkDestroyDevice-device-parameter", kVUIDUndefined);
366 skip |= ValidateDestroyObject(physical_device, device, kVulkanObjectTypeDevice, pAllocator, "VUID-vkDestroyDevice-device-00379",
367 "VUID-vkDestroyDevice-device-00380");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600368 // Report any remaining objects associated with this VkDevice object in LL
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600369 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyDevice-device-00378");
370
371 return skip;
372}
373
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600374void ObjectLifetimes::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600375 RecordDestroyObject(physical_device, device, kVulkanObjectTypeDevice);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000376 DestroyUndestroyedObjects(device);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600377
378 // Clean up Queue's MemRef Linked Lists
379 DestroyQueueDataStructures(device);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600380}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600381
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600382bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
383 VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600384 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600385 skip |=
386 ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600387 return skip;
388}
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600389
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600390void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
391 VkQueue *pQueue) {
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600392 CreateQueue(device, *pQueue);
393 AddQueueInfo(device, queueFamilyIndex, *pQueue);
394}
395
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600396bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600397 return ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue2-device-parameter",
398 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600399}
400
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600401void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600402 CreateQueue(device, *pQueue);
403 AddQueueInfo(device, pQueueInfo->queueFamilyIndex, *pQueue);
404}
405
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600406bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
407 const VkWriteDescriptorSet *pDescriptorWrites,
408 uint32_t descriptorCopyCount,
409 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600410 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600411 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkUpdateDescriptorSets-device-parameter",
412 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600413 if (pDescriptorCopies) {
414 for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
415 if (pDescriptorCopies[idx0].dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600416 skip |= ValidateObject(device, pDescriptorCopies[idx0].dstSet, kVulkanObjectTypeDescriptorSet, false,
417 "VUID-VkCopyDescriptorSet-dstSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600418 }
419 if (pDescriptorCopies[idx0].srcSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600420 skip |= ValidateObject(device, pDescriptorCopies[idx0].srcSet, kVulkanObjectTypeDescriptorSet, false,
421 "VUID-VkCopyDescriptorSet-srcSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600422 }
423 }
424 }
425 if (pDescriptorWrites) {
426 for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
427 skip |= ValidateDescriptorWrite(device, &pDescriptorWrites[idx1], false);
428 }
429 }
430 return skip;
431}
432
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600433bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
434 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600435 bool skip = false;
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600436
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600437 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter",
438 kVUIDUndefined);
439 skip |=
440 ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
441 "VUID-vkResetDescriptorPool-descriptorPool-parameter", "VUID-vkResetDescriptorPool-descriptorPool-parent");
442 for (const auto &itr : object_map[kVulkanObjectTypeDescriptorSet]) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600443 if (itr.second->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600444 skip |= ValidateDestroyObject(device, (VkDescriptorSet)(itr.first), kVulkanObjectTypeDescriptorSet, nullptr,
445 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600446 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600447 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600448 return skip;
449}
450
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600451void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
452 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600453 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
454 // our descriptorSet map.
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600455 auto itr = object_map[kVulkanObjectTypeDescriptorSet].begin();
456 while (itr != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600457 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600458 auto del_itr = itr++;
459 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600460 RecordDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600461 }
462 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600463}
464
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600465bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
466 const VkCommandBufferBeginInfo *begin_info) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600467 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600468 skip |= ValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
469 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600470 if (begin_info) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600471 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600472 if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
473 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600474 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
475 "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
476 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
477 "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600478 }
479 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600480 return skip;
481}
482
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600483bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
484 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600485 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600486 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
487 "VUID-vkGetSwapchainImagesKHR-commonparent");
488 skip |= ValidateObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, false,
489 "VUID-vkGetSwapchainImagesKHR-swapchain-parameter", "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600490 return skip;
491}
492
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600493void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
494 VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600495 if (pSwapchainImages != NULL) {
496 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
497 CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
498 }
499 }
500}
501
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600502bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
503 const VkAllocationCallbacks *pAllocator,
504 VkDescriptorSetLayout *pSetLayout) {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100505 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600506 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorSetLayout-device-parameter",
507 kVUIDUndefined);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600508 if (pCreateInfo) {
509 if (pCreateInfo->pBindings) {
510 for (uint32_t binding_index = 0; binding_index < pCreateInfo->bindingCount; ++binding_index) {
511 const VkDescriptorSetLayoutBinding &binding = pCreateInfo->pBindings[binding_index];
512 const bool is_sampler_type = binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
513 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
514 if (binding.pImmutableSamplers && is_sampler_type) {
515 for (uint32_t index2 = 0; index2 < binding.descriptorCount; ++index2) {
516 const VkSampler sampler = binding.pImmutableSamplers[index2];
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600517 skip |= ValidateObject(device, sampler, kVulkanObjectTypeSampler, false,
518 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100519 }
520 }
521 }
522 }
523 }
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600524 return skip;
525}
526
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600527void ObjectLifetimes::PostCallRecordCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
528 const VkAllocationCallbacks *pAllocator,
529 VkDescriptorSetLayout *pSetLayout) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600530 CreateObject(device, *pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600531}
532
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600533bool ObjectLifetimes::ValidateSamplerObjects(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo) {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600534 bool skip = false;
535 if (pCreateInfo->pBindings) {
536 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
537 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
538 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600539 skip |=
540 ValidateObject(device, pCreateInfo->pBindings[index1].pImmutableSamplers[index2], kVulkanObjectTypeSampler,
541 true, "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600542 }
543 }
544 }
545 }
546 return skip;
547}
548
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600549bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(VkDevice device,
550 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
551 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600552 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
553 "VUID-vkGetDescriptorSetLayoutSupport-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600554 if (pCreateInfo) {
555 skip |= ValidateSamplerObjects(device, pCreateInfo);
556 }
557 return skip;
558}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600559bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
560 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
561 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600562 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
563 "VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600564 if (pCreateInfo) {
565 skip |= ValidateSamplerObjects(device, pCreateInfo);
566 }
567 return skip;
568}
569
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600570bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
571 uint32_t *pQueueFamilyPropertyCount,
572 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600573 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
574 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600575}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600576
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600577void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
578 uint32_t *pQueueFamilyPropertyCount,
579 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600580 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600581 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
582 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600583 }
584 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600585 queue_family_properties[i] = pQueueFamilyProperties[i];
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600586 }
587 }
588}
589
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600590void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
591 VkInstance *pInstance) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600592 CreateObject(*pInstance, *pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600593}
594
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600595bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
596 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600597 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600598 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter",
599 kVUIDUndefined);
600 skip |= ValidateObject(device, pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
601 "VUID-VkCommandBufferAllocateInfo-commandPool-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600602 return skip;
603}
604
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600605void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
606 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600607 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
608 AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
609 }
610}
611
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600612bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
613 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600614 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600615 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
616 kVUIDUndefined);
617 skip |= ValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
618 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
619 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600620 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600621 skip |= ValidateObject(device, pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
622 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
623 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600624 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600625 return skip;
626}
627
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600628void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
629 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600630 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
631 AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600632 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600633}
634
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600635bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
636 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600637 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600638 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter",
639 kVUIDUndefined);
640 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, false,
641 "VUID-vkFreeCommandBuffers-commandPool-parameter", "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600642 for (uint32_t i = 0; i < commandBufferCount; i++) {
643 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
644 skip |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600645 skip |= ValidateDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined,
646 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600647 }
648 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600649 return skip;
650}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600651
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600652void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
653 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600654 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600655 RecordDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600656 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600657}
658
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600659bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
660 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600661 return ValidateDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator,
662 "VUID-vkDestroySwapchainKHR-swapchain-01283", "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600663}
664
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600665void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
666 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600667 RecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
668 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = swapchainImageMap.begin();
669 while (itr != swapchainImageMap.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600670 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600671 if (pNode->parent_object == HandleToUint64(swapchain)) {
672 delete pNode;
673 auto delete_item = itr++;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600674 swapchainImageMap.erase(delete_item);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600675 } else {
676 ++itr;
677 }
678 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600679}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600680
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600681bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
682 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600683 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600684 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
685 kVUIDUndefined);
686 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
687 "VUID-vkFreeDescriptorSets-descriptorPool-parameter", "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600688 for (uint32_t i = 0; i < descriptorSetCount; i++) {
689 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
690 skip |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600691 skip |= ValidateDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
692 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600693 }
694 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600695 return skip;
696}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600697void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
698 const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600699 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600700 RecordDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600701 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600702}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600703
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600704bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
705 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600706 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600707 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
708 kVUIDUndefined);
709 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, true,
710 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
711 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
712 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = object_map[kVulkanObjectTypeDescriptorSet].begin();
713 while (itr != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600714 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600715 auto del_itr = itr++;
716 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600717 skip |= ValidateDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet, nullptr,
718 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600719 }
720 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600721 skip |= ValidateDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
722 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
723 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600724 return skip;
725}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600726void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
727 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600728 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = object_map[kVulkanObjectTypeDescriptorSet].begin();
729 while (itr != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600730 ObjTrackState *pNode = (*itr).second;
731 auto del_itr = itr++;
732 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600733 RecordDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600734 }
735 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600736 RecordDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600737}
738
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600739bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
740 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600741 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600742 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter",
743 kVUIDUndefined);
744 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
745 "VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
746 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600747 auto del_itr = itr;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600748 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600749 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600750 del_itr = itr++;
751 if (pNode->parent_object == HandleToUint64(commandPool)) {
752 skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600753 skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
754 kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600755 }
756 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600757 skip |= ValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
758 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600759 return skip;
760}
761
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600762void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
763 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600764 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600765 auto del_itr = itr;
766 // A CommandPool's cmd buffers are implicitly deleted when pool is deleted. Remove this pool's cmdBuffers from cmd buffer map.
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600767 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600768 ObjTrackState *pNode = (*itr).second;
769 del_itr = itr++;
770 if (pNode->parent_object == HandleToUint64(commandPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600771 RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600772 }
773 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600774 RecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600775}
776
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600777bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
778 uint32_t *pQueueFamilyPropertyCount,
779 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600780 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
781 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600782}
783
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600784bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
785 uint32_t *pQueueFamilyPropertyCount,
786 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600787 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Shannon McPherson3ea65132018-12-05 10:37:39 -0700788 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600789}
790
791void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
792 uint32_t *pQueueFamilyPropertyCount,
793 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600794 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600795 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
796 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600797 }
798 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600799 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600800 }
801 }
802}
803
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600804void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
805 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600806 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600807 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
808 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600809 }
810 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600811 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600812 }
813 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600814}
815
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600816bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
817 uint32_t *pPropertyCount,
818 VkDisplayPropertiesKHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600819 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
820 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600821}
822
823void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
824 VkDisplayPropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600825 if (pProperties) {
826 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600827 CreateObject(physicalDevice, pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600828 }
829 }
830}
831
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600832bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
833 uint32_t *pPropertyCount,
834 VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600835 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600836 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
837 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
838 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
839 "VUID-vkGetDisplayModePropertiesKHR-display-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600840
841 return skip;
842}
843
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600844void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
845 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600846 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600847 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600848 CreateObject(physicalDevice, pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600849 }
850 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600851}
852
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600853bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
854 uint32_t *pPropertyCount,
855 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600856 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
857 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600858}
859
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600860void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
861 uint32_t *pPropertyCount,
862 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600863 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600864 CreateObject(physicalDevice, pProperties[index].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600865 }
866}
867
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600868bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
869 uint32_t *pPropertyCount,
870 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600871 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600872 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
873 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
874 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
875 "VUID-vkGetDisplayModeProperties2KHR-display-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600876
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600877 return skip;
878}
879
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600880void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
881 uint32_t *pPropertyCount,
882 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600883 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600884 CreateObject(physicalDevice, pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR,
885 nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600886 }
887}