blob: f3d046f88172272bd4d5148f810b573af47a35b5 [file] [log] [blame]
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07001/* Copyright (c) 2015-2019 The Khronos Group Inc.
2 * Copyright (c) 2015-2019 Valve Corporation
3 * Copyright (c) 2015-2019 LunarG, Inc.
4 * Copyright (C) 2015-2019 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
John Zulauf1c3844a2019-04-01 17:39:48 -060029VulkanTypedHandle ObjTrackStateTypedHandle(const ObjTrackState &track_state) {
30 // TODO: Unify Typed Handle representation (i.e. VulkanTypedHandle everywhere there are handle/type pairs)
31 VulkanTypedHandle typed_handle;
32 typed_handle.handle = track_state.handle;
33 typed_handle.type = track_state.object_type;
34 return typed_handle;
35}
36
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060037// Add new queue to head of global queue list
Mark Lobodzinski0c668462018-09-27 10:13:19 -060038void ObjectLifetimes::AddQueueInfo(VkDevice device, uint32_t queue_node_index, VkQueue queue) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060039 auto queueItem = queue_info_map.find(queue);
40 if (queueItem == queue_info_map.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060041 ObjTrackQueueInfo *p_queue_info = new ObjTrackQueueInfo;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060042 if (p_queue_info != NULL) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060043 memset(p_queue_info, 0, sizeof(ObjTrackQueueInfo));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060044 p_queue_info->queue = queue;
45 p_queue_info->queue_node_index = queue_node_index;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060046 queue_info_map[queue] = p_queue_info;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060047 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060048 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, HandleToUint64(queue),
49 kVUID_ObjectTracker_InternalError,
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060050 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
51 }
52 }
53}
54
55// Destroy memRef lists and free all memory
Mark Lobodzinski0c668462018-09-27 10:13:19 -060056void ObjectLifetimes::DestroyQueueDataStructures(VkDevice device) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060057 for (auto queue_item : queue_info_map) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060058 delete queue_item.second;
59 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060060 queue_info_map.clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060061
62 // Destroy the items in the queue map
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060063 auto queue = object_map[kVulkanObjectTypeQueue].begin();
64 while (queue != object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060065 uint32_t obj_index = queue->second->object_type;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060066 assert(num_total_objects > 0);
67 num_total_objects--;
68 assert(num_objects[obj_index] > 0);
69 num_objects[obj_index]--;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060070 delete queue->second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060071 queue = object_map[kVulkanObjectTypeQueue].erase(queue);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060072 }
73}
74
75// Check Queue type flags for selected queue operations
Mark Lobodzinski0c668462018-09-27 10:13:19 -060076void ObjectLifetimes::ValidateQueueFlags(VkQueue queue, const char *function) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060077 auto queue_item = queue_info_map.find(queue);
78 if (queue_item != queue_info_map.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060079 ObjTrackQueueInfo *pQueueInfo = queue_item->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060080 if (pQueueInfo != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060081 if ((queue_family_properties[pQueueInfo->queue_node_index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
82 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, HandleToUint64(queue),
83 "VUID-vkQueueBindSparse-queuetype",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060084 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set.", function);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060085 }
86 }
87 }
88}
89
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070090// Look for this device object in any of the instance child devices lists.
91// NOTE: This is of dubious value. In most circumstances Vulkan will die a flaming death if a dispatchable object is invalid.
92// However, if this layer is loaded first and GetProcAddress is used to make API calls, it will detect bad DOs.
John Zulauf1c3844a2019-04-01 17:39:48 -060093bool ObjectLifetimes::ValidateDeviceObject(const VulkanTypedHandle &device_typed, const char *invalid_handle_code,
94 const char *wrong_device_code) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060095 auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
96 auto instance_object_lifetime_data = GetObjectLifetimeData(instance_data->object_dispatch);
97 for (auto object : instance_object_lifetime_data->object_map[kVulkanObjectTypeDevice]) {
John Zulauf1c3844a2019-04-01 17:39:48 -060098 if (object.second->handle == device_typed.handle) return false;
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070099 }
John Zulauf1c3844a2019-04-01 17:39:48 -0600100 return log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device_typed.handle,
101 invalid_handle_code, "Invalid Device Object %s.", report_data->FormatHandle(device_typed).c_str());
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700102}
103
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600104void ObjectLifetimes::AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
105 VkCommandBufferLevel level) {
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)) {
John Zulauf1c3844a2019-04-01 17:39:48 -0600127 // We know that the parent *must* be a command pool
128 const auto parent_pool = CastFromUint64<VkCommandPool>(pNode->parent_object);
Locke92335152019-02-18 13:50:36 -0700129 skip |=
130 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, object_handle,
131 "VUID-vkFreeCommandBuffers-pCommandBuffers-parent",
132 "FreeCommandBuffers is attempting to free Command Buffer %s belonging to Command Pool %s from pool %s).",
John Zulauf1c3844a2019-04-01 17:39:48 -0600133 report_data->FormatHandle(command_buffer).c_str(), report_data->FormatHandle(parent_pool).c_str(),
Locke92335152019-02-18 13:50:36 -0700134 report_data->FormatHandle(command_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600135 }
136 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600137 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, object_handle,
Locke24dc1672019-03-03 23:49:22 -0700138 "VUID-vkFreeCommandBuffers-pCommandBuffers-00048", "Invalid %s Object %s.",
John Zulauf1c3844a2019-04-01 17:39:48 -0600139 object_string[kVulkanObjectTypeCommandBuffer], report_data->FormatHandle(command_buffer).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600140 }
141 return skip;
142}
143
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600144void ObjectLifetimes::AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600145 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600146 pNewObjNode->object_type = kVulkanObjectTypeDescriptorSet;
147 pNewObjNode->status = OBJSTATUS_NONE;
148 pNewObjNode->handle = HandleToUint64(descriptor_set);
149 pNewObjNode->parent_object = HandleToUint64(descriptor_pool);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600150 object_map[kVulkanObjectTypeDescriptorSet][HandleToUint64(descriptor_set)] = pNewObjNode;
151 num_objects[kVulkanObjectTypeDescriptorSet]++;
152 num_total_objects++;
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600153
154 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptor_pool));
155 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
156 ObjTrackState *pPoolNode = itr->second;
157 pPoolNode->child_objects->insert(HandleToUint64(descriptor_set));
158 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600159}
160
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600161bool ObjectLifetimes::ValidateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600162 bool skip = false;
163 uint64_t object_handle = HandleToUint64(descriptor_set);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600164 auto dsItem = object_map[kVulkanObjectTypeDescriptorSet].find(object_handle);
165 if (dsItem != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600166 ObjTrackState *pNode = dsItem->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600167
168 if (pNode->parent_object != HandleToUint64(descriptor_pool)) {
John Zulauf1c3844a2019-04-01 17:39:48 -0600169 // We know that the parent *must* be a descriptor pool
170 const auto parent_pool = CastFromUint64<VkDescriptorPool>(pNode->parent_object);
171 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
172 object_handle, "VUID-vkFreeDescriptorSets-pDescriptorSets-parent",
173 "FreeDescriptorSets is attempting to free descriptorSet %s"
174 " belonging to Descriptor Pool %s from pool %s).",
175 report_data->FormatHandle(descriptor_set).c_str(), report_data->FormatHandle(parent_pool).c_str(),
176 report_data->FormatHandle(descriptor_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600177 }
178 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600179 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, object_handle,
Locke24dc1672019-03-03 23:49:22 -0700180 "VUID-vkFreeDescriptorSets-pDescriptorSets-00310", "Invalid %s Object %s.",
John Zulauf1c3844a2019-04-01 17:39:48 -0600181 object_string[kVulkanObjectTypeDescriptorSet], report_data->FormatHandle(descriptor_set).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600182 }
183 return skip;
184}
185
Dave Houltona9df0ce2018-02-07 10:51:23 -0700186template <typename DispObj>
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600187bool ObjectLifetimes::ValidateDescriptorWrite(DispObj disp, VkWriteDescriptorSet const *desc, bool isPush) {
Chris Forbes2c600e92017-10-20 11:13:20 -0700188 bool skip = false;
189
190 if (!isPush && desc->dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600191 skip |= ValidateObject(disp, desc->dstSet, kVulkanObjectTypeDescriptorSet, false, "VUID-VkWriteDescriptorSet-dstSet-00320",
192 "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700193 }
194
195 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
196 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
197 for (uint32_t idx2 = 0; idx2 < desc->descriptorCount; ++idx2) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600198 skip |= ValidateObject(disp, desc->pTexelBufferView[idx2], kVulkanObjectTypeBufferView, false,
199 "VUID-VkWriteDescriptorSet-descriptorType-00323", "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700200 }
201 }
202
203 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
Dave Houltona9df0ce2018-02-07 10:51:23 -0700204 (desc->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
Chris Forbes2c600e92017-10-20 11:13:20 -0700205 (desc->descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
206 for (uint32_t idx3 = 0; idx3 < desc->descriptorCount; ++idx3) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600207 skip |= ValidateObject(disp, desc->pImageInfo[idx3].imageView, kVulkanObjectTypeImageView, false,
208 "VUID-VkWriteDescriptorSet-descriptorType-00326", "VUID-VkDescriptorImageInfo-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700209 }
210 }
211
212 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
213 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
214 (desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
215 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
216 for (uint32_t idx4 = 0; idx4 < desc->descriptorCount; ++idx4) {
217 if (desc->pBufferInfo[idx4].buffer) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600218 skip |= ValidateObject(disp, desc->pBufferInfo[idx4].buffer, kVulkanObjectTypeBuffer, false,
219 "VUID-VkDescriptorBufferInfo-buffer-parameter", kVUIDUndefined);
Chris Forbes2c600e92017-10-20 11:13:20 -0700220 }
221 }
222 }
223
224 return skip;
225}
226
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600227bool ObjectLifetimes::PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
228 VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
229 const VkWriteDescriptorSet *pDescriptorWrites) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600230 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600231 skip |= ValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false,
232 "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
233 skip |= ValidateObject(commandBuffer, layout, kVulkanObjectTypePipelineLayout, false,
234 "VUID-vkCmdPushDescriptorSetKHR-layout-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600235 if (pDescriptorWrites) {
236 for (uint32_t index0 = 0; index0 < descriptorWriteCount; ++index0) {
237 skip |= ValidateDescriptorWrite(commandBuffer, &pDescriptorWrites[index0], true);
238 }
239 }
240 return skip;
241}
242
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600243void ObjectLifetimes::CreateQueue(VkDevice device, VkQueue vkObj) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600244 ObjTrackState *p_obj_node = NULL;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600245 auto queue_item = object_map[kVulkanObjectTypeQueue].find(HandleToUint64(vkObj));
246 if (queue_item == object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600247 p_obj_node = new ObjTrackState;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600248 object_map[kVulkanObjectTypeQueue][HandleToUint64(vkObj)] = p_obj_node;
249 num_objects[kVulkanObjectTypeQueue]++;
250 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600251 } else {
252 p_obj_node = queue_item->second;
253 }
254 p_obj_node->object_type = kVulkanObjectTypeQueue;
255 p_obj_node->status = OBJSTATUS_NONE;
256 p_obj_node->handle = HandleToUint64(vkObj);
257}
258
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600259void ObjectLifetimes::CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain) {
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,
Locke92335152019-02-18 13:50:36 -0700274 "OBJ ERROR : For device %s, %s object %s has not been destroyed.", report_data->FormatHandle(device).c_str(),
John Zulauf1c3844a2019-04-01 17:39:48 -0600275 object_string[object_type], report_data->FormatHandle(ObjTrackStateTypedHandle(*object_info)).c_str());
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
John Zulauf1c3844a2019-04-01 17:39:48 -0600303 skip |=
304 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, pNode->handle, kVUID_ObjectTracker_ObjectLeak,
305 "OBJ ERROR : %s object %s has not been destroyed.", string_VkDebugReportObjectTypeEXT(debug_object_type),
306 report_data->FormatHandle(ObjTrackStateTypedHandle(*pNode)).c_str());
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600307
308 // Report any remaining objects in LL
309 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyInstance-instance-00629");
310
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600311 skip |= ValidateDestroyObject(instance, device, kVulkanObjectTypeDevice, pAllocator,
312 "VUID-vkDestroyInstance-instance-00630", "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600313 }
314
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600315 ValidateDestroyObject(instance, instance, kVulkanObjectTypeInstance, pAllocator, "VUID-vkDestroyInstance-instance-00630",
316 "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600317
318 return skip;
319}
320
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600321bool ObjectLifetimes::PreCallValidateEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
322 VkPhysicalDevice *pPhysicalDevices) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600323 bool skip = ValidateObject(instance, instance, kVulkanObjectTypeInstance, false,
324 "VUID-vkEnumeratePhysicalDevices-instance-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600325 return skip;
326}
327
328void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700329 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
330 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600331 if (pPhysicalDevices) {
332 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600333 CreateObject(instance, pPhysicalDevices[i], kVulkanObjectTypePhysicalDevice, nullptr);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600334 }
335 }
336}
337
338void ObjectLifetimes::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600339 // Destroy physical devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600340 for (auto iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
341 iit != object_map[kVulkanObjectTypePhysicalDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600342 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600343 VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(pNode->handle);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600344 RecordDestroyObject(instance, physical_device, kVulkanObjectTypePhysicalDevice);
345 iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600346 }
347
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700348 // Destroy child devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600349 for (auto iit = object_map[kVulkanObjectTypeDevice].begin(); iit != object_map[kVulkanObjectTypeDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600350 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600351 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000352 DestroyUndestroyedObjects(device);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700353
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600354 RecordDestroyObject(instance, device, kVulkanObjectTypeDevice);
355 iit = object_map[kVulkanObjectTypeDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600356 }
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700357
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600358 object_map[kVulkanObjectTypeDevice].clear();
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600359}
360
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600361void ObjectLifetimes::PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600362 RecordDestroyObject(instance, instance, kVulkanObjectTypeInstance);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600363}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600364
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600365bool ObjectLifetimes::PreCallValidateDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600366 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600367 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, true, "VUID-vkDestroyDevice-device-parameter", kVUIDUndefined);
368 skip |= ValidateDestroyObject(physical_device, device, kVulkanObjectTypeDevice, pAllocator, "VUID-vkDestroyDevice-device-00379",
369 "VUID-vkDestroyDevice-device-00380");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600370 // Report any remaining objects associated with this VkDevice object in LL
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600371 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyDevice-device-00378");
372
373 return skip;
374}
375
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600376void ObjectLifetimes::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski52db2352018-12-28 09:41:15 -0700377 auto instance_data = GetLayerDataPtr(get_dispatch_key(physical_device), layer_data_map);
378 ValidationObject *validation_data = GetValidationObject(instance_data->object_dispatch, LayerObjectTypeObjectTracker);
379 ObjectLifetimes *object_lifetimes = static_cast<ObjectLifetimes *>(validation_data);
380 object_lifetimes->RecordDestroyObject(physical_device, device, kVulkanObjectTypeDevice);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000381 DestroyUndestroyedObjects(device);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600382
383 // Clean up Queue's MemRef Linked Lists
384 DestroyQueueDataStructures(device);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600385}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600386
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600387bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
388 VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600389 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600390 skip |=
391 ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600392 return skip;
393}
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600394
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600395void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
396 VkQueue *pQueue) {
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600397 CreateQueue(device, *pQueue);
398 AddQueueInfo(device, queueFamilyIndex, *pQueue);
399}
400
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600401bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600402 return ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue2-device-parameter",
403 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600404}
405
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600406void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600407 CreateQueue(device, *pQueue);
408 AddQueueInfo(device, pQueueInfo->queueFamilyIndex, *pQueue);
409}
410
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600411bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
412 const VkWriteDescriptorSet *pDescriptorWrites,
413 uint32_t descriptorCopyCount,
414 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600415 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600416 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkUpdateDescriptorSets-device-parameter",
417 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600418 if (pDescriptorCopies) {
419 for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
420 if (pDescriptorCopies[idx0].dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600421 skip |= ValidateObject(device, pDescriptorCopies[idx0].dstSet, kVulkanObjectTypeDescriptorSet, false,
422 "VUID-VkCopyDescriptorSet-dstSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600423 }
424 if (pDescriptorCopies[idx0].srcSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600425 skip |= ValidateObject(device, pDescriptorCopies[idx0].srcSet, kVulkanObjectTypeDescriptorSet, false,
426 "VUID-VkCopyDescriptorSet-srcSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600427 }
428 }
429 }
430 if (pDescriptorWrites) {
431 for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
432 skip |= ValidateDescriptorWrite(device, &pDescriptorWrites[idx1], false);
433 }
434 }
435 return skip;
436}
437
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600438bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
439 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600440 bool skip = false;
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600441
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600442 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter",
443 kVUIDUndefined);
444 skip |=
445 ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
446 "VUID-vkResetDescriptorPool-descriptorPool-parameter", "VUID-vkResetDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600447
448 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
449 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
450 ObjTrackState *pPoolNode = itr->second;
451 for (auto set : *pPoolNode->child_objects) {
452 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
453 kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600454 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600455 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600456 return skip;
457}
458
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600459void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
460 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600461 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
462 // our descriptorSet map.
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600463 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
464 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
465 ObjTrackState *pPoolNode = itr->second;
466 for (auto set : *pPoolNode->child_objects) {
467 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600468 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600469 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600470 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600471}
472
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600473bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
474 const VkCommandBufferBeginInfo *begin_info) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600475 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600476 skip |= ValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
477 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600478 if (begin_info) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600479 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600480 if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
481 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600482 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
483 "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
484 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
485 "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600486 }
487 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600488 return skip;
489}
490
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600491bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
492 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600493 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600494 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
495 "VUID-vkGetSwapchainImagesKHR-commonparent");
496 skip |= ValidateObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, false,
497 "VUID-vkGetSwapchainImagesKHR-swapchain-parameter", "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600498 return skip;
499}
500
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600501void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700502 VkImage *pSwapchainImages, VkResult result) {
503 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600504 if (pSwapchainImages != NULL) {
505 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
506 CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
507 }
508 }
509}
510
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600511bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
512 const VkAllocationCallbacks *pAllocator,
513 VkDescriptorSetLayout *pSetLayout) {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100514 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600515 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorSetLayout-device-parameter",
516 kVUIDUndefined);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600517 if (pCreateInfo) {
518 if (pCreateInfo->pBindings) {
519 for (uint32_t binding_index = 0; binding_index < pCreateInfo->bindingCount; ++binding_index) {
520 const VkDescriptorSetLayoutBinding &binding = pCreateInfo->pBindings[binding_index];
521 const bool is_sampler_type = binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
522 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
523 if (binding.pImmutableSamplers && is_sampler_type) {
524 for (uint32_t index2 = 0; index2 < binding.descriptorCount; ++index2) {
525 const VkSampler sampler = binding.pImmutableSamplers[index2];
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600526 skip |= ValidateObject(device, sampler, kVulkanObjectTypeSampler, false,
527 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100528 }
529 }
530 }
531 }
532 }
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600533 return skip;
534}
535
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600536void ObjectLifetimes::PostCallRecordCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
537 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700538 VkDescriptorSetLayout *pSetLayout, VkResult result) {
539 if (result != VK_SUCCESS) return;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600540 CreateObject(device, *pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600541}
542
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600543bool ObjectLifetimes::ValidateSamplerObjects(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo) {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600544 bool skip = false;
545 if (pCreateInfo->pBindings) {
546 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
547 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
548 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600549 skip |=
550 ValidateObject(device, pCreateInfo->pBindings[index1].pImmutableSamplers[index2], kVulkanObjectTypeSampler,
551 true, "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600552 }
553 }
554 }
555 }
556 return skip;
557}
558
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600559bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(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-vkGetDescriptorSetLayoutSupport-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600564 if (pCreateInfo) {
565 skip |= ValidateSamplerObjects(device, pCreateInfo);
566 }
567 return skip;
568}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600569bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
570 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
571 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600572 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
573 "VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600574 if (pCreateInfo) {
575 skip |= ValidateSamplerObjects(device, pCreateInfo);
576 }
577 return skip;
578}
579
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600580bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
581 uint32_t *pQueueFamilyPropertyCount,
582 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600583 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
584 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600585}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600586
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600587void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
588 uint32_t *pQueueFamilyPropertyCount,
589 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600590 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600591 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
592 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600593 }
594 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600595 queue_family_properties[i] = pQueueFamilyProperties[i];
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600596 }
597 }
598}
599
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600600void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700601 VkInstance *pInstance, VkResult result) {
602 if (result != VK_SUCCESS) return;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600603 CreateObject(*pInstance, *pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600604}
605
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600606bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
607 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600608 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600609 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter",
610 kVUIDUndefined);
611 skip |= ValidateObject(device, pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
612 "VUID-VkCommandBufferAllocateInfo-commandPool-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600613 return skip;
614}
615
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600616void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700617 VkCommandBuffer *pCommandBuffers, VkResult result) {
618 if (result != VK_SUCCESS) return;
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600619 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
620 AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
621 }
622}
623
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600624bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
625 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600626 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600627 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
628 kVUIDUndefined);
629 skip |= ValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
630 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
631 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600632 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600633 skip |= ValidateObject(device, pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
634 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
635 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600636 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600637 return skip;
638}
639
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600640void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700641 VkDescriptorSet *pDescriptorSets, VkResult result) {
642 if (result != VK_SUCCESS) return;
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600643 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
644 AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600645 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600646}
647
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600648bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
649 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600650 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600651 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter",
652 kVUIDUndefined);
653 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, false,
654 "VUID-vkFreeCommandBuffers-commandPool-parameter", "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600655 for (uint32_t i = 0; i < commandBufferCount; i++) {
656 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
657 skip |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600658 skip |= ValidateDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined,
659 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600660 }
661 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600662 return skip;
663}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600664
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600665void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
666 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600667 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600668 RecordDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600669 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600670}
671
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600672bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
673 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600674 return ValidateDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator,
675 "VUID-vkDestroySwapchainKHR-swapchain-01283", "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600676}
677
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600678void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
679 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600680 RecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
681 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = swapchainImageMap.begin();
682 while (itr != swapchainImageMap.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600683 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600684 if (pNode->parent_object == HandleToUint64(swapchain)) {
685 delete pNode;
686 auto delete_item = itr++;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600687 swapchainImageMap.erase(delete_item);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600688 } else {
689 ++itr;
690 }
691 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600692}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600693
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600694bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
695 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600696 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600697 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
698 kVUIDUndefined);
699 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
700 "VUID-vkFreeDescriptorSets-descriptorPool-parameter", "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600701 for (uint32_t i = 0; i < descriptorSetCount; i++) {
702 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
703 skip |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600704 skip |= ValidateDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
705 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600706 }
707 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600708 return skip;
709}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600710void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
711 const VkDescriptorSet *pDescriptorSets) {
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600712 ObjTrackState *pPoolNode = nullptr;
713 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
714 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
715 pPoolNode = itr->second;
716 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600717 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600718 RecordDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600719 if (pPoolNode) {
720 pPoolNode->child_objects->erase(HandleToUint64(pDescriptorSets[i]));
721 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600722 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600723}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600724
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600725bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
726 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600727 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600728 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
729 kVUIDUndefined);
730 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, true,
731 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
732 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600733
734 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
735 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
736 ObjTrackState *pPoolNode = itr->second;
737 for (auto set : *pPoolNode->child_objects) {
738 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
739 kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600740 }
741 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600742 skip |= ValidateDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
743 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
744 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600745 return skip;
746}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600747void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
748 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600749 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
750 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
751 ObjTrackState *pPoolNode = itr->second;
752 for (auto set : *pPoolNode->child_objects) {
753 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600754 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600755 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600756 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600757 RecordDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600758}
759
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600760bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
761 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600762 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600763 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter",
764 kVUIDUndefined);
765 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
766 "VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
767 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600768 auto del_itr = itr;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600769 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600770 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600771 del_itr = itr++;
772 if (pNode->parent_object == HandleToUint64(commandPool)) {
773 skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600774 skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
775 kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600776 }
777 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600778 skip |= ValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
779 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600780 return skip;
781}
782
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600783void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
784 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600785 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600786 auto del_itr = itr;
787 // 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 -0600788 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600789 ObjTrackState *pNode = (*itr).second;
790 del_itr = itr++;
791 if (pNode->parent_object == HandleToUint64(commandPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600792 RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600793 }
794 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600795 RecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600796}
797
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600798bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
799 uint32_t *pQueueFamilyPropertyCount,
800 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600801 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
802 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600803}
804
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600805bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
806 uint32_t *pQueueFamilyPropertyCount,
807 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600808 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Shannon McPherson3ea65132018-12-05 10:37:39 -0700809 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600810}
811
812void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
813 uint32_t *pQueueFamilyPropertyCount,
814 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600815 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600816 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
817 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600818 }
819 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600820 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600821 }
822 }
823}
824
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600825void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
826 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600827 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600828 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
829 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600830 }
831 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600832 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600833 }
834 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600835}
836
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600837bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
838 uint32_t *pPropertyCount,
839 VkDisplayPropertiesKHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600840 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
841 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600842}
843
844void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700845 VkDisplayPropertiesKHR *pProperties, VkResult result) {
846 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600847 if (pProperties) {
848 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600849 CreateObject(physicalDevice, pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600850 }
851 }
852}
853
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600854bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
855 uint32_t *pPropertyCount,
856 VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600857 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600858 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
859 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
860 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
861 "VUID-vkGetDisplayModePropertiesKHR-display-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600862
863 return skip;
864}
865
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600866void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700867 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties,
868 VkResult result) {
869 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600870 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600871 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600872 CreateObject(physicalDevice, pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600873 }
874 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600875}
876
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600877bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
878 uint32_t *pPropertyCount,
879 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600880 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
881 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600882}
883
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600884void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
885 uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700886 VkDisplayProperties2KHR *pProperties, VkResult result) {
887 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600888 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600889 CreateObject(physicalDevice, pProperties[index].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600890 }
891}
892
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600893bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
894 uint32_t *pPropertyCount,
895 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600896 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600897 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
898 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
899 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
900 "VUID-vkGetDisplayModeProperties2KHR-display-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600901
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600902 return skip;
903}
904
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600905void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700906 uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties,
907 VkResult result) {
908 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600909 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600910 CreateObject(physicalDevice, pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR,
911 nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600912 }
913}