blob: 8cc4cde84f74db79cca00c19f03b6938f9da6922 [file] [log] [blame]
aitor-lunarg3c145292022-03-25 17:30:11 +01001/* Copyright (c) 2015-2022 The Khronos Group Inc.
2 * Copyright (c) 2015-2022 Valve Corporation
3 * Copyright (c) 2015-2022 LunarG, Inc.
4 * Copyright (C) 2015-2022 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"
aitor-lunarg3c145292022-03-25 17:30:11 +010026#include "layer_chassis_dispatch.h"
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060027
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060028uint64_t object_track_index = 0;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060029
John Zulauf1c3844a2019-04-01 17:39:48 -060030VulkanTypedHandle ObjTrackStateTypedHandle(const ObjTrackState &track_state) {
31 // TODO: Unify Typed Handle representation (i.e. VulkanTypedHandle everywhere there are handle/type pairs)
32 VulkanTypedHandle typed_handle;
33 typed_handle.handle = track_state.handle;
34 typed_handle.type = track_state.object_type;
35 return typed_handle;
36}
37
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060038// Destroy memRef lists and free all memory
Mark Lobodzinski702c6a42019-09-11 11:52:23 -060039void ObjectLifetimes::DestroyQueueDataStructures() {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060040 // Destroy the items in the queue map
Jeff Bolzfd3bb242019-08-22 06:10:49 -050041 auto snapshot = object_map[kVulkanObjectTypeQueue].snapshot();
42 for (const auto &queue : snapshot) {
43 uint32_t obj_index = queue.second->object_type;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060044 assert(num_total_objects > 0);
45 num_total_objects--;
46 assert(num_objects[obj_index] > 0);
47 num_objects[obj_index]--;
Jeff Bolzfd3bb242019-08-22 06:10:49 -050048 object_map[kVulkanObjectTypeQueue].erase(queue.first);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060049 }
50}
51
Mark Lobodzinskic763f582019-09-11 11:35:43 -060052void ObjectLifetimes::DestroyUndestroyedObjects(VulkanObjectType object_type) {
53 auto snapshot = object_map[object_type].snapshot();
54 for (const auto &item : snapshot) {
55 auto object_info = item.second;
56 DestroyObjectSilently(object_info->handle, object_type);
57 }
58}
59
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070060// Look for this device object in any of the instance child devices lists.
61// NOTE: This is of dubious value. In most circumstances Vulkan will die a flaming death if a dispatchable object is invalid.
62// 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 -060063bool ObjectLifetimes::ValidateDeviceObject(const VulkanTypedHandle &device_typed, const char *invalid_handle_code,
Jeff Bolz46c0ea02019-10-09 13:06:29 -050064 const char *wrong_device_code) const {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060065 auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
66 auto instance_object_lifetime_data = GetObjectLifetimeData(instance_data->object_dispatch);
Jeff Bolzfd3bb242019-08-22 06:10:49 -050067 if (instance_object_lifetime_data->object_map[kVulkanObjectTypeDevice].contains(device_typed.handle)) {
68 return false;
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070069 }
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -070070 return LogError(instance, invalid_handle_code, "Invalid %s.", report_data->FormatHandle(device_typed).c_str());
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070071}
72
Ben Clayton65576d62021-04-16 10:46:07 +010073bool ObjectLifetimes::ValidateAnonymousObject(uint64_t object, VkObjectType core_object_type, bool null_allowed,
Jeff Bolz46c0ea02019-10-09 13:06:29 -050074 const char *invalid_handle_code, const char *wrong_device_code) const {
Ben Clayton65576d62021-04-16 10:46:07 +010075 if (null_allowed && (object == HandleToUint64(VK_NULL_HANDLE))) return false;
Mark Lobodzinski8af6bb42019-09-11 14:37:29 -060076 auto object_type = ConvertCoreObjectToVulkanObject(core_object_type);
77
78 if (object_type == kVulkanObjectTypeDevice) {
Ben Clayton65576d62021-04-16 10:46:07 +010079 return ValidateDeviceObject(VulkanTypedHandle(reinterpret_cast<VkDevice>(object), object_type), invalid_handle_code,
Mark Lobodzinski8af6bb42019-09-11 14:37:29 -060080 wrong_device_code);
81 }
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -070082
Ben Clayton65576d62021-04-16 10:46:07 +010083 return CheckObjectValidity(object, object_type, null_allowed, invalid_handle_code, wrong_device_code);
Mark Lobodzinski8af6bb42019-09-11 14:37:29 -060084}
85
Mark Lobodzinski702c6a42019-09-11 11:52:23 -060086void ObjectLifetimes::AllocateCommandBuffer(const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
Mark Lobodzinski0c668462018-09-27 10:13:19 -060087 VkCommandBufferLevel level) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -070088 auto new_obj_node = std::make_shared<ObjTrackState>();
89 new_obj_node->object_type = kVulkanObjectTypeCommandBuffer;
90 new_obj_node->handle = HandleToUint64(command_buffer);
91 new_obj_node->parent_object = HandleToUint64(command_pool);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060092 if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -070093 new_obj_node->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060094 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -070095 new_obj_node->status = OBJSTATUS_NONE;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060096 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -070097 InsertObject(object_map[kVulkanObjectTypeCommandBuffer], command_buffer, kVulkanObjectTypeCommandBuffer, new_obj_node);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060098 num_objects[kVulkanObjectTypeCommandBuffer]++;
99 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600100}
101
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500102bool ObjectLifetimes::ValidateCommandBuffer(VkCommandPool command_pool, VkCommandBuffer command_buffer) const {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600103 bool skip = false;
104 uint64_t object_handle = HandleToUint64(command_buffer);
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500105 auto iter = object_map[kVulkanObjectTypeCommandBuffer].find(object_handle);
106 if (iter != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700107 auto node = iter->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600108
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700109 if (node->parent_object != HandleToUint64(command_pool)) {
John Zulauf1c3844a2019-04-01 17:39:48 -0600110 // We know that the parent *must* be a command pool
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700111 const auto parent_pool = CastFromUint64<VkCommandPool>(node->parent_object);
Mark Lobodzinskib03bdac2020-03-16 18:32:44 -0600112 LogObjectList objlist(command_buffer);
113 objlist.add(parent_pool);
114 objlist.add(command_pool);
115 skip |= LogError(objlist, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent",
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700116 "FreeCommandBuffers is attempting to free %s belonging to %s from %s).",
117 report_data->FormatHandle(command_buffer).c_str(), report_data->FormatHandle(parent_pool).c_str(),
118 report_data->FormatHandle(command_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600119 }
120 } else {
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700121 skip |= LogError(command_buffer, "VUID-vkFreeCommandBuffers-pCommandBuffers-00048", "Invalid %s.",
122 report_data->FormatHandle(command_buffer).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600123 }
124 return skip;
125}
126
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600127void ObjectLifetimes::AllocateDescriptorSet(VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700128 auto new_obj_node = std::make_shared<ObjTrackState>();
129 new_obj_node->object_type = kVulkanObjectTypeDescriptorSet;
130 new_obj_node->status = OBJSTATUS_NONE;
131 new_obj_node->handle = HandleToUint64(descriptor_set);
132 new_obj_node->parent_object = HandleToUint64(descriptor_pool);
133 InsertObject(object_map[kVulkanObjectTypeDescriptorSet], descriptor_set, kVulkanObjectTypeDescriptorSet, new_obj_node);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600134 num_objects[kVulkanObjectTypeDescriptorSet]++;
135 num_total_objects++;
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600136
137 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptor_pool));
138 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500139 itr->second->child_objects->insert(HandleToUint64(descriptor_set));
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600140 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600141}
142
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500143bool ObjectLifetimes::ValidateDescriptorSet(VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) const {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600144 bool skip = false;
145 uint64_t object_handle = HandleToUint64(descriptor_set);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700146 auto ds_item = object_map[kVulkanObjectTypeDescriptorSet].find(object_handle);
147 if (ds_item != object_map[kVulkanObjectTypeDescriptorSet].end()) {
148 if (ds_item->second->parent_object != HandleToUint64(descriptor_pool)) {
John Zulauf1c3844a2019-04-01 17:39:48 -0600149 // We know that the parent *must* be a descriptor pool
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700150 const auto parent_pool = CastFromUint64<VkDescriptorPool>(ds_item->second->parent_object);
Mark Lobodzinskib03bdac2020-03-16 18:32:44 -0600151 LogObjectList objlist(descriptor_set);
152 objlist.add(parent_pool);
153 objlist.add(descriptor_pool);
154 skip |= LogError(objlist, "VUID-vkFreeDescriptorSets-pDescriptorSets-parent",
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700155 "FreeDescriptorSets is attempting to free %s"
156 " belonging to %s from %s).",
157 report_data->FormatHandle(descriptor_set).c_str(), report_data->FormatHandle(parent_pool).c_str(),
158 report_data->FormatHandle(descriptor_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600159 }
160 } else {
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700161 skip |= LogError(descriptor_set, "VUID-vkFreeDescriptorSets-pDescriptorSets-00310", "Invalid %s.",
162 report_data->FormatHandle(descriptor_set).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600163 }
164 return skip;
165}
166
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500167bool ObjectLifetimes::ValidateDescriptorWrite(VkWriteDescriptorSet const *desc, bool isPush) const {
Chris Forbes2c600e92017-10-20 11:13:20 -0700168 bool skip = false;
169
170 if (!isPush && desc->dstSet) {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600171 skip |= ValidateObject(desc->dstSet, kVulkanObjectTypeDescriptorSet, false, "VUID-VkWriteDescriptorSet-dstSet-00320",
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600172 "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700173 }
174
175 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
176 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
177 for (uint32_t idx2 = 0; idx2 < desc->descriptorCount; ++idx2) {
Jeff Bolz165818a2020-05-08 11:19:03 -0500178 skip |= ValidateObject(desc->pTexelBufferView[idx2], kVulkanObjectTypeBufferView, true,
179 "VUID-VkWriteDescriptorSet-descriptorType-02994", "VUID-VkWriteDescriptorSet-commonparent");
180 if (!null_descriptor_enabled && desc->pTexelBufferView[idx2] == VK_NULL_HANDLE) {
181 skip |= LogError(desc->dstSet, "VUID-VkWriteDescriptorSet-descriptorType-02995",
182 "VkWriteDescriptorSet: texel buffer view must not be VK_NULL_HANDLE.");
183 }
Chris Forbes2c600e92017-10-20 11:13:20 -0700184 }
185 }
186
187 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
Dave Houltona9df0ce2018-02-07 10:51:23 -0700188 (desc->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
Chris Forbes2c600e92017-10-20 11:13:20 -0700189 (desc->descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
190 for (uint32_t idx3 = 0; idx3 < desc->descriptorCount; ++idx3) {
Jeff Bolz165818a2020-05-08 11:19:03 -0500191 skip |= ValidateObject(desc->pImageInfo[idx3].imageView, kVulkanObjectTypeImageView, true,
192 "VUID-VkWriteDescriptorSet-descriptorType-02996", "VUID-VkDescriptorImageInfo-commonparent");
193 if (!null_descriptor_enabled && desc->pImageInfo[idx3].imageView == VK_NULL_HANDLE) {
194 skip |= LogError(desc->dstSet, "VUID-VkWriteDescriptorSet-descriptorType-02997",
195 "VkWriteDescriptorSet: image view must not be VK_NULL_HANDLE.");
196 }
Chris Forbes2c600e92017-10-20 11:13:20 -0700197 }
198 }
199
200 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
201 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
202 (desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
203 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
204 for (uint32_t idx4 = 0; idx4 < desc->descriptorCount; ++idx4) {
Jeff Bolz165818a2020-05-08 11:19:03 -0500205 skip |= ValidateObject(desc->pBufferInfo[idx4].buffer, kVulkanObjectTypeBuffer, true,
Jeff Bolzc8b18a42020-04-05 16:47:11 -0500206 "VUID-VkDescriptorBufferInfo-buffer-parameter", kVUIDUndefined);
Jeff Bolz165818a2020-05-08 11:19:03 -0500207 if (!null_descriptor_enabled && desc->pBufferInfo[idx4].buffer == VK_NULL_HANDLE) {
208 skip |= LogError(desc->dstSet, "VUID-VkDescriptorBufferInfo-buffer-02998",
209 "VkWriteDescriptorSet: buffer must not be VK_NULL_HANDLE.");
210 }
Jeff Bolzc8b18a42020-04-05 16:47:11 -0500211 }
212 }
213
214 if (desc->descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700215 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(desc->pNext);
Jeff Bolzc8b18a42020-04-05 16:47:11 -0500216 for (uint32_t idx5 = 0; idx5 < desc->descriptorCount; ++idx5) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700217 skip |= ValidateObject(acc_info->pAccelerationStructures[idx5], kVulkanObjectTypeAccelerationStructureKHR, true,
Jeff Bolzc8b18a42020-04-05 16:47:11 -0500218 "VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-parameter",
219 kVUIDUndefined);
Chris Forbes2c600e92017-10-20 11:13:20 -0700220 }
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,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500228 const VkWriteDescriptorSet *pDescriptorWrites) const {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600229 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600230 skip |= ValidateObject(commandBuffer, kVulkanObjectTypeCommandBuffer, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600231 "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
Mark Lobodzinski39965742019-09-11 11:03:51 -0600232 skip |= ValidateObject(layout, kVulkanObjectTypePipelineLayout, false, "VUID-vkCmdPushDescriptorSetKHR-layout-parameter",
233 "VUID-vkCmdPushDescriptorSetKHR-commonparent");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600234 if (pDescriptorWrites) {
235 for (uint32_t index0 = 0; index0 < descriptorWriteCount; ++index0) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600236 skip |= ValidateDescriptorWrite(&pDescriptorWrites[index0], true);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600237 }
238 }
239 return skip;
240}
241
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600242void ObjectLifetimes::CreateQueue(VkQueue vkObj) {
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500243 std::shared_ptr<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()) {
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500246 p_obj_node = std::make_shared<ObjTrackState>();
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700247 InsertObject(object_map[kVulkanObjectTypeQueue], vkObj, kVulkanObjectTypeQueue, p_obj_node);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600248 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 Lobodzinski702c6a42019-09-11 11:52:23 -0600258void ObjectLifetimes::CreateSwapchainImageObject(VkImage swapchain_image, VkSwapchainKHR swapchain) {
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500259 if (!swapchainImageMap.contains(HandleToUint64(swapchain_image))) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700260 auto new_obj_node = std::make_shared<ObjTrackState>();
261 new_obj_node->object_type = kVulkanObjectTypeImage;
262 new_obj_node->status = OBJSTATUS_NONE;
263 new_obj_node->handle = HandleToUint64(swapchain_image);
264 new_obj_node->parent_object = HandleToUint64(swapchain);
265 InsertObject(swapchainImageMap, swapchain_image, kVulkanObjectTypeImage, new_obj_node);
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500266 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600267}
268
Mark Lobodzinskibe102ad2019-09-04 12:03:07 -0600269bool ObjectLifetimes::ReportLeakedInstanceObjects(VkInstance instance, VulkanObjectType object_type,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500270 const std::string &error_code) const {
Mark Lobodzinski7cef2632019-08-28 15:50:13 -0600271 bool skip = false;
272
273 auto snapshot = object_map[object_type].snapshot();
274 for (const auto &item : snapshot) {
275 const auto object_info = item.second;
Mark Lobodzinskib03bdac2020-03-16 18:32:44 -0600276 LogObjectList objlist(instance);
277 objlist.add(ObjTrackStateTypedHandle(*object_info));
278 skip |= LogError(objlist, error_code, "OBJ ERROR : For %s, %s has not been destroyed.",
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700279 report_data->FormatHandle(instance).c_str(),
280 report_data->FormatHandle(ObjTrackStateTypedHandle(*object_info)).c_str());
Mark Lobodzinski7cef2632019-08-28 15:50:13 -0600281 }
282 return skip;
283}
284
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500285bool ObjectLifetimes::ReportLeakedDeviceObjects(VkDevice device, VulkanObjectType object_type,
286 const std::string &error_code) const {
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600287 bool skip = false;
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500288
289 auto snapshot = object_map[object_type].snapshot();
290 for (const auto &item : snapshot) {
291 const auto object_info = item.second;
Mark Lobodzinskib03bdac2020-03-16 18:32:44 -0600292 LogObjectList objlist(device);
293 objlist.add(ObjTrackStateTypedHandle(*object_info));
294 skip |= LogError(objlist, error_code, "OBJ ERROR : For %s, %s has not been destroyed.",
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700295 report_data->FormatHandle(device).c_str(),
296 report_data->FormatHandle(ObjTrackStateTypedHandle(*object_info)).c_str());
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000297 }
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600298 return skip;
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000299}
300
Jeff Bolz5c801d12019-10-09 10:38:45 -0500301bool ObjectLifetimes::PreCallValidateDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) const {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600302 bool skip = false;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600303
Petr Kraus3e6cd032020-04-14 20:41:16 +0200304 // We validate here for coverage, though we'd not have made it this far with a bad instance.
Mark Lobodzinski39965742019-09-11 11:03:51 -0600305 skip |= ValidateObject(instance, kVulkanObjectTypeInstance, true, "VUID-vkDestroyInstance-instance-parameter", kVUIDUndefined);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600306
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500307 auto snapshot = object_map[kVulkanObjectTypeDevice].snapshot();
308 for (const auto &iit : snapshot) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700309 auto node = iit.second;
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600310
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700311 VkDevice device = reinterpret_cast<VkDevice>(node->handle);
312 VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[node->object_type];
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600313
Mark Lobodzinskicb4784a2020-01-29 15:34:59 -0700314 skip |= LogError(device, kVUID_ObjectTracker_ObjectLeak, "OBJ ERROR : %s object %s has not been destroyed.",
315 string_VkDebugReportObjectTypeEXT(debug_object_type),
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700316 report_data->FormatHandle(ObjTrackStateTypedHandle(*node)).c_str());
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600317
Mark Lobodzinski7cef2632019-08-28 15:50:13 -0600318 // Throw errors if any device objects belonging to this instance have not been destroyed
Mark Lobodzinski07548092019-12-17 12:17:12 -0700319 auto device_layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
320 auto obj_lifetimes_data = reinterpret_cast<ObjectLifetimes *>(
321 device_layer_data->GetValidationObject(device_layer_data->object_dispatch, LayerObjectTypeObjectTracker));
322 skip |= obj_lifetimes_data->ReportUndestroyedDeviceObjects(device, "VUID-vkDestroyDevice-device-00378");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600323
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600324 skip |= ValidateDestroyObject(device, kVulkanObjectTypeDevice, pAllocator, "VUID-vkDestroyInstance-instance-00630",
325 "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600326 }
327
Petr Kraus3e6cd032020-04-14 20:41:16 +0200328 skip |= ValidateDestroyObject(instance, kVulkanObjectTypeInstance, pAllocator, "VUID-vkDestroyInstance-instance-00630",
329 "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600330
Mark Lobodzinski7cef2632019-08-28 15:50:13 -0600331 // Report any remaining instance objects
332 skip |= ReportUndestroyedInstanceObjects(instance, "VUID-vkDestroyInstance-instance-00629");
Mark Lobodzinski7cef2632019-08-28 15:50:13 -0600333
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600334 return skip;
335}
336
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600337bool ObjectLifetimes::PreCallValidateEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500338 VkPhysicalDevice *pPhysicalDevices) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600339 bool skip = ValidateObject(instance, kVulkanObjectTypeInstance, false, "VUID-vkEnumeratePhysicalDevices-instance-parameter",
340 kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600341 return skip;
342}
343
344void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700345 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
346 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600347 if (pPhysicalDevices) {
348 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinski1e76a7d2019-09-11 11:11:46 -0600349 CreateObject(pPhysicalDevices[i], kVulkanObjectTypePhysicalDevice, nullptr);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600350 }
351 }
352}
353
354void ObjectLifetimes::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600355 // Destroy physical devices
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500356 auto snapshot = object_map[kVulkanObjectTypePhysicalDevice].snapshot();
357 for (const auto &iit : snapshot) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700358 auto node = iit.second;
359 VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(node->handle);
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600360 RecordDestroyObject(physical_device, kVulkanObjectTypePhysicalDevice);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600361 }
362
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700363 // Destroy child devices
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500364 auto snapshot2 = object_map[kVulkanObjectTypeDevice].snapshot();
365 for (const auto &iit : snapshot2) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700366 auto node = iit.second;
367 VkDevice device = reinterpret_cast<VkDevice>(node->handle);
Mark Lobodzinskie65acca2019-09-11 12:06:17 -0600368 DestroyLeakedInstanceObjects();
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700369
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600370 RecordDestroyObject(device, kVulkanObjectTypeDevice);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600371 }
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600372}
373
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600374void ObjectLifetimes::PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600375 RecordDestroyObject(instance, kVulkanObjectTypeInstance);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600376}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600377
Jeff Bolz5c801d12019-10-09 10:38:45 -0500378bool ObjectLifetimes::PreCallValidateDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) const {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600379 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600380 skip |= ValidateObject(device, kVulkanObjectTypeDevice, true, "VUID-vkDestroyDevice-device-parameter", kVUIDUndefined);
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600381 skip |= ValidateDestroyObject(device, kVulkanObjectTypeDevice, pAllocator, "VUID-vkDestroyDevice-device-00379",
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600382 "VUID-vkDestroyDevice-device-00380");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600383 // Report any remaining objects associated with this VkDevice object in LL
Mark Lobodzinski7cef2632019-08-28 15:50:13 -0600384 skip |= ReportUndestroyedDeviceObjects(device, "VUID-vkDestroyDevice-device-00378");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600385
386 return skip;
387}
388
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600389void ObjectLifetimes::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski52db2352018-12-28 09:41:15 -0700390 auto instance_data = GetLayerDataPtr(get_dispatch_key(physical_device), layer_data_map);
391 ValidationObject *validation_data = GetValidationObject(instance_data->object_dispatch, LayerObjectTypeObjectTracker);
392 ObjectLifetimes *object_lifetimes = static_cast<ObjectLifetimes *>(validation_data);
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600393 object_lifetimes->RecordDestroyObject(device, kVulkanObjectTypeDevice);
Mark Lobodzinskie65acca2019-09-11 12:06:17 -0600394 DestroyLeakedDeviceObjects();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600395
396 // Clean up Queue's MemRef Linked Lists
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600397 DestroyQueueDataStructures();
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600398}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600399
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600400bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500401 VkQueue *pQueue) const {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600402 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600403 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600404 return skip;
405}
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600406
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600407void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
408 VkQueue *pQueue) {
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600409 auto lock = WriteSharedLock();
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600410 CreateQueue(*pQueue);
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600411}
412
Jeff Bolz5c801d12019-10-09 10:38:45 -0500413bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600414 return ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue2-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600415}
416
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600417void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600418 auto lock = WriteSharedLock();
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600419 CreateQueue(*pQueue);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600420}
421
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600422bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
423 const VkWriteDescriptorSet *pDescriptorWrites,
424 uint32_t descriptorCopyCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500425 const VkCopyDescriptorSet *pDescriptorCopies) const {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600426 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600427 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkUpdateDescriptorSets-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600428 if (pDescriptorCopies) {
429 for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
430 if (pDescriptorCopies[idx0].dstSet) {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600431 skip |= ValidateObject(pDescriptorCopies[idx0].dstSet, kVulkanObjectTypeDescriptorSet, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600432 "VUID-VkCopyDescriptorSet-dstSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600433 }
434 if (pDescriptorCopies[idx0].srcSet) {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600435 skip |= ValidateObject(pDescriptorCopies[idx0].srcSet, kVulkanObjectTypeDescriptorSet, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600436 "VUID-VkCopyDescriptorSet-srcSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600437 }
438 }
439 }
440 if (pDescriptorWrites) {
441 for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600442 skip |= ValidateDescriptorWrite(&pDescriptorWrites[idx1], false);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600443 }
444 }
445 return skip;
446}
447
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600448bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500449 VkDescriptorPoolResetFlags flags) const {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600450 bool skip = false;
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600451 auto lock = ReadSharedLock();
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600452
Mark Lobodzinski39965742019-09-11 11:03:51 -0600453 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter", kVUIDUndefined);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600454 skip |=
Mark Lobodzinski39965742019-09-11 11:03:51 -0600455 ValidateObject(descriptorPool, kVulkanObjectTypeDescriptorPool, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600456 "VUID-vkResetDescriptorPool-descriptorPool-parameter", "VUID-vkResetDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600457
458 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
459 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700460 auto pool_node = itr->second;
461 for (auto set : *pool_node->child_objects) {
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600462 skip |= ValidateDestroyObject((VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600463 kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600464 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600465 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600466 return skip;
467}
468
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600469void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
470 VkDescriptorPoolResetFlags flags) {
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600471 auto lock = WriteSharedLock();
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600472 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
473 // our descriptorSet map.
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600474 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
475 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700476 auto pool_node = itr->second;
477 for (auto set : *pool_node->child_objects) {
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600478 RecordDestroyObject((VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600479 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700480 pool_node->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600481 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600482}
483
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600484bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500485 const VkCommandBufferBeginInfo *begin_info) const {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600486 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600487 skip |= ValidateObject(command_buffer, kVulkanObjectTypeCommandBuffer, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600488 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600489 if (begin_info) {
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500490 auto iter = object_map[kVulkanObjectTypeCommandBuffer].find(HandleToUint64(command_buffer));
491 if (iter != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700492 auto node = iter->second;
493 if ((begin_info->pInheritanceInfo) && (node->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500494 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
495 skip |=
Mark Lobodzinski39965742019-09-11 11:03:51 -0600496 ValidateObject(begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600497 "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500498 skip |=
amhagana448ea52021-11-02 14:09:14 -0400499 ValidateObject(begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, true,
500 "VUID-VkCommandBufferBeginInfo-flags-06000", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500501 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600502 }
503 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600504 return skip;
505}
506
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600507bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500508 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) const {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600509 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600510 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600511 "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinski39965742019-09-11 11:03:51 -0600512 skip |= ValidateObject(swapchain, kVulkanObjectTypeSwapchainKHR, false, "VUID-vkGetSwapchainImagesKHR-swapchain-parameter",
513 "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600514 return skip;
515}
516
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600517void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700518 VkImage *pSwapchainImages, VkResult result) {
519 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600520 auto lock = WriteSharedLock();
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600521 if (pSwapchainImages != NULL) {
522 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600523 CreateSwapchainImageObject(pSwapchainImages[i], swapchain);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600524 }
525 }
526}
527
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600528bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
529 const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500530 VkDescriptorSetLayout *pSetLayout) const {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100531 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600532 skip |=
533 ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorSetLayout-device-parameter", 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 Lobodzinski39965742019-09-11 11:03:51 -0600543 skip |= ValidateObject(sampler, kVulkanObjectTypeSampler, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600544 "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;
Mark Lobodzinski1e76a7d2019-09-11 11:11:46 -0600557 CreateObject(*pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600558}
559
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500560bool ObjectLifetimes::ValidateSamplerObjects(const VkDescriptorSetLayoutCreateInfo *pCreateInfo) const {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600561 bool skip = false;
562 if (pCreateInfo->pBindings) {
563 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
564 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
565 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600566 skip |= ValidateObject(pCreateInfo->pBindings[index1].pImmutableSamplers[index2], kVulkanObjectTypeSampler,
567 true, "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600568 }
569 }
570 }
571 }
572 return skip;
573}
574
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600575bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(VkDevice device,
576 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500577 VkDescriptorSetLayoutSupport *pSupport) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600578 bool skip = ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkGetDescriptorSetLayoutSupport-device-parameter",
579 kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600580 if (pCreateInfo) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600581 skip |= ValidateSamplerObjects(pCreateInfo);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600582 }
583 return skip;
584}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600585bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
586 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500587 VkDescriptorSetLayoutSupport *pSupport) const {
Mike Schuchardt65847d92019-12-20 13:50:47 -0800588 bool skip = ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkGetDescriptorSetLayoutSupport-device-parameter",
Mark Lobodzinski39965742019-09-11 11:03:51 -0600589 kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600590 if (pCreateInfo) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600591 skip |= ValidateSamplerObjects(pCreateInfo);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600592 }
593 return skip;
594}
595
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600596bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
597 uint32_t *pQueueFamilyPropertyCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500598 VkQueueFamilyProperties *pQueueFamilyProperties) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600599 return ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600600 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600601}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600602
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600603void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
604 uint32_t *pQueueFamilyPropertyCount,
Jeff Bolz6d243112019-08-21 13:24:11 -0500605 VkQueueFamilyProperties *pQueueFamilyProperties) {}
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600606
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600607void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700608 VkInstance *pInstance, VkResult result) {
609 if (result != VK_SUCCESS) return;
Mark Lobodzinski1e76a7d2019-09-11 11:11:46 -0600610 CreateObject(*pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600611}
612
Jeff Bolz165818a2020-05-08 11:19:03 -0500613bool ObjectLifetimes::PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
614 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) const {
615 bool skip = false;
616 skip |= ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false, "VUID-vkCreateDevice-physicalDevice-parameter",
617 kVUIDUndefined);
618
619 return skip;
620}
621
622void ObjectLifetimes::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
623 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
624 if (result != VK_SUCCESS) return;
625 CreateObject(*pDevice, kVulkanObjectTypeDevice, pAllocator);
626
627 auto device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
628 ValidationObject *validation_data = GetValidationObject(device_data->object_dispatch, LayerObjectTypeObjectTracker);
629 ObjectLifetimes *object_tracking = static_cast<ObjectLifetimes *>(validation_data);
630
631 object_tracking->device_createinfo_pnext = SafePnextCopy(pCreateInfo->pNext);
632 const auto *robustness2_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700633 LvlFindInChain<VkPhysicalDeviceRobustness2FeaturesEXT>(object_tracking->device_createinfo_pnext);
Jeff Bolz165818a2020-05-08 11:19:03 -0500634 object_tracking->null_descriptor_enabled = robustness2_features && robustness2_features->nullDescriptor;
635}
636
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600637bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500638 VkCommandBuffer *pCommandBuffers) const {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600639 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600640 skip |=
641 ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter", kVUIDUndefined);
642 skip |= ValidateObject(pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600643 "VUID-VkCommandBufferAllocateInfo-commandPool-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600644 return skip;
645}
646
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600647void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700648 VkCommandBuffer *pCommandBuffers, VkResult result) {
649 if (result != VK_SUCCESS) return;
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600650 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600651 AllocateCommandBuffer(pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600652 }
653}
654
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600655bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500656 VkDescriptorSet *pDescriptorSets) const {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600657 bool skip = false;
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600658 auto lock = ReadSharedLock();
Mark Lobodzinski39965742019-09-11 11:03:51 -0600659 skip |=
660 ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter", kVUIDUndefined);
661 skip |= ValidateObject(pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600662 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
663 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600664 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600665 skip |= ValidateObject(pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600666 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
667 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600668 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600669 return skip;
670}
671
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600672void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700673 VkDescriptorSet *pDescriptorSets, VkResult result) {
674 if (result != VK_SUCCESS) return;
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600675 auto lock = WriteSharedLock();
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600676 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600677 AllocateDescriptorSet(pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600678 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600679}
680
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600681bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500682 const VkCommandBuffer *pCommandBuffers) const {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600683 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600684 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter", kVUIDUndefined);
685 skip |= ValidateObject(commandPool, kVulkanObjectTypeCommandPool, false, "VUID-vkFreeCommandBuffers-commandPool-parameter",
686 "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600687 for (uint32_t i = 0; i < commandBufferCount; i++) {
688 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600689 skip |= ValidateCommandBuffer(commandPool, pCommandBuffers[i]);
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600690 skip |=
691 ValidateDestroyObject(pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600692 }
693 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600694 return skip;
695}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600696
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600697void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
698 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600699 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600700 RecordDestroyObject(pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600701 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600702}
703
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600704bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500705 const VkAllocationCallbacks *pAllocator) const {
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600706 return ValidateDestroyObject(swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator, "VUID-vkDestroySwapchainKHR-swapchain-01283",
707 "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600708}
709
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600710void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
711 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600712 RecordDestroyObject(swapchain, kVulkanObjectTypeSwapchainKHR);
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500713
714 auto snapshot = swapchainImageMap.snapshot(
715 [swapchain](std::shared_ptr<ObjTrackState> pNode) { return pNode->parent_object == HandleToUint64(swapchain); });
716 for (const auto &itr : snapshot) {
717 swapchainImageMap.erase(itr.first);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600718 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600719}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600720
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600721bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500722 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) const {
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600723 auto lock = ReadSharedLock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600724 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600725 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter", kVUIDUndefined);
726 skip |= ValidateObject(descriptorPool, kVulkanObjectTypeDescriptorPool, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600727 "VUID-vkFreeDescriptorSets-descriptorPool-parameter", "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600728 for (uint32_t i = 0; i < descriptorSetCount; i++) {
729 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600730 skip |= ValidateDescriptorSet(descriptorPool, pDescriptorSets[i]);
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600731 skip |=
732 ValidateDestroyObject(pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600733 }
734 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600735 return skip;
736}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600737void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
738 const VkDescriptorSet *pDescriptorSets) {
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600739 auto lock = WriteSharedLock();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700740 std::shared_ptr<ObjTrackState> pool_node = nullptr;
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600741 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
742 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700743 pool_node = itr->second;
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600744 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600745 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600746 RecordDestroyObject(pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700747 if (pool_node) {
748 pool_node->child_objects->erase(HandleToUint64(pDescriptorSets[i]));
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600749 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600750 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600751}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600752
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600753bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500754 const VkAllocationCallbacks *pAllocator) const {
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600755 auto lock = ReadSharedLock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600756 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600757 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter", kVUIDUndefined);
758 skip |= ValidateObject(descriptorPool, kVulkanObjectTypeDescriptorPool, true,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600759 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
760 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600761
762 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
763 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700764 auto pool_node = itr->second;
765 for (auto set : *pool_node->child_objects) {
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600766 skip |= ValidateDestroyObject((VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600767 kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600768 }
769 }
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600770 skip |= ValidateDestroyObject(descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600771 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
772 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600773 return skip;
774}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600775void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
776 const VkAllocationCallbacks *pAllocator) {
Jeremy Gebben2e5b41b2021-10-11 16:41:49 -0600777 auto lock = WriteSharedLock();
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600778 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
779 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700780 auto pool_node = itr->second;
781 for (auto set : *pool_node->child_objects) {
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600782 RecordDestroyObject((VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600783 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700784 pool_node->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600785 }
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600786 RecordDestroyObject(descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600787}
788
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600789bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500790 const VkAllocationCallbacks *pAllocator) const {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600791 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600792 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter", kVUIDUndefined);
793 skip |= ValidateObject(commandPool, kVulkanObjectTypeCommandPool, true, "VUID-vkDestroyCommandPool-commandPool-parameter",
794 "VUID-vkDestroyCommandPool-commandPool-parent");
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500795
796 auto snapshot = object_map[kVulkanObjectTypeCommandBuffer].snapshot(
797 [commandPool](std::shared_ptr<ObjTrackState> pNode) { return pNode->parent_object == HandleToUint64(commandPool); });
798 for (const auto &itr : snapshot) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700799 auto node = itr.second;
Mark Lobodzinski702c6a42019-09-11 11:52:23 -0600800 skip |= ValidateCommandBuffer(commandPool, reinterpret_cast<VkCommandBuffer>(itr.first));
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600801 skip |= ValidateDestroyObject(reinterpret_cast<VkCommandBuffer>(itr.first), kVulkanObjectTypeCommandBuffer, nullptr,
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500802 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600803 }
Mark Lobodzinski3d89a2c2019-09-11 11:41:11 -0600804 skip |= ValidateDestroyObject(commandPool, kVulkanObjectTypeCommandPool, pAllocator,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600805 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600806 return skip;
807}
808
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600809void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
810 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500811 auto snapshot = object_map[kVulkanObjectTypeCommandBuffer].snapshot(
812 [commandPool](std::shared_ptr<ObjTrackState> pNode) { return pNode->parent_object == HandleToUint64(commandPool); });
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600813 // A CommandPool's cmd buffers are implicitly deleted when pool is deleted. Remove this pool's cmdBuffers from cmd buffer map.
Jeff Bolzfd3bb242019-08-22 06:10:49 -0500814 for (const auto &itr : snapshot) {
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600815 RecordDestroyObject(reinterpret_cast<VkCommandBuffer>(itr.first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600816 }
Mark Lobodzinski82742f62019-09-11 11:20:26 -0600817 RecordDestroyObject(commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600818}
819
Jeff Bolz5c801d12019-10-09 10:38:45 -0500820bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(
Mike Schuchardt2df08912020-12-15 16:28:09 -0800821 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600822 return ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600823 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600824}
825
Jeff Bolz5c801d12019-10-09 10:38:45 -0500826bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(
827 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600828 return ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Shannon McPherson3ea65132018-12-05 10:37:39 -0700829 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600830}
831
832void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
833 uint32_t *pQueueFamilyPropertyCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -0800834 VkQueueFamilyProperties2 *pQueueFamilyProperties) {}
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600835
Mike Schuchardt2df08912020-12-15 16:28:09 -0800836void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
837 uint32_t *pQueueFamilyPropertyCount,
838 VkQueueFamilyProperties2 *pQueueFamilyProperties) {}
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600839
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600840bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
841 uint32_t *pPropertyCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500842 VkDisplayPropertiesKHR *pProperties) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600843 return ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600844 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600845}
846
847void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700848 VkDisplayPropertiesKHR *pProperties, VkResult result) {
849 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600850 if (pProperties) {
851 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinski1e76a7d2019-09-11 11:11:46 -0600852 CreateObject(pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600853 }
854 }
855}
856
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600857bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
858 uint32_t *pPropertyCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500859 VkDisplayModePropertiesKHR *pProperties) const {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600860 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600861 skip |= ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600862 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski39965742019-09-11 11:03:51 -0600863 skip |= ValidateObject(display, kVulkanObjectTypeDisplayKHR, false, "VUID-vkGetDisplayModePropertiesKHR-display-parameter",
864 kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600865
866 return skip;
867}
868
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600869void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700870 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties,
871 VkResult result) {
872 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600873 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600874 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinski1e76a7d2019-09-11 11:11:46 -0600875 CreateObject(pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600876 }
877 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600878}
879
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600880bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
881 uint32_t *pPropertyCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500882 VkDisplayProperties2KHR *pProperties) const {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600883 return ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600884 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600885}
886
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600887void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
888 uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700889 VkDisplayProperties2KHR *pProperties, VkResult result) {
890 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Timo Suorantad2eaa042020-07-13 11:30:38 +0300891 if (pProperties) {
892 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
893 CreateObject(pProperties[index].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
894 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600895 }
896}
897
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600898bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
899 uint32_t *pPropertyCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500900 VkDisplayModeProperties2KHR *pProperties) const {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600901 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600902 skip |= ValidateObject(physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600903 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski39965742019-09-11 11:03:51 -0600904 skip |= ValidateObject(display, kVulkanObjectTypeDisplayKHR, false, "VUID-vkGetDisplayModeProperties2KHR-display-parameter",
905 kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600906
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600907 return skip;
908}
909
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600910void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700911 uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties,
912 VkResult result) {
913 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Timo Suorantad2eaa042020-07-13 11:30:38 +0300914 if (pProperties) {
915 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
916 CreateObject(pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
917 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600918 }
919}
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600920
Mark Lobodzinski616ffc62020-10-22 09:31:00 -0600921void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
922 uint32_t *pPropertyCount,
923 VkDisplayPlanePropertiesKHR *pProperties,
924 VkResult result) {
925 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
926 if (pProperties) {
927 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
928 CreateObject(pProperties[index].currentDisplay, kVulkanObjectTypeDisplayKHR, nullptr);
929 }
930 }
931}
932
933void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
934 uint32_t *pPropertyCount,
935 VkDisplayPlaneProperties2KHR *pProperties,
936 VkResult result) {
937 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
938 if (pProperties) {
939 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
940 CreateObject(pProperties[index].displayPlaneProperties.currentDisplay, kVulkanObjectTypeDisplayKHR, nullptr);
941 }
942 }
943}
944
Tobias Hectorc9057422019-07-23 12:15:52 +0100945bool ObjectLifetimes::PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500946 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) const {
Tobias Hectorc9057422019-07-23 12:15:52 +0100947 bool skip = false;
Mark Lobodzinski39965742019-09-11 11:03:51 -0600948 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkCreateFramebuffer-device-parameter", kVUIDUndefined);
Tobias Hectorc9057422019-07-23 12:15:52 +0100949 if (pCreateInfo) {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600950 skip |= ValidateObject(pCreateInfo->renderPass, kVulkanObjectTypeRenderPass, false,
Tobias Hectorc9057422019-07-23 12:15:52 +0100951 "VUID-VkFramebufferCreateInfo-renderPass-parameter", "VUID-VkFramebufferCreateInfo-commonparent");
Mike Schuchardt2df08912020-12-15 16:28:09 -0800952 if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) == 0) {
Tobias Hectorc9057422019-07-23 12:15:52 +0100953 for (uint32_t index1 = 0; index1 < pCreateInfo->attachmentCount; ++index1) {
Mark Lobodzinski39965742019-09-11 11:03:51 -0600954 skip |= ValidateObject(pCreateInfo->pAttachments[index1], kVulkanObjectTypeImageView, true, kVUIDUndefined,
Tobias Hectorc9057422019-07-23 12:15:52 +0100955 "VUID-VkFramebufferCreateInfo-commonparent");
956 }
957 }
958 }
959
960 return skip;
961}
962
963void ObjectLifetimes::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
964 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
965 VkResult result) {
966 if (result != VK_SUCCESS) return;
Mark Lobodzinski1e76a7d2019-09-11 11:11:46 -0600967 CreateObject(*pFramebuffer, kVulkanObjectTypeFramebuffer, pAllocator);
Tobias Hectorc9057422019-07-23 12:15:52 +0100968}
Mark Lobodzinski417b7572019-09-11 15:10:26 -0600969
Jeff Bolz5c801d12019-10-09 10:38:45 -0500970bool ObjectLifetimes::PreCallValidateSetDebugUtilsObjectNameEXT(VkDevice device,
971 const VkDebugUtilsObjectNameInfoEXT *pNameInfo) const {
Mark Lobodzinski417b7572019-09-11 15:10:26 -0600972 bool skip = false;
973 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkSetDebugUtilsObjectNameEXT-device-parameter",
974 kVUIDUndefined);
975 skip |= ValidateAnonymousObject(pNameInfo->objectHandle, pNameInfo->objectType, false,
976 "VUID-VkDebugUtilsObjectNameInfoEXT-objectType-02590", kVUIDUndefined);
977
978 return skip;
979}
980
Jeff Bolz5c801d12019-10-09 10:38:45 -0500981bool ObjectLifetimes::PreCallValidateSetDebugUtilsObjectTagEXT(VkDevice device,
982 const VkDebugUtilsObjectTagInfoEXT *pTagInfo) const {
Mark Lobodzinski417b7572019-09-11 15:10:26 -0600983 bool skip = false;
984 skip |=
985 ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkSetDebugUtilsObjectTagEXT-device-parameter", kVUIDUndefined);
986 skip |= ValidateAnonymousObject(pTagInfo->objectHandle, pTagInfo->objectType, false,
987 "VUID-VkDebugUtilsObjectTagInfoEXT-objectHandle-01910", kVUIDUndefined);
988
989 return skip;
990}
Mark Lobodzinski67f86382019-12-12 12:28:54 -0700991
992bool ObjectLifetimes::PreCallValidateCreateDescriptorUpdateTemplate(VkDevice device,
993 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
994 const VkAllocationCallbacks *pAllocator,
995 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) const {
996 bool skip = false;
997 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorUpdateTemplate-device-parameter",
998 kVUIDUndefined);
999 if (pCreateInfo) {
1000 if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET) {
1001 skip |= ValidateObject(pCreateInfo->descriptorSetLayout, kVulkanObjectTypeDescriptorSetLayout, false,
1002 "VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00350",
1003 "VUID-VkDescriptorUpdateTemplateCreateInfo-commonparent");
1004 }
1005 if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR) {
1006 skip |= ValidateObject(pCreateInfo->pipelineLayout, kVulkanObjectTypePipelineLayout, false,
1007 "VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00352",
1008 "VUID-VkDescriptorUpdateTemplateCreateInfo-commonparent");
1009 }
1010 }
1011
1012 return skip;
1013}
1014
1015bool ObjectLifetimes::PreCallValidateCreateDescriptorUpdateTemplateKHR(
1016 VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
1017 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) const {
1018 return PreCallValidateCreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
1019}
1020
1021void ObjectLifetimes::PostCallRecordCreateDescriptorUpdateTemplate(VkDevice device,
1022 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
1023 const VkAllocationCallbacks *pAllocator,
1024 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate,
1025 VkResult result) {
1026 if (result != VK_SUCCESS) return;
1027 CreateObject(*pDescriptorUpdateTemplate, kVulkanObjectTypeDescriptorUpdateTemplate, pAllocator);
1028}
1029
1030void ObjectLifetimes::PostCallRecordCreateDescriptorUpdateTemplateKHR(VkDevice device,
1031 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
1032 const VkAllocationCallbacks *pAllocator,
1033 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate,
1034 VkResult result) {
1035 return PostCallRecordCreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate, result);
1036}
Nathaniel Cesario7e5b1a72021-10-04 23:39:20 -06001037
1038bool ObjectLifetimes::ValidateAccelerationStructures(const char *dst_handle_vuid, uint32_t count,
1039 const VkAccelerationStructureBuildGeometryInfoKHR *infos) const {
1040 bool skip = false;
1041 if (infos) {
1042 const char *device_vuid = "VUID-VkAccelerationStructureBuildGeometryInfoKHR-commonparent";
1043 for (uint32_t i = 0; i < count; ++i) {
1044 skip |= ValidateObject(infos[i].srcAccelerationStructure, kVulkanObjectTypeAccelerationStructureKHR, true,
1045 kVUIDUndefined, device_vuid);
1046 skip |= ValidateObject(infos[i].dstAccelerationStructure, kVulkanObjectTypeAccelerationStructureKHR, false,
1047 dst_handle_vuid, device_vuid);
1048 }
1049 }
1050
1051 return skip;
1052}
1053
1054bool ObjectLifetimes::PreCallValidateCmdBuildAccelerationStructuresKHR(
1055 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
1056 const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) const {
1057 bool skip = ValidateObject(commandBuffer, kVulkanObjectTypeCommandBuffer, false,
1058 "VUID-vkCmdBuildAccelerationStructuresKHR-commandBuffer-parameter", kVUIDUndefined);
1059 skip |=
1060 ValidateAccelerationStructures("VUID-vkCmdBuildAccelerationStructuresKHR-dstAccelerationStructure-03800", infoCount, pInfos);
1061 return skip;
1062}
1063
1064bool ObjectLifetimes::PreCallValidateCmdBuildAccelerationStructuresIndirectKHR(
1065 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
1066 const VkDeviceAddress *pIndirectDeviceAddresses, const uint32_t *pIndirectStrides,
1067 const uint32_t *const *ppMaxPrimitiveCounts) const {
1068 bool skip = ValidateObject(commandBuffer, kVulkanObjectTypeCommandBuffer, false,
1069 "VUID-vkCmdBuildAccelerationStructuresKHR-commandBuffer-parameter", kVUIDUndefined);
1070 skip |= ValidateAccelerationStructures("VUID-vkCmdBuildAccelerationStructuresIndirectKHR-dstAccelerationStructure-03800",
1071 infoCount, pInfos);
1072 return skip;
1073}
1074
1075bool ObjectLifetimes::PreCallValidateBuildAccelerationStructuresKHR(
1076 VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount,
1077 const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
1078 const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) const {
1079 bool skip = ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkBuildAccelerationStructuresKHR-device-parameter",
1080 kVUIDUndefined);
1081 skip |= ValidateObject(deferredOperation, kVulkanObjectTypeDeferredOperationKHR, true,
1082 "VUID-vkBuildAccelerationStructuresKHR-deferredOperation-parameter",
1083 "VUID-vkBuildAccelerationStructuresKHR-deferredOperation-parent");
1084 skip |=
1085 ValidateAccelerationStructures("VUID-vkBuildAccelerationStructuresKHR-dstAccelerationStructure-03800", infoCount, pInfos);
1086 return skip;
1087}
aitor-lunarg3c145292022-03-25 17:30:11 +01001088
1089bool ObjectLifetimes::PreCallValidateCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1090 VkPipelineCache pipelineCache, uint32_t createInfoCount,
1091 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1092 const VkAllocationCallbacks *pAllocator,
1093 VkPipeline *pPipelines) const {
1094 bool skip = false;
1095 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkCreateRayTracingPipelinesKHR-device-parameter",
1096 kVUIDUndefined);
1097 skip |= ValidateObject(deferredOperation, kVulkanObjectTypeDeferredOperationKHR, true,
1098 "VUID-vkCreateRayTracingPipelinesKHR-deferredOperation-parameter",
1099 "VUID-vkCreateRayTracingPipelinesKHR-deferredOperation-parent");
1100 skip |= ValidateObject(pipelineCache, kVulkanObjectTypePipelineCache, true,
1101 "VUID-vkCreateRayTracingPipelinesKHR-pipelineCache-parameter",
1102 "VUID-vkCreateRayTracingPipelinesKHR-pipelineCache-parent");
1103 if (pCreateInfos) {
1104 for (uint32_t index0 = 0; index0 < createInfoCount; ++index0) {
1105 if (pCreateInfos[index0].pStages) {
1106 for (uint32_t index1 = 0; index1 < pCreateInfos[index0].stageCount; ++index1) {
1107 skip |= ValidateObject(pCreateInfos[index0].pStages[index1].module, kVulkanObjectTypeShaderModule, false,
1108 "VUID-VkPipelineShaderStageCreateInfo-module-parameter", kVUIDUndefined);
1109 }
1110 }
1111 if (pCreateInfos[index0].pLibraryInfo) {
1112 if (pCreateInfos[index0].pLibraryInfo->pLibraries) {
1113 for (uint32_t index2 = 0; index2 < pCreateInfos[index0].pLibraryInfo->libraryCount; ++index2) {
1114 skip |= ValidateObject(pCreateInfos[index0].pLibraryInfo->pLibraries[index2], kVulkanObjectTypePipeline,
1115 false, "VUID-VkPipelineLibraryCreateInfoKHR-pLibraries-parameter", kVUIDUndefined);
1116 }
1117 }
1118 }
1119 skip |= ValidateObject(pCreateInfos[index0].layout, kVulkanObjectTypePipelineLayout, false,
1120 "VUID-VkRayTracingPipelineCreateInfoKHR-layout-parameter",
1121 "VUID-VkRayTracingPipelineCreateInfoKHR-commonparent");
1122 if ((pCreateInfos[index0].flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) && (pCreateInfos[index0].basePipelineIndex == -1))
1123 skip |= ValidateObject(pCreateInfos[index0].basePipelineHandle, kVulkanObjectTypePipeline, false,
1124 "VUID-VkRayTracingPipelineCreateInfoKHR-flags-03421",
1125 "VUID-VkRayTracingPipelineCreateInfoKHR-commonparent");
1126 }
1127 }
1128
1129 return skip;
1130}
1131
1132void ObjectLifetimes::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1133 VkPipelineCache pipelineCache, uint32_t createInfoCount,
1134 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1135 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1136 VkResult result) {
1137 if (VK_ERROR_VALIDATION_FAILED_EXT == result) return;
1138 if (pPipelines) {
1139 if (deferredOperation != VK_NULL_HANDLE && result == VK_OPERATION_DEFERRED_KHR) {
1140 auto register_fn = [this, pAllocator](const std::vector<VkPipeline> &pipelines) {
1141 for (auto pipe : pipelines) {
1142 if (!pipe) continue;
1143 this->CreateObject(pipe, kVulkanObjectTypePipeline, pAllocator);
1144 }
1145 };
1146
1147 auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
1148 if (wrap_handles) {
1149 deferredOperation = layer_data->Unwrap(deferredOperation);
1150 }
1151 std::vector<std::function<void(const std::vector<VkPipeline> &)>> cleanup_fn;
1152 auto find_res = layer_data->deferred_operation_post_check.pop(deferredOperation);
1153 if (find_res->first) {
1154 cleanup_fn = std::move(find_res->second);
1155 }
1156 cleanup_fn.emplace_back(register_fn);
1157 layer_data->deferred_operation_post_check.insert(deferredOperation, cleanup_fn);
1158 } else {
1159 for (uint32_t index = 0; index < createInfoCount; index++) {
1160 if (!pPipelines[index]) continue;
1161 CreateObject(pPipelines[index], kVulkanObjectTypePipeline, pAllocator);
1162 }
1163 }
1164 }
1165}
Tony-LunarGd0a9ed92022-06-22 15:21:51 -06001166#ifdef VK_USE_PLATFORM_METAL_EXT
1167bool ObjectLifetimes::PreCallValidateExportMetalObjectsEXT(VkDevice device, VkExportMetalObjectsInfoEXT *pMetalObjectsInfo) const {
1168 bool skip = false;
1169 skip |= ValidateObject(device, kVulkanObjectTypeDevice, false, "VUID-vkExportMetalObjectsEXT-device-parameter", kVUIDUndefined);
1170
1171 const VkBaseOutStructure *metal_objects_info_ptr = reinterpret_cast<const VkBaseOutStructure *>(pMetalObjectsInfo->pNext);
1172 while (metal_objects_info_ptr) {
1173 switch (metal_objects_info_ptr->sType) {
1174 case VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT: {
1175 auto metal_command_queue_ptr = reinterpret_cast<const VkExportMetalCommandQueueInfoEXT *>(metal_objects_info_ptr);
1176 skip |= ValidateObject(metal_command_queue_ptr->queue, kVulkanObjectTypeQueue, false,
1177 "VUID-VkExportMetalCommandQueueInfoEXT-queue-parameter", kVUIDUndefined);
1178 } break;
1179 case VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT: {
1180 auto metal_buffer_ptr = reinterpret_cast<const VkExportMetalBufferInfoEXT *>(metal_objects_info_ptr);
1181 skip |= ValidateObject(metal_buffer_ptr->memory, kVulkanObjectTypeDeviceMemory, false,
1182 "VUID-VkExportMetalBufferInfoEXT-memory-parameter", kVUIDUndefined);
1183 } break;
1184 case VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT: {
1185 auto metal_texture_ptr = reinterpret_cast<const VkExportMetalTextureInfoEXT *>(metal_objects_info_ptr);
1186 skip |= ValidateObject(metal_texture_ptr->image, kVulkanObjectTypeImage, true,
1187 "VUID-VkExportMetalTextureInfoEXT-image-parameter",
1188 "VUID-VkExportMetalTextureInfoEXT-commonparent");
1189 skip |= ValidateObject(metal_texture_ptr->imageView, kVulkanObjectTypeImageView, true,
1190 "VUID-VkExportMetalTextureInfoEXT-imageView-parameter",
1191 "VUID-VkExportMetalTextureInfoEXT-commonparent");
1192 skip |= ValidateObject(metal_texture_ptr->bufferView, kVulkanObjectTypeBufferView, true,
1193 "VUID-VkExportMetalTextureInfoEXT-bufferView-parameter",
1194 "VUID-VkExportMetalTextureInfoEXT-commonparent");
1195 } break;
1196 case VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT: {
1197 auto metal_iosurface_ptr = reinterpret_cast<const VkExportMetalIOSurfaceInfoEXT *>(metal_objects_info_ptr);
1198 skip |= ValidateObject(metal_iosurface_ptr->image, kVulkanObjectTypeImage, false,
1199 "VUID-VkExportMetalIOSurfaceInfoEXT-image-parameter", kVUIDUndefined);
1200 } break;
1201 case VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT: {
1202 auto metal_shared_event_ptr = reinterpret_cast<const VkExportMetalSharedEventInfoEXT *>(metal_objects_info_ptr);
1203 skip |= ValidateObject(metal_shared_event_ptr->semaphore, kVulkanObjectTypeSemaphore, true,
1204 "VUID-VkExportMetalSharedEventInfoEXT-semaphore-parameter",
1205 "VUID-VkExportMetalSharedEventInfoEXT-commonparent");
1206 skip |= ValidateObject(metal_shared_event_ptr->event, kVulkanObjectTypeEvent, true,
1207 "VUID-VkExportMetalSharedEventInfoEXT-event-parameter",
1208 "VUID-VkExportMetalSharedEventInfoEXT-commonparent");
1209
1210 } break;
1211 default:
1212 break;
1213 }
1214 metal_objects_info_ptr = metal_objects_info_ptr->pNext;
1215 }
1216 return skip;
1217}
1218#endif // VK_USE_PLATFORM_METAL_EXT