blob: 386475dd4222e345f4794d963396cf6acc1c77bc [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 Lobodzinski52db2352018-12-28 09:41:15 -0700375 auto instance_data = GetLayerDataPtr(get_dispatch_key(physical_device), layer_data_map);
376 ValidationObject *validation_data = GetValidationObject(instance_data->object_dispatch, LayerObjectTypeObjectTracker);
377 ObjectLifetimes *object_lifetimes = static_cast<ObjectLifetimes *>(validation_data);
378 object_lifetimes->RecordDestroyObject(physical_device, device, kVulkanObjectTypeDevice);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000379 DestroyUndestroyedObjects(device);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600380
381 // Clean up Queue's MemRef Linked Lists
382 DestroyQueueDataStructures(device);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600383}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600384
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600385bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
386 VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600387 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600388 skip |=
389 ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600390 return skip;
391}
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600392
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600393void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
394 VkQueue *pQueue) {
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600395 CreateQueue(device, *pQueue);
396 AddQueueInfo(device, queueFamilyIndex, *pQueue);
397}
398
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600399bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600400 return ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue2-device-parameter",
401 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600402}
403
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600404void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600405 CreateQueue(device, *pQueue);
406 AddQueueInfo(device, pQueueInfo->queueFamilyIndex, *pQueue);
407}
408
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600409bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
410 const VkWriteDescriptorSet *pDescriptorWrites,
411 uint32_t descriptorCopyCount,
412 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600413 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600414 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkUpdateDescriptorSets-device-parameter",
415 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600416 if (pDescriptorCopies) {
417 for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
418 if (pDescriptorCopies[idx0].dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600419 skip |= ValidateObject(device, pDescriptorCopies[idx0].dstSet, kVulkanObjectTypeDescriptorSet, false,
420 "VUID-VkCopyDescriptorSet-dstSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600421 }
422 if (pDescriptorCopies[idx0].srcSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600423 skip |= ValidateObject(device, pDescriptorCopies[idx0].srcSet, kVulkanObjectTypeDescriptorSet, false,
424 "VUID-VkCopyDescriptorSet-srcSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600425 }
426 }
427 }
428 if (pDescriptorWrites) {
429 for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
430 skip |= ValidateDescriptorWrite(device, &pDescriptorWrites[idx1], false);
431 }
432 }
433 return skip;
434}
435
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600436bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
437 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600438 bool skip = false;
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600439
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600440 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter",
441 kVUIDUndefined);
442 skip |=
443 ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
444 "VUID-vkResetDescriptorPool-descriptorPool-parameter", "VUID-vkResetDescriptorPool-descriptorPool-parent");
445 for (const auto &itr : object_map[kVulkanObjectTypeDescriptorSet]) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600446 if (itr.second->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600447 skip |= ValidateDestroyObject(device, (VkDescriptorSet)(itr.first), kVulkanObjectTypeDescriptorSet, nullptr,
448 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600449 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600450 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600451 return skip;
452}
453
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600454void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
455 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600456 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
457 // our descriptorSet map.
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600458 auto itr = object_map[kVulkanObjectTypeDescriptorSet].begin();
459 while (itr != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600460 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600461 auto del_itr = itr++;
462 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600463 RecordDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600464 }
465 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600466}
467
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600468bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
469 const VkCommandBufferBeginInfo *begin_info) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600470 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600471 skip |= ValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
472 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600473 if (begin_info) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600474 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600475 if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
476 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600477 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
478 "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
479 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
480 "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600481 }
482 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600483 return skip;
484}
485
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600486bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
487 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600488 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600489 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
490 "VUID-vkGetSwapchainImagesKHR-commonparent");
491 skip |= ValidateObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, false,
492 "VUID-vkGetSwapchainImagesKHR-swapchain-parameter", "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600493 return skip;
494}
495
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600496void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
497 VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600498 if (pSwapchainImages != NULL) {
499 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
500 CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
501 }
502 }
503}
504
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600505bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
506 const VkAllocationCallbacks *pAllocator,
507 VkDescriptorSetLayout *pSetLayout) {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100508 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600509 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorSetLayout-device-parameter",
510 kVUIDUndefined);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600511 if (pCreateInfo) {
512 if (pCreateInfo->pBindings) {
513 for (uint32_t binding_index = 0; binding_index < pCreateInfo->bindingCount; ++binding_index) {
514 const VkDescriptorSetLayoutBinding &binding = pCreateInfo->pBindings[binding_index];
515 const bool is_sampler_type = binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
516 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
517 if (binding.pImmutableSamplers && is_sampler_type) {
518 for (uint32_t index2 = 0; index2 < binding.descriptorCount; ++index2) {
519 const VkSampler sampler = binding.pImmutableSamplers[index2];
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600520 skip |= ValidateObject(device, sampler, kVulkanObjectTypeSampler, false,
521 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100522 }
523 }
524 }
525 }
526 }
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600527 return skip;
528}
529
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600530void ObjectLifetimes::PostCallRecordCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
531 const VkAllocationCallbacks *pAllocator,
532 VkDescriptorSetLayout *pSetLayout) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600533 CreateObject(device, *pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600534}
535
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600536bool ObjectLifetimes::ValidateSamplerObjects(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo) {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600537 bool skip = false;
538 if (pCreateInfo->pBindings) {
539 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
540 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
541 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600542 skip |=
543 ValidateObject(device, pCreateInfo->pBindings[index1].pImmutableSamplers[index2], kVulkanObjectTypeSampler,
544 true, "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600545 }
546 }
547 }
548 }
549 return skip;
550}
551
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600552bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(VkDevice device,
553 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
554 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600555 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
556 "VUID-vkGetDescriptorSetLayoutSupport-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600557 if (pCreateInfo) {
558 skip |= ValidateSamplerObjects(device, pCreateInfo);
559 }
560 return skip;
561}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600562bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
563 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
564 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600565 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
566 "VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600567 if (pCreateInfo) {
568 skip |= ValidateSamplerObjects(device, pCreateInfo);
569 }
570 return skip;
571}
572
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600573bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
574 uint32_t *pQueueFamilyPropertyCount,
575 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600576 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
577 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600578}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600579
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600580void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
581 uint32_t *pQueueFamilyPropertyCount,
582 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600583 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600584 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
585 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600586 }
587 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600588 queue_family_properties[i] = pQueueFamilyProperties[i];
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600589 }
590 }
591}
592
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600593void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
594 VkInstance *pInstance) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600595 CreateObject(*pInstance, *pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600596}
597
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600598bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
599 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600600 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600601 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter",
602 kVUIDUndefined);
603 skip |= ValidateObject(device, pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
604 "VUID-VkCommandBufferAllocateInfo-commandPool-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600605 return skip;
606}
607
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600608void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
609 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600610 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
611 AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
612 }
613}
614
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600615bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
616 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600617 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600618 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
619 kVUIDUndefined);
620 skip |= ValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
621 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
622 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600623 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600624 skip |= ValidateObject(device, pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
625 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
626 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600627 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600628 return skip;
629}
630
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600631void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
632 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600633 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
634 AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600635 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600636}
637
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600638bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
639 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600640 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600641 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter",
642 kVUIDUndefined);
643 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, false,
644 "VUID-vkFreeCommandBuffers-commandPool-parameter", "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600645 for (uint32_t i = 0; i < commandBufferCount; i++) {
646 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
647 skip |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600648 skip |= ValidateDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined,
649 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600650 }
651 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600652 return skip;
653}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600654
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600655void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
656 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600657 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600658 RecordDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600659 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600660}
661
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600662bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
663 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600664 return ValidateDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator,
665 "VUID-vkDestroySwapchainKHR-swapchain-01283", "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600666}
667
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600668void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
669 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600670 RecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
671 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = swapchainImageMap.begin();
672 while (itr != swapchainImageMap.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600673 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600674 if (pNode->parent_object == HandleToUint64(swapchain)) {
675 delete pNode;
676 auto delete_item = itr++;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600677 swapchainImageMap.erase(delete_item);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600678 } else {
679 ++itr;
680 }
681 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600682}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600683
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600684bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
685 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600686 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600687 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
688 kVUIDUndefined);
689 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
690 "VUID-vkFreeDescriptorSets-descriptorPool-parameter", "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600691 for (uint32_t i = 0; i < descriptorSetCount; i++) {
692 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
693 skip |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600694 skip |= ValidateDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
695 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600696 }
697 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600698 return skip;
699}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600700void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
701 const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600702 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600703 RecordDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600704 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600705}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600706
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600707bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
708 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600709 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600710 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
711 kVUIDUndefined);
712 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, true,
713 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
714 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
715 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = object_map[kVulkanObjectTypeDescriptorSet].begin();
716 while (itr != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600717 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600718 auto del_itr = itr++;
719 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600720 skip |= ValidateDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet, nullptr,
721 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600722 }
723 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600724 skip |= ValidateDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
725 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
726 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600727 return skip;
728}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600729void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
730 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600731 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = object_map[kVulkanObjectTypeDescriptorSet].begin();
732 while (itr != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600733 ObjTrackState *pNode = (*itr).second;
734 auto del_itr = itr++;
735 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600736 RecordDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600737 }
738 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600739 RecordDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600740}
741
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600742bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
743 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600744 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600745 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter",
746 kVUIDUndefined);
747 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
748 "VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
749 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600750 auto del_itr = itr;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600751 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600752 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600753 del_itr = itr++;
754 if (pNode->parent_object == HandleToUint64(commandPool)) {
755 skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600756 skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
757 kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600758 }
759 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600760 skip |= ValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
761 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600762 return skip;
763}
764
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600765void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
766 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600767 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600768 auto del_itr = itr;
769 // 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 -0600770 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600771 ObjTrackState *pNode = (*itr).second;
772 del_itr = itr++;
773 if (pNode->parent_object == HandleToUint64(commandPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600774 RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600775 }
776 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600777 RecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600778}
779
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600780bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
781 uint32_t *pQueueFamilyPropertyCount,
782 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600783 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
784 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600785}
786
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600787bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
788 uint32_t *pQueueFamilyPropertyCount,
789 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600790 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Shannon McPherson3ea65132018-12-05 10:37:39 -0700791 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600792}
793
794void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
795 uint32_t *pQueueFamilyPropertyCount,
796 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600797 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600798 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
799 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600800 }
801 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600802 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600803 }
804 }
805}
806
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600807void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
808 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600809 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600810 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
811 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600812 }
813 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600814 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600815 }
816 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600817}
818
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600819bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
820 uint32_t *pPropertyCount,
821 VkDisplayPropertiesKHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600822 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
823 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600824}
825
826void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
827 VkDisplayPropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600828 if (pProperties) {
829 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600830 CreateObject(physicalDevice, pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600831 }
832 }
833}
834
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600835bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
836 uint32_t *pPropertyCount,
837 VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600838 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600839 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
840 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
841 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
842 "VUID-vkGetDisplayModePropertiesKHR-display-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600843
844 return skip;
845}
846
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600847void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
848 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600849 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600850 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600851 CreateObject(physicalDevice, pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600852 }
853 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600854}
855
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600856bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
857 uint32_t *pPropertyCount,
858 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600859 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
860 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600861}
862
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600863void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
864 uint32_t *pPropertyCount,
865 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600866 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600867 CreateObject(physicalDevice, pProperties[index].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600868 }
869}
870
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600871bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
872 uint32_t *pPropertyCount,
873 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600874 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600875 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
876 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
877 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
878 "VUID-vkGetDisplayModeProperties2KHR-display-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600879
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600880 return skip;
881}
882
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600883void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
884 uint32_t *pPropertyCount,
885 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600886 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600887 CreateObject(physicalDevice, pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR,
888 nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600889 }
890}