blob: 6262a2baa935c8d77591deeae3b7d697dcfbc11a [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// Destroy memRef lists and free all memory
Mark Lobodzinski0c668462018-09-27 10:13:19 -060038void ObjectLifetimes::DestroyQueueDataStructures(VkDevice device) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060039 // Destroy the items in the queue map
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060040 auto queue = object_map[kVulkanObjectTypeQueue].begin();
41 while (queue != object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060042 uint32_t obj_index = queue->second->object_type;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060043 assert(num_total_objects > 0);
44 num_total_objects--;
45 assert(num_objects[obj_index] > 0);
46 num_objects[obj_index]--;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060047 delete queue->second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060048 queue = object_map[kVulkanObjectTypeQueue].erase(queue);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060049 }
50}
51
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070052// Look for this device object in any of the instance child devices lists.
53// NOTE: This is of dubious value. In most circumstances Vulkan will die a flaming death if a dispatchable object is invalid.
54// 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 -060055bool ObjectLifetimes::ValidateDeviceObject(const VulkanTypedHandle &device_typed, const char *invalid_handle_code,
56 const char *wrong_device_code) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060057 auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
58 auto instance_object_lifetime_data = GetObjectLifetimeData(instance_data->object_dispatch);
59 for (auto object : instance_object_lifetime_data->object_map[kVulkanObjectTypeDevice]) {
John Zulauf1c3844a2019-04-01 17:39:48 -060060 if (object.second->handle == device_typed.handle) return false;
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070061 }
John Zulauf1c3844a2019-04-01 17:39:48 -060062 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 -060063 invalid_handle_code, "Invalid %s.", report_data->FormatHandle(device_typed).c_str());
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070064}
65
Mark Lobodzinski0c668462018-09-27 10:13:19 -060066void ObjectLifetimes::AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
67 VkCommandBufferLevel level) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060068 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060069 pNewObjNode->object_type = kVulkanObjectTypeCommandBuffer;
70 pNewObjNode->handle = HandleToUint64(command_buffer);
71 pNewObjNode->parent_object = HandleToUint64(command_pool);
72 if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
73 pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
74 } else {
75 pNewObjNode->status = OBJSTATUS_NONE;
76 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060077 object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)] = pNewObjNode;
78 num_objects[kVulkanObjectTypeCommandBuffer]++;
79 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060080}
81
Mark Lobodzinski0c668462018-09-27 10:13:19 -060082bool ObjectLifetimes::ValidateCommandBuffer(VkDevice device, VkCommandPool command_pool, VkCommandBuffer command_buffer) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060083 bool skip = false;
84 uint64_t object_handle = HandleToUint64(command_buffer);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060085 if (object_map[kVulkanObjectTypeCommandBuffer].find(object_handle) != object_map[kVulkanObjectTypeCommandBuffer].end()) {
86 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060087
88 if (pNode->parent_object != HandleToUint64(command_pool)) {
John Zulauf1c3844a2019-04-01 17:39:48 -060089 // We know that the parent *must* be a command pool
90 const auto parent_pool = CastFromUint64<VkCommandPool>(pNode->parent_object);
locke-lunarg9edc2812019-06-17 23:18:52 -060091 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
92 object_handle, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent",
93 "FreeCommandBuffers is attempting to free %s belonging to %s from %s).",
94 report_data->FormatHandle(command_buffer).c_str(), report_data->FormatHandle(parent_pool).c_str(),
95 report_data->FormatHandle(command_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060096 }
97 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -060098 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 -060099 "VUID-vkFreeCommandBuffers-pCommandBuffers-00048", "Invalid %s.",
100 report_data->FormatHandle(command_buffer).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600101 }
102 return skip;
103}
104
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600105void ObjectLifetimes::AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600106 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600107 pNewObjNode->object_type = kVulkanObjectTypeDescriptorSet;
108 pNewObjNode->status = OBJSTATUS_NONE;
109 pNewObjNode->handle = HandleToUint64(descriptor_set);
110 pNewObjNode->parent_object = HandleToUint64(descriptor_pool);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600111 object_map[kVulkanObjectTypeDescriptorSet][HandleToUint64(descriptor_set)] = pNewObjNode;
112 num_objects[kVulkanObjectTypeDescriptorSet]++;
113 num_total_objects++;
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600114
115 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptor_pool));
116 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
117 ObjTrackState *pPoolNode = itr->second;
118 pPoolNode->child_objects->insert(HandleToUint64(descriptor_set));
119 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600120}
121
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600122bool ObjectLifetimes::ValidateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600123 bool skip = false;
124 uint64_t object_handle = HandleToUint64(descriptor_set);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600125 auto dsItem = object_map[kVulkanObjectTypeDescriptorSet].find(object_handle);
126 if (dsItem != object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600127 ObjTrackState *pNode = dsItem->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600128
129 if (pNode->parent_object != HandleToUint64(descriptor_pool)) {
John Zulauf1c3844a2019-04-01 17:39:48 -0600130 // We know that the parent *must* be a descriptor pool
131 const auto parent_pool = CastFromUint64<VkDescriptorPool>(pNode->parent_object);
132 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
133 object_handle, "VUID-vkFreeDescriptorSets-pDescriptorSets-parent",
locke-lunarg9edc2812019-06-17 23:18:52 -0600134 "FreeDescriptorSets is attempting to free %s"
135 " belonging to %s from %s).",
John Zulauf1c3844a2019-04-01 17:39:48 -0600136 report_data->FormatHandle(descriptor_set).c_str(), report_data->FormatHandle(parent_pool).c_str(),
137 report_data->FormatHandle(descriptor_pool).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600138 }
139 } else {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600140 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 -0600141 "VUID-vkFreeDescriptorSets-pDescriptorSets-00310", "Invalid %s.",
142 report_data->FormatHandle(descriptor_set).c_str());
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600143 }
144 return skip;
145}
146
Dave Houltona9df0ce2018-02-07 10:51:23 -0700147template <typename DispObj>
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600148bool ObjectLifetimes::ValidateDescriptorWrite(DispObj disp, VkWriteDescriptorSet const *desc, bool isPush) {
Chris Forbes2c600e92017-10-20 11:13:20 -0700149 bool skip = false;
150
151 if (!isPush && desc->dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600152 skip |= ValidateObject(disp, desc->dstSet, kVulkanObjectTypeDescriptorSet, false, "VUID-VkWriteDescriptorSet-dstSet-00320",
153 "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700154 }
155
156 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
157 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
158 for (uint32_t idx2 = 0; idx2 < desc->descriptorCount; ++idx2) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600159 skip |= ValidateObject(disp, desc->pTexelBufferView[idx2], kVulkanObjectTypeBufferView, false,
160 "VUID-VkWriteDescriptorSet-descriptorType-00323", "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700161 }
162 }
163
164 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
Dave Houltona9df0ce2018-02-07 10:51:23 -0700165 (desc->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
Chris Forbes2c600e92017-10-20 11:13:20 -0700166 (desc->descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
167 for (uint32_t idx3 = 0; idx3 < desc->descriptorCount; ++idx3) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600168 skip |= ValidateObject(disp, desc->pImageInfo[idx3].imageView, kVulkanObjectTypeImageView, false,
169 "VUID-VkWriteDescriptorSet-descriptorType-00326", "VUID-VkDescriptorImageInfo-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700170 }
171 }
172
173 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
174 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
175 (desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
176 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
177 for (uint32_t idx4 = 0; idx4 < desc->descriptorCount; ++idx4) {
178 if (desc->pBufferInfo[idx4].buffer) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600179 skip |= ValidateObject(disp, desc->pBufferInfo[idx4].buffer, kVulkanObjectTypeBuffer, false,
180 "VUID-VkDescriptorBufferInfo-buffer-parameter", kVUIDUndefined);
Chris Forbes2c600e92017-10-20 11:13:20 -0700181 }
182 }
183 }
184
185 return skip;
186}
187
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600188bool ObjectLifetimes::PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
189 VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
190 const VkWriteDescriptorSet *pDescriptorWrites) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600191 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500192 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600193 skip |= ValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false,
194 "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
195 skip |= ValidateObject(commandBuffer, layout, kVulkanObjectTypePipelineLayout, false,
196 "VUID-vkCmdPushDescriptorSetKHR-layout-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600197 if (pDescriptorWrites) {
198 for (uint32_t index0 = 0; index0 < descriptorWriteCount; ++index0) {
199 skip |= ValidateDescriptorWrite(commandBuffer, &pDescriptorWrites[index0], true);
200 }
201 }
202 return skip;
203}
204
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600205void ObjectLifetimes::CreateQueue(VkDevice device, VkQueue vkObj) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600206 ObjTrackState *p_obj_node = NULL;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600207 auto queue_item = object_map[kVulkanObjectTypeQueue].find(HandleToUint64(vkObj));
208 if (queue_item == object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600209 p_obj_node = new ObjTrackState;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600210 object_map[kVulkanObjectTypeQueue][HandleToUint64(vkObj)] = p_obj_node;
211 num_objects[kVulkanObjectTypeQueue]++;
212 num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600213 } else {
214 p_obj_node = queue_item->second;
215 }
216 p_obj_node->object_type = kVulkanObjectTypeQueue;
217 p_obj_node->status = OBJSTATUS_NONE;
218 p_obj_node->handle = HandleToUint64(vkObj);
219}
220
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600221void ObjectLifetimes::CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600222 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600223 pNewObjNode->object_type = kVulkanObjectTypeImage;
224 pNewObjNode->status = OBJSTATUS_NONE;
225 pNewObjNode->handle = HandleToUint64(swapchain_image);
226 pNewObjNode->parent_object = HandleToUint64(swapchain);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600227 swapchainImageMap[HandleToUint64(swapchain_image)] = pNewObjNode;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600228}
229
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600230bool ObjectLifetimes::DeviceReportUndestroyedObjects(VkDevice device, VulkanObjectType object_type, const std::string &error_code) {
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600231 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600232 for (const auto &item : object_map[object_type]) {
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000233 const ObjTrackState *object_info = item.second;
locke-lunarg9edc2812019-06-17 23:18:52 -0600234 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type], object_info->handle,
235 error_code, "OBJ ERROR : For %s, %s has not been destroyed.", report_data->FormatHandle(device).c_str(),
236 report_data->FormatHandle(ObjTrackStateTypedHandle(*object_info)).c_str());
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000237 }
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600238 return skip;
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000239}
240
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600241void ObjectLifetimes::DeviceDestroyUndestroyedObjects(VkDevice device, VulkanObjectType object_type) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600242 while (!object_map[object_type].empty()) {
243 auto item = object_map[object_type].begin();
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000244
245 ObjTrackState *object_info = item->second;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600246 DestroyObjectSilently(object_info->handle, object_type);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600247 }
248}
249
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600250bool ObjectLifetimes::PreCallValidateDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600251 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500252 auto lock = read_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600253
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600254 // 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 -0600255 skip |= ValidateObject(instance, instance, kVulkanObjectTypeInstance, true, "VUID-vkDestroyInstance-instance-parameter",
256 kVUIDUndefined);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600257
258 // Validate that child devices have been destroyed
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600259 for (const auto &iit : object_map[kVulkanObjectTypeDevice]) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600260 ObjTrackState *pNode = iit.second;
261
262 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
263 VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[pNode->object_type];
264
John Zulauf1c3844a2019-04-01 17:39:48 -0600265 skip |=
266 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, pNode->handle, kVUID_ObjectTracker_ObjectLeak,
267 "OBJ ERROR : %s object %s has not been destroyed.", string_VkDebugReportObjectTypeEXT(debug_object_type),
268 report_data->FormatHandle(ObjTrackStateTypedHandle(*pNode)).c_str());
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600269
270 // Report any remaining objects in LL
271 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyInstance-instance-00629");
272
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600273 skip |= ValidateDestroyObject(instance, device, kVulkanObjectTypeDevice, pAllocator,
274 "VUID-vkDestroyInstance-instance-00630", "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600275 }
276
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600277 ValidateDestroyObject(instance, instance, kVulkanObjectTypeInstance, pAllocator, "VUID-vkDestroyInstance-instance-00630",
278 "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600279
280 return skip;
281}
282
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600283bool ObjectLifetimes::PreCallValidateEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
284 VkPhysicalDevice *pPhysicalDevices) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500285 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600286 bool skip = ValidateObject(instance, instance, kVulkanObjectTypeInstance, false,
287 "VUID-vkEnumeratePhysicalDevices-instance-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600288 return skip;
289}
290
291void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700292 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
293 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500294 auto lock = write_shared_lock();
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600295 if (pPhysicalDevices) {
296 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600297 CreateObject(instance, pPhysicalDevices[i], kVulkanObjectTypePhysicalDevice, nullptr);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600298 }
299 }
300}
301
302void ObjectLifetimes::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500303 auto lock = write_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600304 // Destroy physical devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600305 for (auto iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
306 iit != object_map[kVulkanObjectTypePhysicalDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600307 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600308 VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(pNode->handle);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600309 RecordDestroyObject(instance, physical_device, kVulkanObjectTypePhysicalDevice);
310 iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600311 }
312
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700313 // Destroy child devices
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600314 for (auto iit = object_map[kVulkanObjectTypeDevice].begin(); iit != object_map[kVulkanObjectTypeDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600315 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600316 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000317 DestroyUndestroyedObjects(device);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700318
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600319 RecordDestroyObject(instance, device, kVulkanObjectTypeDevice);
320 iit = object_map[kVulkanObjectTypeDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600321 }
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700322
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600323 object_map[kVulkanObjectTypeDevice].clear();
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600324}
325
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600326void ObjectLifetimes::PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500327 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600328 RecordDestroyObject(instance, instance, kVulkanObjectTypeInstance);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600329}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600330
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600331bool ObjectLifetimes::PreCallValidateDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600332 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500333 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600334 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, true, "VUID-vkDestroyDevice-device-parameter", kVUIDUndefined);
335 skip |= ValidateDestroyObject(physical_device, device, kVulkanObjectTypeDevice, pAllocator, "VUID-vkDestroyDevice-device-00379",
336 "VUID-vkDestroyDevice-device-00380");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600337 // Report any remaining objects associated with this VkDevice object in LL
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600338 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyDevice-device-00378");
339
340 return skip;
341}
342
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600343void ObjectLifetimes::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500344 auto lock = write_shared_lock();
Mark Lobodzinski52db2352018-12-28 09:41:15 -0700345 auto instance_data = GetLayerDataPtr(get_dispatch_key(physical_device), layer_data_map);
346 ValidationObject *validation_data = GetValidationObject(instance_data->object_dispatch, LayerObjectTypeObjectTracker);
347 ObjectLifetimes *object_lifetimes = static_cast<ObjectLifetimes *>(validation_data);
348 object_lifetimes->RecordDestroyObject(physical_device, device, kVulkanObjectTypeDevice);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000349 DestroyUndestroyedObjects(device);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600350
351 // Clean up Queue's MemRef Linked Lists
352 DestroyQueueDataStructures(device);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600353}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600354
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600355bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
356 VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600357 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500358 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600359 skip |=
360 ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue-device-parameter", kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600361 return skip;
362}
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600363
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600364void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
365 VkQueue *pQueue) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500366 auto lock = write_shared_lock();
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600367 CreateQueue(device, *pQueue);
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600368}
369
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600370bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500371 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600372 return ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue2-device-parameter",
373 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600374}
375
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600376void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500377 auto lock = write_shared_lock();
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600378 CreateQueue(device, *pQueue);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600379}
380
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600381bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
382 const VkWriteDescriptorSet *pDescriptorWrites,
383 uint32_t descriptorCopyCount,
384 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600385 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500386 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600387 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkUpdateDescriptorSets-device-parameter",
388 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600389 if (pDescriptorCopies) {
390 for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
391 if (pDescriptorCopies[idx0].dstSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600392 skip |= ValidateObject(device, pDescriptorCopies[idx0].dstSet, kVulkanObjectTypeDescriptorSet, false,
393 "VUID-VkCopyDescriptorSet-dstSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600394 }
395 if (pDescriptorCopies[idx0].srcSet) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600396 skip |= ValidateObject(device, pDescriptorCopies[idx0].srcSet, kVulkanObjectTypeDescriptorSet, false,
397 "VUID-VkCopyDescriptorSet-srcSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600398 }
399 }
400 }
401 if (pDescriptorWrites) {
402 for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
403 skip |= ValidateDescriptorWrite(device, &pDescriptorWrites[idx1], false);
404 }
405 }
406 return skip;
407}
408
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600409bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
410 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600411 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500412 auto lock = read_shared_lock();
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600413
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600414 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter",
415 kVUIDUndefined);
416 skip |=
417 ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
418 "VUID-vkResetDescriptorPool-descriptorPool-parameter", "VUID-vkResetDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600419
420 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
421 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
422 ObjTrackState *pPoolNode = itr->second;
423 for (auto set : *pPoolNode->child_objects) {
424 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
425 kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600426 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600427 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600428 return skip;
429}
430
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600431void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
432 VkDescriptorPoolResetFlags flags) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500433 auto lock = write_shared_lock();
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600434 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
435 // our descriptorSet map.
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600436 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
437 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
438 ObjTrackState *pPoolNode = itr->second;
439 for (auto set : *pPoolNode->child_objects) {
440 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600441 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600442 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600443 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600444}
445
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600446bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
447 const VkCommandBufferBeginInfo *begin_info) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600448 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500449 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600450 skip |= ValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
451 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600452 if (begin_info) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600453 ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600454 if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
455 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600456 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
457 "VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
458 skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
459 "VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600460 }
461 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600462 return skip;
463}
464
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600465bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
466 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600467 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500468 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600469 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
470 "VUID-vkGetSwapchainImagesKHR-commonparent");
471 skip |= ValidateObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, false,
472 "VUID-vkGetSwapchainImagesKHR-swapchain-parameter", "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600473 return skip;
474}
475
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600476void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700477 VkImage *pSwapchainImages, VkResult result) {
478 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500479 auto lock = write_shared_lock();
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600480 if (pSwapchainImages != NULL) {
481 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
482 CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
483 }
484 }
485}
486
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600487bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
488 const VkAllocationCallbacks *pAllocator,
489 VkDescriptorSetLayout *pSetLayout) {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100490 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500491 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600492 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateDescriptorSetLayout-device-parameter",
493 kVUIDUndefined);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600494 if (pCreateInfo) {
495 if (pCreateInfo->pBindings) {
496 for (uint32_t binding_index = 0; binding_index < pCreateInfo->bindingCount; ++binding_index) {
497 const VkDescriptorSetLayoutBinding &binding = pCreateInfo->pBindings[binding_index];
498 const bool is_sampler_type = binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
499 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
500 if (binding.pImmutableSamplers && is_sampler_type) {
501 for (uint32_t index2 = 0; index2 < binding.descriptorCount; ++index2) {
502 const VkSampler sampler = binding.pImmutableSamplers[index2];
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600503 skip |= ValidateObject(device, sampler, kVulkanObjectTypeSampler, false,
504 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100505 }
506 }
507 }
508 }
509 }
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600510 return skip;
511}
512
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600513void ObjectLifetimes::PostCallRecordCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
514 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700515 VkDescriptorSetLayout *pSetLayout, VkResult result) {
516 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500517 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600518 CreateObject(device, *pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600519}
520
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600521bool ObjectLifetimes::ValidateSamplerObjects(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo) {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600522 bool skip = false;
523 if (pCreateInfo->pBindings) {
524 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
525 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
526 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600527 skip |=
528 ValidateObject(device, pCreateInfo->pBindings[index1].pImmutableSamplers[index2], kVulkanObjectTypeSampler,
529 true, "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600530 }
531 }
532 }
533 }
534 return skip;
535}
536
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600537bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(VkDevice device,
538 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
539 VkDescriptorSetLayoutSupport *pSupport) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500540 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600541 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
542 "VUID-vkGetDescriptorSetLayoutSupport-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600543 if (pCreateInfo) {
544 skip |= ValidateSamplerObjects(device, pCreateInfo);
545 }
546 return skip;
547}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600548bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
549 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
550 VkDescriptorSetLayoutSupport *pSupport) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500551 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600552 bool skip = ValidateObject(device, device, kVulkanObjectTypeDevice, false,
553 "VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600554 if (pCreateInfo) {
555 skip |= ValidateSamplerObjects(device, pCreateInfo);
556 }
557 return skip;
558}
559
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600560bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
561 uint32_t *pQueueFamilyPropertyCount,
562 VkQueueFamilyProperties *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500563 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600564 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
565 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600566}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600567
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600568void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
569 uint32_t *pQueueFamilyPropertyCount,
Jeff Bolz6d243112019-08-21 13:24:11 -0500570 VkQueueFamilyProperties *pQueueFamilyProperties) {}
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600571
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600572void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700573 VkInstance *pInstance, VkResult result) {
574 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500575 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600576 CreateObject(*pInstance, *pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600577}
578
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600579bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
580 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600581 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500582 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600583 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter",
584 kVUIDUndefined);
585 skip |= ValidateObject(device, pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
586 "VUID-VkCommandBufferAllocateInfo-commandPool-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600587 return skip;
588}
589
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600590void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700591 VkCommandBuffer *pCommandBuffers, VkResult result) {
592 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500593 auto lock = write_shared_lock();
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600594 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
595 AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
596 }
597}
598
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600599bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
600 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600601 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500602 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600603 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
604 kVUIDUndefined);
605 skip |= ValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
606 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
607 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600608 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600609 skip |= ValidateObject(device, pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
610 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
611 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600612 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600613 return skip;
614}
615
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600616void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700617 VkDescriptorSet *pDescriptorSets, VkResult result) {
618 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500619 auto lock = write_shared_lock();
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600620 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
621 AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600622 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600623}
624
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600625bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
626 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600627 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500628 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600629 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter",
630 kVUIDUndefined);
631 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, false,
632 "VUID-vkFreeCommandBuffers-commandPool-parameter", "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600633 for (uint32_t i = 0; i < commandBufferCount; i++) {
634 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
635 skip |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600636 skip |= ValidateDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined,
637 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600638 }
639 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600640 return skip;
641}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600642
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600643void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
644 const VkCommandBuffer *pCommandBuffers) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500645 auto lock = write_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600646 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600647 RecordDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600648 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600649}
650
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600651bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
652 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500653 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600654 return ValidateDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator,
655 "VUID-vkDestroySwapchainKHR-swapchain-01283", "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600656}
657
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600658void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
659 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500660 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600661 RecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
662 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = swapchainImageMap.begin();
663 while (itr != swapchainImageMap.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600664 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600665 if (pNode->parent_object == HandleToUint64(swapchain)) {
666 delete pNode;
667 auto delete_item = itr++;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600668 swapchainImageMap.erase(delete_item);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600669 } else {
670 ++itr;
671 }
672 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600673}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600674
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600675bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
676 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500677 auto lock = read_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600678 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600679 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
680 kVUIDUndefined);
681 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
682 "VUID-vkFreeDescriptorSets-descriptorPool-parameter", "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600683 for (uint32_t i = 0; i < descriptorSetCount; i++) {
684 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
685 skip |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600686 skip |= ValidateDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, 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 Lobodzinski0c668462018-09-27 10:13:19 -0600692void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
693 const VkDescriptorSet *pDescriptorSets) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500694 auto lock = write_shared_lock();
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600695 ObjTrackState *pPoolNode = nullptr;
696 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
697 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
698 pPoolNode = itr->second;
699 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600700 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600701 RecordDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600702 if (pPoolNode) {
703 pPoolNode->child_objects->erase(HandleToUint64(pDescriptorSets[i]));
704 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600705 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600706}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600707
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600708bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
709 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500710 auto lock = read_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600711 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600712 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
713 kVUIDUndefined);
714 skip |= ValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, true,
715 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
716 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600717
718 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
719 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
720 ObjTrackState *pPoolNode = itr->second;
721 for (auto set : *pPoolNode->child_objects) {
722 skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
723 kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600724 }
725 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600726 skip |= ValidateDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
727 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
728 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600729 return skip;
730}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600731void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
732 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500733 auto lock = write_shared_lock();
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600734 auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
735 if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
736 ObjTrackState *pPoolNode = itr->second;
737 for (auto set : *pPoolNode->child_objects) {
738 RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600739 }
Jeff Bolzcf802bc2019-02-10 00:18:00 -0600740 pPoolNode->child_objects->clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600741 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600742 RecordDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600743}
744
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600745bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
746 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500747 auto lock = read_shared_lock();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600748 bool skip = false;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600749 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter",
750 kVUIDUndefined);
751 skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
752 "VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
753 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600754 auto del_itr = itr;
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600755 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600756 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600757 del_itr = itr++;
758 if (pNode->parent_object == HandleToUint64(commandPool)) {
759 skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600760 skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
761 kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600762 }
763 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600764 skip |= ValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
765 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600766 return skip;
767}
768
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600769void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
770 const VkAllocationCallbacks *pAllocator) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500771 auto lock = write_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600772 auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600773 auto del_itr = itr;
774 // 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 -0600775 while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600776 ObjTrackState *pNode = (*itr).second;
777 del_itr = itr++;
778 if (pNode->parent_object == HandleToUint64(commandPool)) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600779 RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600780 }
781 }
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600782 RecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600783}
784
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600785bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
786 uint32_t *pQueueFamilyPropertyCount,
787 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500788 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600789 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
790 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600791}
792
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600793bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
794 uint32_t *pQueueFamilyPropertyCount,
795 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500796 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600797 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
Shannon McPherson3ea65132018-12-05 10:37:39 -0700798 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600799}
800
801void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
802 uint32_t *pQueueFamilyPropertyCount,
Jeff Bolz6d243112019-08-21 13:24:11 -0500803 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {}
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600804
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600805void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
Jeff Bolz6d243112019-08-21 13:24:11 -0500806 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {}
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600807
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600808bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
809 uint32_t *pPropertyCount,
810 VkDisplayPropertiesKHR *pProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500811 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600812 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
813 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600814}
815
816void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700817 VkDisplayPropertiesKHR *pProperties, VkResult result) {
818 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500819 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600820 if (pProperties) {
821 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600822 CreateObject(physicalDevice, pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600823 }
824 }
825}
826
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600827bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
828 uint32_t *pPropertyCount,
829 VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600830 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500831 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600832 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
833 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
834 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
835 "VUID-vkGetDisplayModePropertiesKHR-display-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600836
837 return skip;
838}
839
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600840void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700841 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties,
842 VkResult result) {
843 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500844 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600845 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600846 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600847 CreateObject(physicalDevice, pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600848 }
849 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600850}
851
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600852bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
853 uint32_t *pPropertyCount,
854 VkDisplayProperties2KHR *pProperties) {
Jeff Bolzc31aae42019-08-12 20:29:43 -0500855 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600856 return ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
857 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600858}
859
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600860void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
861 uint32_t *pPropertyCount,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700862 VkDisplayProperties2KHR *pProperties, VkResult result) {
863 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500864 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600865 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600866 CreateObject(physicalDevice, pProperties[index].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600867 }
868}
869
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600870bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
871 uint32_t *pPropertyCount,
872 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600873 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500874 auto lock = read_shared_lock();
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600875 skip |= ValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
876 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
877 skip |= ValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
878 "VUID-vkGetDisplayModeProperties2KHR-display-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600879
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600880 return skip;
881}
882
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600883void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700884 uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties,
885 VkResult result) {
886 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500887 auto lock = write_shared_lock();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600888 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskiadd93232018-10-09 11:49:42 -0600889 CreateObject(physicalDevice, pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR,
890 nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600891 }
892}
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600893
894bool ObjectLifetimes::PreCallValidateAcquirePerformanceConfigurationINTEL(
895 VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL *pAcquireInfo,
896 VkPerformanceConfigurationINTEL *pConfiguration) {
897 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500898 auto lock = read_shared_lock();
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600899 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false,
900 "VUID-vkAcquirePerformanceConfigurationINTEL-device-parameter", kVUIDUndefined);
901
902 return skip;
903}
904
905bool ObjectLifetimes::PreCallValidateReleasePerformanceConfigurationINTEL(VkDevice device,
906 VkPerformanceConfigurationINTEL configuration) {
907 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500908 auto lock = read_shared_lock();
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600909 skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false,
910 "VUID-vkReleasePerformanceConfigurationINTEL-device-parameter", kVUIDUndefined);
911
912 return skip;
913}
914
915bool ObjectLifetimes::PreCallValidateQueueSetPerformanceConfigurationINTEL(VkQueue queue,
916 VkPerformanceConfigurationINTEL configuration) {
917 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500918 auto lock = read_shared_lock();
Shannon McPhersonf7d9cf62019-06-26 09:23:57 -0600919 skip |=
920 ValidateObject(queue, queue, kVulkanObjectTypeQueue, false, "VUID-vkQueueSetPerformanceConfigurationINTEL-queue-parameter",
921 "VUID-vkQueueSetPerformanceConfigurationINTEL-commonparent");
922
923 return skip;
924}
Tobias Hectorc9057422019-07-23 12:15:52 +0100925
926bool ObjectLifetimes::PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
927 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) {
928 bool skip = false;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500929 auto lock = read_shared_lock();
Tobias Hectorc9057422019-07-23 12:15:52 +0100930 skip |=
931 ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateFramebuffer-device-parameter", kVUIDUndefined);
932 if (pCreateInfo) {
933 skip |= ValidateObject(device, pCreateInfo->renderPass, kVulkanObjectTypeRenderPass, false,
934 "VUID-VkFramebufferCreateInfo-renderPass-parameter", "VUID-VkFramebufferCreateInfo-commonparent");
935 if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR) == 0) {
936 for (uint32_t index1 = 0; index1 < pCreateInfo->attachmentCount; ++index1) {
937 skip |= ValidateObject(device, pCreateInfo->pAttachments[index1], kVulkanObjectTypeImageView, true, kVUIDUndefined,
938 "VUID-VkFramebufferCreateInfo-commonparent");
939 }
940 }
941 }
942
943 return skip;
944}
945
946void ObjectLifetimes::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
947 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
948 VkResult result) {
949 if (result != VK_SUCCESS) return;
Jeff Bolzc31aae42019-08-12 20:29:43 -0500950 auto lock = write_shared_lock();
Tobias Hectorc9057422019-07-23 12:15:52 +0100951 CreateObject(device, *pFramebuffer, kVulkanObjectTypeFramebuffer, pAllocator);
952}