blob: 964f6e6f122a2b63f503e577a44a5e62d1bc1f2d [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,
locke-lunarg9edc2812019-06-17 23:18:52 -0600101 invalid_handle_code, "Invalid %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);
locke-lunarg9edc2812019-06-17 23:18:52 -0600129 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
130 object_handle, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent",
131 "FreeCommandBuffers is attempting to free %s belonging to %s from %s).",
132 report_data->FormatHandle(command_buffer).c_str(), report_data->FormatHandle(parent_pool).c_str(),
133 report_data->FormatHandle(command_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600134 }
135 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600136 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, object_handle,
locke-lunarg9edc2812019-06-17 23:18:52 -0600137 "VUID-vkFreeCommandBuffers-pCommandBuffers-00048", "Invalid %s.",
138 report_data->FormatHandle(command_buffer).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600139 }
140 return skip;
141}
142
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600143void ObjectLifetimes::AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600144 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600145 pNewObjNode->object_type = kVulkanObjectTypeDescriptorSet;
146 pNewObjNode->status = OBJSTATUS_NONE;
147 pNewObjNode->handle = HandleToUint64(descriptor_set);
148 pNewObjNode->parent_object = HandleToUint64(descriptor_pool);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600149 object_map[kVulkanObjectTypeDescriptorSet][HandleToUint64(descriptor_set)] = pNewObjNode;
150 num_objects[kVulkanObjectTypeDescriptorSet]++;
151 num_total_objects++;
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600152
153 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptor_pool));
154 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
155 ObjTrackState *pPoolNode = itr->second;
156 pPoolNode->child_objects->insert(HandleToUint64(descriptor_set));
157 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600158}
159
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600160bool ObjectLifetimes::ValidateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600161 bool skip = false;
162 uint64_t object_handle = HandleToUint64(descriptor_set);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600163 auto dsItem = object_map[kVulkanObjectTypeDescriptorSet].find(object_handle);
164 if (dsItem != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600165 ObjTrackState *pNode = dsItem->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600166
167 if (pNode->parent_object != HandleToUint64(descriptor_pool)) {
John Zulauf1c3844a2019-04-01 17:39:48 -0600168 // We know that the parent *must* be a descriptor pool
169 const auto parent_pool = CastFromUint64<VkDescriptorPool>(pNode->parent_object);
170 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
171 object_handle, "VUID-vkFreeDescriptorSets-pDescriptorSets-parent",
locke-lunarg9edc2812019-06-17 23:18:52 -0600172 "FreeDescriptorSets is attempting to free %s"
173 " belonging to %s from %s).",
John Zulauf1c3844a2019-04-01 17:39:48 -0600174 report_data->FormatHandle(descriptor_set).c_str(), report_data->FormatHandle(parent_pool).c_str(),
175 report_data->FormatHandle(descriptor_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600176 }
177 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600178 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, object_handle,
locke-lunarg9edc2812019-06-17 23:18:52 -0600179 "VUID-vkFreeDescriptorSets-pDescriptorSets-00310", "Invalid %s.",
180 report_data->FormatHandle(descriptor_set).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600181 }
182 return skip;
183}
184
Dave Houltona9df0ce2018-02-07 10:51:23 -0700185template <typename DispObj>
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600186bool ObjectLifetimes::ValidateDescriptorWrite(DispObj disp, VkWriteDescriptorSet const *desc, bool isPush) {
Chris Forbes2c600e92017-10-20 11:13:20 -0700187 bool skip = false;
188
189 if (!isPush && desc->dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600190 skip |= ValidateObject(disp, desc->dstSet, kVulkanObjectTypeDescriptorSet, false, "VUID-VkWriteDescriptorSet-dstSet-00320",
191 "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700192 }
193
194 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
195 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
196 for (uint32_t idx2 = 0; idx2 < desc->descriptorCount; ++idx2) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600197 skip |= ValidateObject(disp, desc->pTexelBufferView[idx2], kVulkanObjectTypeBufferView, false,
198 "VUID-VkWriteDescriptorSet-descriptorType-00323", "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700199 }
200 }
201
202 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
Dave Houltona9df0ce2018-02-07 10:51:23 -0700203 (desc->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
Chris Forbes2c600e92017-10-20 11:13:20 -0700204 (desc->descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
205 for (uint32_t idx3 = 0; idx3 < desc->descriptorCount; ++idx3) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600206 skip |= ValidateObject(disp, desc->pImageInfo[idx3].imageView, kVulkanObjectTypeImageView, false,
207 "VUID-VkWriteDescriptorSet-descriptorType-00326", "VUID-VkDescriptorImageInfo-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700208 }
209 }
210
211 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
212 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
213 (desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
214 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
215 for (uint32_t idx4 = 0; idx4 < desc->descriptorCount; ++idx4) {
216 if (desc->pBufferInfo[idx4].buffer) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600217 skip |= ValidateObject(disp, desc->pBufferInfo[idx4].buffer, kVulkanObjectTypeBuffer, false,
218 "VUID-VkDescriptorBufferInfo-buffer-parameter", kVUIDUndefined);
Chris Forbes2c600e92017-10-20 11:13:20 -0700219 }
220 }
221 }
222
223 return skip;
224}
225
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600226bool ObjectLifetimes::PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
227 VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
228 const VkWriteDescriptorSet *pDescriptorWrites) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600229 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600230 skip |= ValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false,
231 "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
232 skip |= ValidateObject(commandBuffer, layout, kVulkanObjectTypePipelineLayout, false,
233 "VUID-vkCmdPushDescriptorSetKHR-layout-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600234 if (pDescriptorWrites) {
235 for (uint32_t index0 = 0; index0 < descriptorWriteCount; ++index0) {
236 skip |= ValidateDescriptorWrite(commandBuffer, &pDescriptorWrites[index0], true);
237 }
238 }
239 return skip;
240}
241
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600242void ObjectLifetimes::CreateQueue(VkDevice device, VkQueue vkObj) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600243 ObjTrackState *p_obj_node = NULL;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600244 auto queue_item = object_map[kVulkanObjectTypeQueue].find(HandleToUint64(vkObj));
245 if (queue_item == object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600246 p_obj_node = new ObjTrackState;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600247 object_map[kVulkanObjectTypeQueue][HandleToUint64(vkObj)] = p_obj_node;
248 num_objects[kVulkanObjectTypeQueue]++;
249 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600250 } else {
251 p_obj_node = queue_item->second;
252 }
253 p_obj_node->object_type = kVulkanObjectTypeQueue;
254 p_obj_node->status = OBJSTATUS_NONE;
255 p_obj_node->handle = HandleToUint64(vkObj);
256}
257
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600258void ObjectLifetimes::CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600259 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600260 pNewObjNode->object_type = kVulkanObjectTypeImage;
261 pNewObjNode->status = OBJSTATUS_NONE;
262 pNewObjNode->handle = HandleToUint64(swapchain_image);
263 pNewObjNode->parent_object = HandleToUint64(swapchain);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600264 swapchainImageMap[HandleToUint64(swapchain_image)] = pNewObjNode;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600265}
266
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600267bool ObjectLifetimes::DeviceReportUndestroyedObjects(VkDevice device, VulkanObjectType object_type, const std::string &error_code) {
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600268 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600269 for (const auto &item : object_map[object_type]) {
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000270 const ObjTrackState *object_info = item.second;
locke-lunarg9edc2812019-06-17 23:18:52 -0600271 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type], object_info->handle,
272 error_code, "OBJ ERROR : For %s, %s has not been destroyed.", report_data->FormatHandle(device).c_str(),
273 report_data->FormatHandle(ObjTrackStateTypedHandle(*object_info)).c_str());
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000274 }
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600275 return skip;
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000276}
277
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600278void ObjectLifetimes::DeviceDestroyUndestroyedObjects(VkDevice device, VulkanObjectType object_type) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600279 while (!object_map[object_type].empty()) {
280 auto item = object_map[object_type].begin();
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000281
282 ObjTrackState *object_info = item->second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600283 DestroyObjectSilently(object_info->handle, object_type);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600284 }
285}
286
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600287bool ObjectLifetimes::PreCallValidateDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600288 bool skip = false;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600289
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600290 // 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 -0600291 skip |= ValidateObject(instance, instance, kVulkanObjectTypeInstance, true, "VUID-vkDestroyInstance-instance-parameter",
292 kVUIDUndefined);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600293
294 // Validate that child devices have been destroyed
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600295 for (const auto &iit : object_map[kVulkanObjectTypeDevice]) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600296 ObjTrackState *pNode = iit.second;
297
298 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
299 VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[pNode->object_type];
300
John Zulauf1c3844a2019-04-01 17:39:48 -0600301 skip |=
302 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, pNode->handle, kVUID_ObjectTracker_ObjectLeak,
303 "OBJ ERROR : %s object %s has not been destroyed.", string_VkDebugReportObjectTypeEXT(debug_object_type),
304 report_data->FormatHandle(ObjTrackStateTypedHandle(*pNode)).c_str());
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600305
306 // Report any remaining objects in LL
307 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyInstance-instance-00629");
308
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600309 skip |= ValidateDestroyObject(instance, device, kVulkanObjectTypeDevice, pAllocator,
310 "VUID-vkDestroyInstance-instance-00630", "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600311 }
312
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600313 ValidateDestroyObject(instance, instance, kVulkanObjectTypeInstance, pAllocator, "VUID-vkDestroyInstance-instance-00630",
314 "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600315
316 return skip;
317}
318
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600319bool ObjectLifetimes::PreCallValidateEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
320 VkPhysicalDevice *pPhysicalDevices) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600321 bool skip = ValidateObject(instance, instance, kVulkanObjectTypeInstance, false,
322 "VUID-vkEnumeratePhysicalDevices-instance-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600323 return skip;
324}
325
326void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700327 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
328 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600329 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");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600445
446 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
447 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
448 ObjTrackState *pPoolNode = itr->second;
449 for (auto set : *pPoolNode->child_objects) {
450 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
451 kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600452 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600453 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600454 return skip;
455}
456
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600457void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
458 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600459 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
460 // our descriptorSet map.
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600461 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
462 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
463 ObjTrackState *pPoolNode = itr->second;
464 for (auto set : *pPoolNode->child_objects) {
465 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600466 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600467 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600468 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600469}
470
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600471bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
472 const VkCommandBufferBeginInfo *begin_info) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600473 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600474 skip |= ValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
475 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600476 if (begin_info) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600477 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600478 if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
479 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600480 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
481 "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
482 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
483 "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600484 }
485 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600486 return skip;
487}
488
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600489bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
490 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600491 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600492 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
493 "VUID-vkGetSwapchainImagesKHR-commonparent");
494 skip |= ValidateObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, false,
495 "VUID-vkGetSwapchainImagesKHR-swapchain-parameter", "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600496 return skip;
497}
498
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600499void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700500 VkImage *pSwapchainImages, VkResult result) {
501 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600502 if (pSwapchainImages != NULL) {
503 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
504 CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
505 }
506 }
507}
508
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600509bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
510 const VkAllocationCallbacks *pAllocator,
511 VkDescriptorSetLayout *pSetLayout) {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100512 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600513 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorSetLayout-device-parameter",
514 kVUIDUndefined);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600515 if (pCreateInfo) {
516 if (pCreateInfo->pBindings) {
517 for (uint32_t binding_index = 0; binding_index < pCreateInfo->bindingCount; ++binding_index) {
518 const VkDescriptorSetLayoutBinding &binding = pCreateInfo->pBindings[binding_index];
519 const bool is_sampler_type = binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
520 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
521 if (binding.pImmutableSamplers && is_sampler_type) {
522 for (uint32_t index2 = 0; index2 < binding.descriptorCount; ++index2) {
523 const VkSampler sampler = binding.pImmutableSamplers[index2];
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600524 skip |= ValidateObject(device, sampler, kVulkanObjectTypeSampler, false,
525 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100526 }
527 }
528 }
529 }
530 }
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600531 return skip;
532}
533
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600534void ObjectLifetimes::PostCallRecordCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
535 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700536 VkDescriptorSetLayout *pSetLayout, VkResult result) {
537 if (result != VK_SUCCESS) return;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600538 CreateObject(device, *pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600539}
540
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600541bool ObjectLifetimes::ValidateSamplerObjects(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo) {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600542 bool skip = false;
543 if (pCreateInfo->pBindings) {
544 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
545 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
546 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600547 skip |=
548 ValidateObject(device, pCreateInfo->pBindings[index1].pImmutableSamplers[index2], kVulkanObjectTypeSampler,
549 true, "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600550 }
551 }
552 }
553 }
554 return skip;
555}
556
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600557bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(VkDevice device,
558 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
559 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600560 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
561 "VUID-vkGetDescriptorSetLayoutSupport-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600562 if (pCreateInfo) {
563 skip |= ValidateSamplerObjects(device, pCreateInfo);
564 }
565 return skip;
566}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600567bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
568 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
569 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600570 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
571 "VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600572 if (pCreateInfo) {
573 skip |= ValidateSamplerObjects(device, pCreateInfo);
574 }
575 return skip;
576}
577
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600578bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
579 uint32_t *pQueueFamilyPropertyCount,
580 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600581 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
582 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600583}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600584
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600585void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
586 uint32_t *pQueueFamilyPropertyCount,
587 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600588 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600589 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
590 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600591 }
592 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600593 queue_family_properties[i] = pQueueFamilyProperties[i];
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600594 }
595 }
596}
597
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600598void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700599 VkInstance *pInstance, VkResult result) {
600 if (result != VK_SUCCESS) return;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600601 CreateObject(*pInstance, *pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600602}
603
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600604bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
605 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600606 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600607 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter",
608 kVUIDUndefined);
609 skip |= ValidateObject(device, pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
610 "VUID-VkCommandBufferAllocateInfo-commandPool-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600611 return skip;
612}
613
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600614void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700615 VkCommandBuffer *pCommandBuffers, VkResult result) {
616 if (result != VK_SUCCESS) return;
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600617 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
618 AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
619 }
620}
621
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600622bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
623 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600624 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600625 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
626 kVUIDUndefined);
627 skip |= ValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
628 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
629 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600630 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600631 skip |= ValidateObject(device, pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
632 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
633 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600634 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600635 return skip;
636}
637
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600638void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700639 VkDescriptorSet *pDescriptorSets, VkResult result) {
640 if (result != VK_SUCCESS) return;
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600641 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
642 AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600643 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600644}
645
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600646bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
647 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600648 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600649 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter",
650 kVUIDUndefined);
651 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, false,
652 "VUID-vkFreeCommandBuffers-commandPool-parameter", "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600653 for (uint32_t i = 0; i < commandBufferCount; i++) {
654 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
655 skip |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600656 skip |= ValidateDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined,
657 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600658 }
659 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600660 return skip;
661}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600662
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600663void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
664 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600665 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600666 RecordDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600667 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600668}
669
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600670bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
671 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600672 return ValidateDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator,
673 "VUID-vkDestroySwapchainKHR-swapchain-01283", "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600674}
675
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600676void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
677 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600678 RecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
679 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = swapchainImageMap.begin();
680 while (itr != swapchainImageMap.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600681 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600682 if (pNode->parent_object == HandleToUint64(swapchain)) {
683 delete pNode;
684 auto delete_item = itr++;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600685 swapchainImageMap.erase(delete_item);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600686 } else {
687 ++itr;
688 }
689 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600690}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600691
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600692bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
693 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600694 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600695 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
696 kVUIDUndefined);
697 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
698 "VUID-vkFreeDescriptorSets-descriptorPool-parameter", "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600699 for (uint32_t i = 0; i < descriptorSetCount; i++) {
700 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
701 skip |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600702 skip |= ValidateDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
703 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600704 }
705 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600706 return skip;
707}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600708void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
709 const VkDescriptorSet *pDescriptorSets) {
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600710 ObjTrackState *pPoolNode = nullptr;
711 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
712 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
713 pPoolNode = itr->second;
714 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600715 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600716 RecordDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600717 if (pPoolNode) {
718 pPoolNode->child_objects->erase(HandleToUint64(pDescriptorSets[i]));
719 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600720 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600721}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600722
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600723bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
724 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600725 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600726 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
727 kVUIDUndefined);
728 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, true,
729 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
730 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600731
732 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
733 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
734 ObjTrackState *pPoolNode = itr->second;
735 for (auto set : *pPoolNode->child_objects) {
736 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
737 kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600738 }
739 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600740 skip |= ValidateDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
741 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
742 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600743 return skip;
744}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600745void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
746 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600747 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
748 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
749 ObjTrackState *pPoolNode = itr->second;
750 for (auto set : *pPoolNode->child_objects) {
751 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600752 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600753 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600754 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600755 RecordDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600756}
757
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600758bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
759 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600760 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600761 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter",
762 kVUIDUndefined);
763 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
764 "VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
765 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600766 auto del_itr = itr;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600767 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600768 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600769 del_itr = itr++;
770 if (pNode->parent_object == HandleToUint64(commandPool)) {
771 skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600772 skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
773 kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600774 }
775 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600776 skip |= ValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
777 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600778 return skip;
779}
780
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600781void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
782 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600783 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600784 auto del_itr = itr;
785 // 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 -0600786 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600787 ObjTrackState *pNode = (*itr).second;
788 del_itr = itr++;
789 if (pNode->parent_object == HandleToUint64(commandPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600790 RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600791 }
792 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600793 RecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600794}
795
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600796bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
797 uint32_t *pQueueFamilyPropertyCount,
798 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600799 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
800 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600801}
802
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600803bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
804 uint32_t *pQueueFamilyPropertyCount,
805 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600806 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Shannon McPherson3ea65132018-12-05 10:37:39 -0700807 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600808}
809
810void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
811 uint32_t *pQueueFamilyPropertyCount,
812 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600813 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600814 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
815 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600816 }
817 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600818 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600819 }
820 }
821}
822
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600823void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
824 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600825 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600826 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
827 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600828 }
829 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600830 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600831 }
832 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600833}
834
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600835bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
836 uint32_t *pPropertyCount,
837 VkDisplayPropertiesKHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600838 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
839 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600840}
841
842void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700843 VkDisplayPropertiesKHR *pProperties, VkResult result) {
844 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600845 if (pProperties) {
846 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600847 CreateObject(physicalDevice, pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600848 }
849 }
850}
851
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600852bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
853 uint32_t *pPropertyCount,
854 VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600855 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600856 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
857 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
858 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
859 "VUID-vkGetDisplayModePropertiesKHR-display-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600860
861 return skip;
862}
863
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600864void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700865 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties,
866 VkResult result) {
867 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600868 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600869 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600870 CreateObject(physicalDevice, pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600871 }
872 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600873}
874
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600875bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
876 uint32_t *pPropertyCount,
877 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600878 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
879 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600880}
881
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600882void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
883 uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700884 VkDisplayProperties2KHR *pProperties, VkResult result) {
885 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
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].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600888 }
889}
890
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600891bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
892 uint32_t *pPropertyCount,
893 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600894 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600895 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
896 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
897 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
898 "VUID-vkGetDisplayModeProperties2KHR-display-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600899
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600900 return skip;
901}
902
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600903void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700904 uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties,
905 VkResult result) {
906 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600907 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600908 CreateObject(physicalDevice, pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR,
909 nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600910 }
911}
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600912
913bool ObjectLifetimes::PreCallValidateAcquirePerformanceConfigurationINTEL(
914 VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL *pAcquireInfo,
915 VkPerformanceConfigurationINTEL *pConfiguration) {
916 bool skip = false;
917 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false,
918 "VUID-vkAcquirePerformanceConfigurationINTEL-device-parameter", kVUIDUndefined);
919
920 return skip;
921}
922
923bool ObjectLifetimes::PreCallValidateReleasePerformanceConfigurationINTEL(VkDevice device,
924 VkPerformanceConfigurationINTEL configuration) {
925 bool skip = false;
926 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false,
927 "VUID-vkReleasePerformanceConfigurationINTEL-device-parameter", kVUIDUndefined);
928
929 return skip;
930}
931
932bool ObjectLifetimes::PreCallValidateQueueSetPerformanceConfigurationINTEL(VkQueue queue,
933 VkPerformanceConfigurationINTEL configuration) {
934 bool skip = false;
935 skip |=
936 ValidateObject(queue, queue, kVulkanObjectTypeQueue, false, "VUID-vkQueueSetPerformanceConfigurationINTEL-queue-parameter",
937 "VUID-vkQueueSetPerformanceConfigurationINTEL-commonparent");
938
939 return skip;
940}