blob: 9a98d2014907a1fdae1110a17774534aa686cb03 [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;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500230 auto lock = read_shared_lock();
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;
locke-lunarg9edc2812019-06-17 23:18:52 -0600272 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type], object_info->handle,
273 error_code, "OBJ ERROR : For %s, %s has not been destroyed.", report_data->FormatHandle(device).c_str(),
274 report_data->FormatHandle(ObjTrackStateTypedHandle(*object_info)).c_str());
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000275 }
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600276 return skip;
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000277}
278
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600279void ObjectLifetimes::DeviceDestroyUndestroyedObjects(VkDevice device, VulkanObjectType object_type) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600280 while (!object_map[object_type].empty()) {
281 auto item = object_map[object_type].begin();
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000282
283 ObjTrackState *object_info = item->second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600284 DestroyObjectSilently(object_info->handle, object_type);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600285 }
286}
287
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600288bool ObjectLifetimes::PreCallValidateDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600289 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500290 auto lock = read_shared_lock();
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) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500323 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600324 bool skip = ValidateObject(instance, instance, kVulkanObjectTypeInstance, false,
325 "VUID-vkEnumeratePhysicalDevices-instance-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600326 return skip;
327}
328
329void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700330 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
331 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500332 auto lock = write_shared_lock();
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600333 if (pPhysicalDevices) {
334 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600335 CreateObject(instance, pPhysicalDevices[i], kVulkanObjectTypePhysicalDevice, nullptr);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600336 }
337 }
338}
339
340void ObjectLifetimes::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500341 auto lock = write_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600342 // Destroy physical devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600343 for (auto iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
344 iit != object_map[kVulkanObjectTypePhysicalDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600345 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600346 VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(pNode->handle);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600347 RecordDestroyObject(instance, physical_device, kVulkanObjectTypePhysicalDevice);
348 iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600349 }
350
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700351 // Destroy child devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600352 for (auto iit = object_map[kVulkanObjectTypeDevice].begin(); iit != object_map[kVulkanObjectTypeDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600353 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600354 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000355 DestroyUndestroyedObjects(device);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700356
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600357 RecordDestroyObject(instance, device, kVulkanObjectTypeDevice);
358 iit = object_map[kVulkanObjectTypeDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600359 }
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700360
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600361 object_map[kVulkanObjectTypeDevice].clear();
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600362}
363
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600364void ObjectLifetimes::PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500365 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600366 RecordDestroyObject(instance, instance, kVulkanObjectTypeInstance);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600367}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600368
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600369bool ObjectLifetimes::PreCallValidateDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600370 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500371 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600372 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, true, "VUID-vkDestroyDevice-device-parameter", kVUIDUndefined);
373 skip |= ValidateDestroyObject(physical_device, device, kVulkanObjectTypeDevice, pAllocator, "VUID-vkDestroyDevice-device-00379",
374 "VUID-vkDestroyDevice-device-00380");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600375 // Report any remaining objects associated with this VkDevice object in LL
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600376 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyDevice-device-00378");
377
378 return skip;
379}
380
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600381void ObjectLifetimes::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500382 auto lock = write_shared_lock();
Mark Lobodzinski52db2352018-12-28 09:41:15 -0700383 auto instance_data = GetLayerDataPtr(get_dispatch_key(physical_device), layer_data_map);
384 ValidationObject *validation_data = GetValidationObject(instance_data->object_dispatch, LayerObjectTypeObjectTracker);
385 ObjectLifetimes *object_lifetimes = static_cast<ObjectLifetimes *>(validation_data);
386 object_lifetimes->RecordDestroyObject(physical_device, device, kVulkanObjectTypeDevice);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000387 DestroyUndestroyedObjects(device);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600388
389 // Clean up Queue's MemRef Linked Lists
390 DestroyQueueDataStructures(device);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600391}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600392
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600393bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
394 VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600395 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500396 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600397 skip |=
398 ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600399 return skip;
400}
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600401
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600402void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
403 VkQueue *pQueue) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500404 auto lock = write_shared_lock();
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600405 CreateQueue(device, *pQueue);
406 AddQueueInfo(device, queueFamilyIndex, *pQueue);
407}
408
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600409bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500410 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600411 return ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue2-device-parameter",
412 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600413}
414
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600415void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500416 auto lock = write_shared_lock();
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600417 CreateQueue(device, *pQueue);
418 AddQueueInfo(device, pQueueInfo->queueFamilyIndex, *pQueue);
419}
420
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600421bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
422 const VkWriteDescriptorSet *pDescriptorWrites,
423 uint32_t descriptorCopyCount,
424 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600425 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500426 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600427 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkUpdateDescriptorSets-device-parameter",
428 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600429 if (pDescriptorCopies) {
430 for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
431 if (pDescriptorCopies[idx0].dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600432 skip |= ValidateObject(device, pDescriptorCopies[idx0].dstSet, kVulkanObjectTypeDescriptorSet, false,
433 "VUID-VkCopyDescriptorSet-dstSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600434 }
435 if (pDescriptorCopies[idx0].srcSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600436 skip |= ValidateObject(device, pDescriptorCopies[idx0].srcSet, kVulkanObjectTypeDescriptorSet, false,
437 "VUID-VkCopyDescriptorSet-srcSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600438 }
439 }
440 }
441 if (pDescriptorWrites) {
442 for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
443 skip |= ValidateDescriptorWrite(device, &pDescriptorWrites[idx1], false);
444 }
445 }
446 return skip;
447}
448
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600449bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
450 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600451 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500452 auto lock = read_shared_lock();
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600453
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600454 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter",
455 kVUIDUndefined);
456 skip |=
457 ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
458 "VUID-vkResetDescriptorPool-descriptorPool-parameter", "VUID-vkResetDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600459
460 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
461 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
462 ObjTrackState *pPoolNode = itr->second;
463 for (auto set : *pPoolNode->child_objects) {
464 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
465 kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600466 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600467 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600468 return skip;
469}
470
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600471void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
472 VkDescriptorPoolResetFlags flags) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500473 auto lock = write_shared_lock();
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600474 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
475 // our descriptorSet map.
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600476 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
477 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
478 ObjTrackState *pPoolNode = itr->second;
479 for (auto set : *pPoolNode->child_objects) {
480 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600481 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600482 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600483 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600484}
485
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600486bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
487 const VkCommandBufferBeginInfo *begin_info) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600488 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500489 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600490 skip |= ValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
491 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600492 if (begin_info) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600493 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600494 if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
495 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600496 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
497 "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
498 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
499 "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600500 }
501 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600502 return skip;
503}
504
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600505bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
506 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600507 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500508 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600509 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
510 "VUID-vkGetSwapchainImagesKHR-commonparent");
511 skip |= ValidateObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, false,
512 "VUID-vkGetSwapchainImagesKHR-swapchain-parameter", "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600513 return skip;
514}
515
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600516void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700517 VkImage *pSwapchainImages, VkResult result) {
518 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500519 auto lock = write_shared_lock();
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600520 if (pSwapchainImages != NULL) {
521 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
522 CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
523 }
524 }
525}
526
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600527bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
528 const VkAllocationCallbacks *pAllocator,
529 VkDescriptorSetLayout *pSetLayout) {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100530 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500531 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600532 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorSetLayout-device-parameter",
533 kVUIDUndefined);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600534 if (pCreateInfo) {
535 if (pCreateInfo->pBindings) {
536 for (uint32_t binding_index = 0; binding_index < pCreateInfo->bindingCount; ++binding_index) {
537 const VkDescriptorSetLayoutBinding &binding = pCreateInfo->pBindings[binding_index];
538 const bool is_sampler_type = binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
539 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
540 if (binding.pImmutableSamplers && is_sampler_type) {
541 for (uint32_t index2 = 0; index2 < binding.descriptorCount; ++index2) {
542 const VkSampler sampler = binding.pImmutableSamplers[index2];
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600543 skip |= ValidateObject(device, sampler, kVulkanObjectTypeSampler, false,
544 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100545 }
546 }
547 }
548 }
549 }
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600550 return skip;
551}
552
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600553void ObjectLifetimes::PostCallRecordCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
554 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700555 VkDescriptorSetLayout *pSetLayout, VkResult result) {
556 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500557 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600558 CreateObject(device, *pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600559}
560
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600561bool ObjectLifetimes::ValidateSamplerObjects(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo) {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600562 bool skip = false;
563 if (pCreateInfo->pBindings) {
564 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
565 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
566 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600567 skip |=
568 ValidateObject(device, pCreateInfo->pBindings[index1].pImmutableSamplers[index2], kVulkanObjectTypeSampler,
569 true, "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600570 }
571 }
572 }
573 }
574 return skip;
575}
576
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600577bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(VkDevice device,
578 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
579 VkDescriptorSetLayoutSupport *pSupport) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500580 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600581 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
582 "VUID-vkGetDescriptorSetLayoutSupport-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600583 if (pCreateInfo) {
584 skip |= ValidateSamplerObjects(device, pCreateInfo);
585 }
586 return skip;
587}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600588bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
589 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
590 VkDescriptorSetLayoutSupport *pSupport) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500591 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600592 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
593 "VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600594 if (pCreateInfo) {
595 skip |= ValidateSamplerObjects(device, pCreateInfo);
596 }
597 return skip;
598}
599
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600600bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
601 uint32_t *pQueueFamilyPropertyCount,
602 VkQueueFamilyProperties *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500603 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600604 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
605 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600606}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600607
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600608void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
609 uint32_t *pQueueFamilyPropertyCount,
610 VkQueueFamilyProperties *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500611 auto lock = write_shared_lock();
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600612 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600613 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
614 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600615 }
616 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600617 queue_family_properties[i] = pQueueFamilyProperties[i];
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600618 }
619 }
620}
621
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600622void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700623 VkInstance *pInstance, VkResult result) {
624 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500625 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600626 CreateObject(*pInstance, *pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600627}
628
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600629bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
630 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600631 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500632 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600633 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter",
634 kVUIDUndefined);
635 skip |= ValidateObject(device, pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
636 "VUID-VkCommandBufferAllocateInfo-commandPool-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600637 return skip;
638}
639
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600640void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700641 VkCommandBuffer *pCommandBuffers, VkResult result) {
642 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500643 auto lock = write_shared_lock();
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600644 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
645 AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
646 }
647}
648
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600649bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
650 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600651 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500652 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600653 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
654 kVUIDUndefined);
655 skip |= ValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
656 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
657 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600658 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600659 skip |= ValidateObject(device, pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
660 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
661 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600662 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600663 return skip;
664}
665
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600666void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700667 VkDescriptorSet *pDescriptorSets, VkResult result) {
668 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500669 auto lock = write_shared_lock();
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600670 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
671 AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600672 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600673}
674
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600675bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
676 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600677 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500678 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600679 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter",
680 kVUIDUndefined);
681 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, false,
682 "VUID-vkFreeCommandBuffers-commandPool-parameter", "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600683 for (uint32_t i = 0; i < commandBufferCount; i++) {
684 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
685 skip |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600686 skip |= ValidateDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined,
687 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600688 }
689 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600690 return skip;
691}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600692
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600693void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
694 const VkCommandBuffer *pCommandBuffers) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500695 auto lock = write_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600696 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600697 RecordDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600698 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600699}
700
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600701bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
702 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500703 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600704 return ValidateDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator,
705 "VUID-vkDestroySwapchainKHR-swapchain-01283", "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600706}
707
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600708void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
709 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500710 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600711 RecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
712 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = swapchainImageMap.begin();
713 while (itr != swapchainImageMap.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600714 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600715 if (pNode->parent_object == HandleToUint64(swapchain)) {
716 delete pNode;
717 auto delete_item = itr++;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600718 swapchainImageMap.erase(delete_item);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600719 } else {
720 ++itr;
721 }
722 }
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::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
726 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500727 auto lock = read_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600728 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600729 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
730 kVUIDUndefined);
731 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
732 "VUID-vkFreeDescriptorSets-descriptorPool-parameter", "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600733 for (uint32_t i = 0; i < descriptorSetCount; i++) {
734 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
735 skip |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600736 skip |= ValidateDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
737 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600738 }
739 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600740 return skip;
741}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600742void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
743 const VkDescriptorSet *pDescriptorSets) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500744 auto lock = write_shared_lock();
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600745 ObjTrackState *pPoolNode = nullptr;
746 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
747 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
748 pPoolNode = itr->second;
749 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600750 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600751 RecordDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600752 if (pPoolNode) {
753 pPoolNode->child_objects->erase(HandleToUint64(pDescriptorSets[i]));
754 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600755 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600756}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600757
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600758bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
759 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500760 auto lock = read_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600761 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600762 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
763 kVUIDUndefined);
764 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, true,
765 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
766 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600767
768 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
769 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
770 ObjTrackState *pPoolNode = itr->second;
771 for (auto set : *pPoolNode->child_objects) {
772 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
773 kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600774 }
775 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600776 skip |= ValidateDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
777 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
778 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600779 return skip;
780}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600781void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
782 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500783 auto lock = write_shared_lock();
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600784 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
785 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
786 ObjTrackState *pPoolNode = itr->second;
787 for (auto set : *pPoolNode->child_objects) {
788 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600789 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600790 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600791 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600792 RecordDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600793}
794
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600795bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
796 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500797 auto lock = read_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600798 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600799 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter",
800 kVUIDUndefined);
801 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
802 "VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
803 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600804 auto del_itr = itr;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600805 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600806 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600807 del_itr = itr++;
808 if (pNode->parent_object == HandleToUint64(commandPool)) {
809 skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600810 skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
811 kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600812 }
813 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600814 skip |= ValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
815 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600816 return skip;
817}
818
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600819void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
820 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500821 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600822 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600823 auto del_itr = itr;
824 // 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 -0600825 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600826 ObjTrackState *pNode = (*itr).second;
827 del_itr = itr++;
828 if (pNode->parent_object == HandleToUint64(commandPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600829 RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600830 }
831 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600832 RecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600833}
834
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600835bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
836 uint32_t *pQueueFamilyPropertyCount,
837 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500838 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600839 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
840 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600841}
842
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600843bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
844 uint32_t *pQueueFamilyPropertyCount,
845 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500846 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600847 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Shannon McPherson3ea65132018-12-05 10:37:39 -0700848 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600849}
850
851void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
852 uint32_t *pQueueFamilyPropertyCount,
853 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500854 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600855 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600856 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
857 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600858 }
859 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600860 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600861 }
862 }
863}
864
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600865void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
866 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500867 auto lock = write_shared_lock();
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600868 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600869 if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
870 queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600871 }
872 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600873 queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600874 }
875 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600876}
877
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600878bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
879 uint32_t *pPropertyCount,
880 VkDisplayPropertiesKHR *pProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500881 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600882 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
883 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600884}
885
886void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700887 VkDisplayPropertiesKHR *pProperties, VkResult result) {
888 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500889 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600890 if (pProperties) {
891 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600892 CreateObject(physicalDevice, pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600893 }
894 }
895}
896
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600897bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
898 uint32_t *pPropertyCount,
899 VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600900 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500901 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600902 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
903 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
904 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
905 "VUID-vkGetDisplayModePropertiesKHR-display-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600906
907 return skip;
908}
909
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600910void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700911 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties,
912 VkResult result) {
913 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500914 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600915 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600916 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600917 CreateObject(physicalDevice, pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600918 }
919 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600920}
921
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600922bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
923 uint32_t *pPropertyCount,
924 VkDisplayProperties2KHR *pProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500925 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600926 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
927 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600928}
929
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600930void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
931 uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700932 VkDisplayProperties2KHR *pProperties, VkResult result) {
933 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500934 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600935 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600936 CreateObject(physicalDevice, pProperties[index].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600937 }
938}
939
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600940bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
941 uint32_t *pPropertyCount,
942 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600943 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500944 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600945 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
946 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
947 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
948 "VUID-vkGetDisplayModeProperties2KHR-display-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600949
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600950 return skip;
951}
952
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600953void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700954 uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties,
955 VkResult result) {
956 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500957 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600958 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600959 CreateObject(physicalDevice, pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR,
960 nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600961 }
962}
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600963
964bool ObjectLifetimes::PreCallValidateAcquirePerformanceConfigurationINTEL(
965 VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL *pAcquireInfo,
966 VkPerformanceConfigurationINTEL *pConfiguration) {
967 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500968 auto lock = read_shared_lock();
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600969 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false,
970 "VUID-vkAcquirePerformanceConfigurationINTEL-device-parameter", kVUIDUndefined);
971
972 return skip;
973}
974
975bool ObjectLifetimes::PreCallValidateReleasePerformanceConfigurationINTEL(VkDevice device,
976 VkPerformanceConfigurationINTEL configuration) {
977 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500978 auto lock = read_shared_lock();
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600979 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false,
980 "VUID-vkReleasePerformanceConfigurationINTEL-device-parameter", kVUIDUndefined);
981
982 return skip;
983}
984
985bool ObjectLifetimes::PreCallValidateQueueSetPerformanceConfigurationINTEL(VkQueue queue,
986 VkPerformanceConfigurationINTEL configuration) {
987 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500988 auto lock = read_shared_lock();
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600989 skip |=
990 ValidateObject(queue, queue, kVulkanObjectTypeQueue, false, "VUID-vkQueueSetPerformanceConfigurationINTEL-queue-parameter",
991 "VUID-vkQueueSetPerformanceConfigurationINTEL-commonparent");
992
993 return skip;
994}
Tobias Hectorc9057422019-07-23 12:15:52 +0100995
996bool ObjectLifetimes::PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
997 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) {
998 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500999 auto lock = read_shared_lock();
Tobias Hectorc9057422019-07-23 12:15:52 +01001000 skip |=
1001 ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateFramebuffer-device-parameter", kVUIDUndefined);
1002 if (pCreateInfo) {
1003 skip |= ValidateObject(device, pCreateInfo->renderPass, kVulkanObjectTypeRenderPass, false,
1004 "VUID-VkFramebufferCreateInfo-renderPass-parameter", "VUID-VkFramebufferCreateInfo-commonparent");
1005 if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR) == 0) {
1006 for (uint32_t index1 = 0; index1 < pCreateInfo->attachmentCount; ++index1) {
1007 skip |= ValidateObject(device, pCreateInfo->pAttachments[index1], kVulkanObjectTypeImageView, true, kVUIDUndefined,
1008 "VUID-VkFramebufferCreateInfo-commonparent");
1009 }
1010 }
1011 }
1012
1013 return skip;
1014}
1015
1016void ObjectLifetimes::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
1017 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
1018 VkResult result) {
1019 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -05001020 auto lock = write_shared_lock();
Tobias Hectorc9057422019-07-23 12:15:52 +01001021 CreateObject(device, *pFramebuffer, kVulkanObjectTypeFramebuffer, pAllocator);
1022}