blob: 88f367e26af93146726dfcdef7127abb605ab2e8 [file] [log] [blame]
Dave Houltonb817a872018-06-26 13:22:01 -06001/* Copyright (c) 2015-2018 The Khronos Group Inc.
2 * Copyright (c) 2015-2018 Valve Corporation
3 * Copyright (c) 2015-2018 LunarG, Inc.
4 * Copyright (C) 2015-2018 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 Lobodzinski63902f02018-09-21 10:36:44 -060024#include "object_lifetime_validation.h"
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060025
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060026uint64_t object_track_index = 0;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060027
28// Add new queue to head of global queue list
Mark Lobodzinski0c668462018-09-27 10:13:19 -060029void ObjectLifetimes::AddQueueInfo(VkDevice device, uint32_t queue_node_index, VkQueue queue) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060030 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060031 auto queueItem = device_data->objdata.queue_info_map.find(queue);
32 if (queueItem == device_data->objdata.queue_info_map.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060033 ObjTrackQueueInfo *p_queue_info = new ObjTrackQueueInfo;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060034 if (p_queue_info != NULL) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060035 memset(p_queue_info, 0, sizeof(ObjTrackQueueInfo));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060036 p_queue_info->queue = queue;
37 p_queue_info->queue_node_index = queue_node_index;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060038 device_data->objdata.queue_info_map[queue] = p_queue_info;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060039 } else {
40 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -060041 HandleToUint64(queue), kVUID_ObjectTracker_InternalError,
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060042 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
43 }
44 }
45}
46
47// Destroy memRef lists and free all memory
Mark Lobodzinski0c668462018-09-27 10:13:19 -060048void ObjectLifetimes::DestroyQueueDataStructures(VkDevice device) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060049 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
50
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060051 for (auto queue_item : device_data->objdata.queue_info_map) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060052 delete queue_item.second;
53 }
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060054 device_data->objdata.queue_info_map.clear();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060055
56 // Destroy the items in the queue map
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060057 auto queue = device_data->objdata.object_map[kVulkanObjectTypeQueue].begin();
58 while (queue != device_data->objdata.object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060059 uint32_t obj_index = queue->second->object_type;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060060 assert(device_data->objdata.num_total_objects > 0);
61 device_data->objdata.num_total_objects--;
62 assert(device_data->objdata.num_objects[obj_index] > 0);
63 device_data->objdata.num_objects[obj_index]--;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060064 log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -060065 queue->second->handle, kVUID_ObjectTracker_Info,
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060066 "OBJ_STAT Destroy Queue obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " Queue objs).",
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060067 queue->second->handle, device_data->objdata.num_total_objects, device_data->objdata.num_objects[obj_index]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060068 delete queue->second;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060069 queue = device_data->objdata.object_map[kVulkanObjectTypeQueue].erase(queue);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060070 }
71}
72
73// Check Queue type flags for selected queue operations
Mark Lobodzinski0c668462018-09-27 10:13:19 -060074void ObjectLifetimes::ValidateQueueFlags(VkQueue queue, const char *function) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060075 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060076 auto queue_item = device_data->objdata.queue_info_map.find(queue);
77 if (queue_item != device_data->objdata.queue_info_map.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -060078 ObjTrackQueueInfo *pQueueInfo = queue_item->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060079 if (pQueueInfo != NULL) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060080 instance_layer_data *instance_data =
81 GetLayerDataPtr(get_dispatch_key(device_data->physical_device), instance_layer_data_map);
82 if ((instance_data->objdata.queue_family_properties[pQueueInfo->queue_node_index].queueFlags &
83 VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060084 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
Dave Houlton57ae22f2018-05-18 16:20:52 -060085 HandleToUint64(queue), "VUID-vkQueueBindSparse-queuetype",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060086 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set.", function);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060087 }
88 }
89 }
90}
91
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070092// Look for this device object in any of the instance child devices lists.
93// NOTE: This is of dubious value. In most circumstances Vulkan will die a flaming death if a dispatchable object is invalid.
94// However, if this layer is loaded first and GetProcAddress is used to make API calls, it will detect bad DOs.
Mark Lobodzinski0c668462018-09-27 10:13:19 -060095bool ObjectLifetimes::ValidateDeviceObject(uint64_t device_handle, const std::string &invalid_handle_code,
96 const std::string &wrong_device_code) {
Mark Lobodzinski9bd81192017-11-13 09:38:23 -070097 VkInstance last_instance = nullptr;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -060098 for (auto instance_data : instance_layer_data_map) {
99 for (auto object : instance_data.second->objdata.object_map[kVulkanObjectTypeDevice]) {
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700100 // Grab last instance to use for possible error message
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600101 last_instance = instance_data.second->instance;
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700102 if (object.second->handle == device_handle) return false;
103 }
104 }
105
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600106 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(last_instance), instance_layer_data_map);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700107 return log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device_handle,
Mark Lobodzinski88529492018-04-01 10:38:15 -0600108 invalid_handle_code, "Invalid Device Object 0x%" PRIxLEAST64 ".", device_handle);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700109}
110
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600111void ObjectLifetimes::AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
112 VkCommandBufferLevel level) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600113 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
114
115 log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -0600116 HandleToUint64(command_buffer), kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600117 object_track_index++, "VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT", HandleToUint64(command_buffer));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600118
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600119 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600120 pNewObjNode->object_type = kVulkanObjectTypeCommandBuffer;
121 pNewObjNode->handle = HandleToUint64(command_buffer);
122 pNewObjNode->parent_object = HandleToUint64(command_pool);
123 if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
124 pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
125 } else {
126 pNewObjNode->status = OBJSTATUS_NONE;
127 }
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600128 device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)] = pNewObjNode;
129 device_data->objdata.num_objects[kVulkanObjectTypeCommandBuffer]++;
130 device_data->objdata.num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600131}
132
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600133bool ObjectLifetimes::ValidateCommandBuffer(VkDevice device, VkCommandPool command_pool, VkCommandBuffer command_buffer) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600134 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
135 bool skip = false;
136 uint64_t object_handle = HandleToUint64(command_buffer);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600137 if (device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer].find(object_handle) !=
138 device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer].end()) {
139 ObjTrackState *pNode = device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600140
141 if (pNode->parent_object != HandleToUint64(command_pool)) {
142 skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton57ae22f2018-05-18 16:20:52 -0600143 object_handle, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent",
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600144 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600145 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
146 HandleToUint64(command_buffer), pNode->parent_object, HandleToUint64(command_pool));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600147 }
148 } else {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600149 skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton57ae22f2018-05-18 16:20:52 -0600150 object_handle, "VUID-vkFreeCommandBuffers-pCommandBuffers-00048", "Invalid %s Object 0x%" PRIxLEAST64 ".",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600151 object_string[kVulkanObjectTypeCommandBuffer], object_handle);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600152 }
153 return skip;
154}
155
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600156void ObjectLifetimes::AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600157 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
158
159 log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -0600160 HandleToUint64(descriptor_set), kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600161 object_track_index++, "VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT", HandleToUint64(descriptor_set));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600162
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600163 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600164 pNewObjNode->object_type = kVulkanObjectTypeDescriptorSet;
165 pNewObjNode->status = OBJSTATUS_NONE;
166 pNewObjNode->handle = HandleToUint64(descriptor_set);
167 pNewObjNode->parent_object = HandleToUint64(descriptor_pool);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600168 device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet][HandleToUint64(descriptor_set)] = pNewObjNode;
169 device_data->objdata.num_objects[kVulkanObjectTypeDescriptorSet]++;
170 device_data->objdata.num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600171}
172
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600173bool ObjectLifetimes::ValidateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600174 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
175 bool skip = false;
176 uint64_t object_handle = HandleToUint64(descriptor_set);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600177 auto dsItem = device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].find(object_handle);
178 if (dsItem != device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600179 ObjTrackState *pNode = dsItem->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600180
181 if (pNode->parent_object != HandleToUint64(descriptor_pool)) {
182 skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
Dave Houlton57ae22f2018-05-18 16:20:52 -0600183 object_handle, "VUID-vkFreeDescriptorSets-pDescriptorSets-parent",
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600184 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600185 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
186 HandleToUint64(descriptor_set), pNode->parent_object, HandleToUint64(descriptor_pool));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600187 }
188 } else {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600189 skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
Dave Houlton57ae22f2018-05-18 16:20:52 -0600190 object_handle, "VUID-vkFreeDescriptorSets-pDescriptorSets-00310", "Invalid %s Object 0x%" PRIxLEAST64 ".",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600191 object_string[kVulkanObjectTypeDescriptorSet], object_handle);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600192 }
193 return skip;
194}
195
Dave Houltona9df0ce2018-02-07 10:51:23 -0700196template <typename DispObj>
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600197bool ObjectLifetimes::ValidateDescriptorWrite(DispObj disp, VkWriteDescriptorSet const *desc, bool isPush) {
Chris Forbes2c600e92017-10-20 11:13:20 -0700198 bool skip = false;
199
200 if (!isPush && desc->dstSet) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600201 skip |= DeviceValidateObject(disp, desc->dstSet, kVulkanObjectTypeDescriptorSet, false,
202 "VUID-VkWriteDescriptorSet-dstSet-00320", "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700203 }
204
205 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
206 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
207 for (uint32_t idx2 = 0; idx2 < desc->descriptorCount; ++idx2) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600208 skip |=
209 DeviceValidateObject(disp, desc->pTexelBufferView[idx2], kVulkanObjectTypeBufferView, false,
210 "VUID-VkWriteDescriptorSet-descriptorType-00323", "VUID-VkWriteDescriptorSet-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700211 }
212 }
213
214 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
Dave Houltona9df0ce2018-02-07 10:51:23 -0700215 (desc->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
Chris Forbes2c600e92017-10-20 11:13:20 -0700216 (desc->descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
217 for (uint32_t idx3 = 0; idx3 < desc->descriptorCount; ++idx3) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600218 skip |=
219 DeviceValidateObject(disp, desc->pImageInfo[idx3].imageView, kVulkanObjectTypeImageView, false,
220 "VUID-VkWriteDescriptorSet-descriptorType-00326", "VUID-VkDescriptorImageInfo-commonparent");
Chris Forbes2c600e92017-10-20 11:13:20 -0700221 }
222 }
223
224 if ((desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
225 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
226 (desc->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
227 (desc->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
228 for (uint32_t idx4 = 0; idx4 < desc->descriptorCount; ++idx4) {
229 if (desc->pBufferInfo[idx4].buffer) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600230 skip |= DeviceValidateObject(disp, desc->pBufferInfo[idx4].buffer, kVulkanObjectTypeBuffer, false,
231 "VUID-VkDescriptorBufferInfo-buffer-parameter", kVUIDUndefined);
Chris Forbes2c600e92017-10-20 11:13:20 -0700232 }
233 }
234 }
235
236 return skip;
237}
238
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600239bool ObjectLifetimes::PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
240 VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
241 const VkWriteDescriptorSet *pDescriptorWrites) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600242 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600243 skip |= DeviceValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false,
244 "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-parameter",
245 "VUID-vkCmdPushDescriptorSetKHR-commonparent");
246 skip |= DeviceValidateObject(commandBuffer, layout, kVulkanObjectTypePipelineLayout, false,
247 "VUID-vkCmdPushDescriptorSetKHR-layout-parameter", "VUID-vkCmdPushDescriptorSetKHR-commonparent");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600248 if (pDescriptorWrites) {
249 for (uint32_t index0 = 0; index0 < descriptorWriteCount; ++index0) {
250 skip |= ValidateDescriptorWrite(commandBuffer, &pDescriptorWrites[index0], true);
251 }
252 }
253 return skip;
254}
255
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600256void ObjectLifetimes::CreateQueue(VkDevice device, VkQueue vkObj) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600257 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
258
259 log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -0600260 HandleToUint64(vkObj), kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64,
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600261 object_track_index++, "VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT", HandleToUint64(vkObj));
262
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600263 ObjTrackState *p_obj_node = NULL;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600264 auto queue_item = device_data->objdata.object_map[kVulkanObjectTypeQueue].find(HandleToUint64(vkObj));
265 if (queue_item == device_data->objdata.object_map[kVulkanObjectTypeQueue].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600266 p_obj_node = new ObjTrackState;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600267 device_data->objdata.object_map[kVulkanObjectTypeQueue][HandleToUint64(vkObj)] = p_obj_node;
268 device_data->objdata.num_objects[kVulkanObjectTypeQueue]++;
269 device_data->objdata.num_total_objects++;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600270 } else {
271 p_obj_node = queue_item->second;
272 }
273 p_obj_node->object_type = kVulkanObjectTypeQueue;
274 p_obj_node->status = OBJSTATUS_NONE;
275 p_obj_node->handle = HandleToUint64(vkObj);
276}
277
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600278void ObjectLifetimes::CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600279 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(dispatchable_object), layer_data_map);
280 log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Dave Houltonb817a872018-06-26 13:22:01 -0600281 HandleToUint64(swapchain_image), kVUID_ObjectTracker_Info, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600282 object_track_index++, "SwapchainImage", HandleToUint64(swapchain_image));
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600283
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600284 ObjTrackState *pNewObjNode = new ObjTrackState;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600285 pNewObjNode->object_type = kVulkanObjectTypeImage;
286 pNewObjNode->status = OBJSTATUS_NONE;
287 pNewObjNode->handle = HandleToUint64(swapchain_image);
288 pNewObjNode->parent_object = HandleToUint64(swapchain);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600289 device_data->objdata.swapchainImageMap[HandleToUint64(swapchain_image)] = pNewObjNode;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600290}
291
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600292bool ObjectLifetimes::DeviceReportUndestroyedObjects(VkDevice device, VulkanObjectType object_type, const std::string &error_code) {
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600293 bool skip = false;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600294 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600295 for (const auto &item : device_data->objdata.object_map[object_type]) {
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000296 const ObjTrackState *object_info = item.second;
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600297 skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type],
298 object_info->handle, error_code,
299 "OBJ ERROR : For device 0x%" PRIxLEAST64 ", %s object 0x%" PRIxLEAST64 " has not been destroyed.",
300 HandleToUint64(device), object_string[object_type], object_info->handle);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000301 }
Mark Lobodzinski5183a032018-09-13 14:44:28 -0600302 return skip;
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000303}
304
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600305void ObjectLifetimes::DeviceDestroyUndestroyedObjects(VkDevice device, VulkanObjectType object_type) {
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000306 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600307 while (!device_data->objdata.object_map[object_type].empty()) {
308 auto item = device_data->objdata.object_map[object_type].begin();
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000309
310 ObjTrackState *object_info = item->second;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600311 DestroyObjectSilently(&device_data->objdata, object_info->handle, object_type);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600312 }
313}
314
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600315bool ObjectLifetimes::PreCallValidateDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600316 dispatch_key key = get_dispatch_key(instance);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600317 instance_layer_data *instance_data = GetLayerDataPtr(key, instance_layer_data_map);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600318 bool skip = false;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600319
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600320 // We validate here for coverage, though we'd not have made it this for with a bad instance.
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600321 skip |= InstanceValidateObject(instance, instance, kVulkanObjectTypeInstance, true, "VUID-vkDestroyInstance-instance-parameter",
322 kVUIDUndefined);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600323
324 // Validate that child devices have been destroyed
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600325 for (const auto &iit : instance_data->objdata.object_map[kVulkanObjectTypeDevice]) {
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600326 ObjTrackState *pNode = iit.second;
327
328 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
329 VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[pNode->object_type];
330
331 skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, pNode->handle,
332 kVUID_ObjectTracker_ObjectLeak, "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.",
333 string_VkDebugReportObjectTypeEXT(debug_object_type), pNode->handle);
334
335 // Report any remaining objects in LL
336 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyInstance-instance-00629");
337
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600338 skip |= InstanceValidateDestroyObject(instance, device, kVulkanObjectTypeDevice, pAllocator,
339 "VUID-vkDestroyInstance-instance-00630", "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600340 }
341
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600342 InstanceValidateDestroyObject(instance, instance, kVulkanObjectTypeInstance, pAllocator,
343 "VUID-vkDestroyInstance-instance-00630", "VUID-vkDestroyInstance-instance-00631");
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600344
345 return skip;
346}
347
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600348bool ObjectLifetimes::PreCallValidateEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
349 VkPhysicalDevice *pPhysicalDevices) {
350 bool skip = InstanceValidateObject(instance, instance, kVulkanObjectTypeInstance, false,
351 "VUID-vkEnumeratePhysicalDevices-instance-parameter", kVUIDUndefined);
352 return skip;
353}
354
355void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
356 VkPhysicalDevice *pPhysicalDevices) {
357 if (pPhysicalDevices) {
358 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
359 InstanceCreateObject(instance, pPhysicalDevices[i], kVulkanObjectTypePhysicalDevice, nullptr);
360 }
361 }
362}
363
364void ObjectLifetimes::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600365 dispatch_key key = get_dispatch_key(instance);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600366 instance_layer_data *instance_data = GetLayerDataPtr(key, instance_layer_data_map);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600367
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600368 // Destroy physical devices
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600369 for (auto iit = instance_data->objdata.object_map[kVulkanObjectTypePhysicalDevice].begin();
370 iit != instance_data->objdata.object_map[kVulkanObjectTypePhysicalDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600371 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600372 VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(pNode->handle);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600373 InstanceRecordDestroyObject(instance, physical_device, kVulkanObjectTypePhysicalDevice);
374 iit = instance_data->objdata.object_map[kVulkanObjectTypePhysicalDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600375 }
376
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700377 // Destroy child devices
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600378 for (auto iit = instance_data->objdata.object_map[kVulkanObjectTypeDevice].begin();
379 iit != instance_data->objdata.object_map[kVulkanObjectTypeDevice].end();) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600380 ObjTrackState *pNode = iit->second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600381 VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000382 DestroyUndestroyedObjects(device);
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700383
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600384 InstanceRecordDestroyObject(instance, device, kVulkanObjectTypeDevice);
385 iit = instance_data->objdata.object_map[kVulkanObjectTypeDevice].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600386 }
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700387
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600388 instance_data->objdata.object_map[kVulkanObjectTypeDevice].clear();
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600389}
390
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600391void ObjectLifetimes::PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600392 InstanceRecordDestroyObject(instance, instance, kVulkanObjectTypeInstance);
Mark Lobodzinski34f5ea62018-09-14 09:51:43 -0600393}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600394
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600395bool ObjectLifetimes::PreCallValidateDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski9bd81192017-11-13 09:38:23 -0700396 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600397 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600398 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, true, "VUID-vkDestroyDevice-device-parameter",
399 kVUIDUndefined);
400 skip |= InstanceValidateDestroyObject(device_data->physical_device, device, kVulkanObjectTypeDevice, pAllocator,
401 "VUID-vkDestroyDevice-device-00379", "VUID-vkDestroyDevice-device-00380");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600402 // Report any remaining objects associated with this VkDevice object in LL
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600403 skip |= ReportUndestroyedObjects(device, "VUID-vkDestroyDevice-device-00378");
404
405 return skip;
406}
407
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600408void ObjectLifetimes::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600409 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600410 InstanceRecordDestroyObject(device_data->physical_device, device, kVulkanObjectTypeDevice);
Gabríel Arthúr Péturssonfdcb5402018-03-20 21:52:06 +0000411 DestroyUndestroyedObjects(device);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600412
413 // Clean up Queue's MemRef Linked Lists
414 DestroyQueueDataStructures(device);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600415}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600416
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600417bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
418 VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600419 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600420 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue-device-parameter",
421 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600422 return skip;
423}
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600424
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600425void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
426 VkQueue *pQueue) {
Mark Lobodzinski439645a2017-07-19 15:18:15 -0600427 CreateQueue(device, *pQueue);
428 AddQueueInfo(device, queueFamilyIndex, *pQueue);
429}
430
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600431bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600432 return DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetDeviceQueue2-device-parameter",
433 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600434}
435
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600436void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600437 CreateQueue(device, *pQueue);
438 AddQueueInfo(device, pQueueInfo->queueFamilyIndex, *pQueue);
439}
440
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600441bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
442 const VkWriteDescriptorSet *pDescriptorWrites,
443 uint32_t descriptorCopyCount,
444 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600445 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600446 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkUpdateDescriptorSets-device-parameter",
447 kVUIDUndefined);
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600448 if (pDescriptorCopies) {
449 for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
450 if (pDescriptorCopies[idx0].dstSet) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600451 skip |= DeviceValidateObject(device, pDescriptorCopies[idx0].dstSet, kVulkanObjectTypeDescriptorSet, false,
452 "VUID-VkCopyDescriptorSet-dstSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600453 }
454 if (pDescriptorCopies[idx0].srcSet) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600455 skip |= DeviceValidateObject(device, pDescriptorCopies[idx0].srcSet, kVulkanObjectTypeDescriptorSet, false,
456 "VUID-VkCopyDescriptorSet-srcSet-parameter", "VUID-VkCopyDescriptorSet-commonparent");
Mark Lobodzinskib58fe782018-09-14 11:50:27 -0600457 }
458 }
459 }
460 if (pDescriptorWrites) {
461 for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
462 skip |= ValidateDescriptorWrite(device, &pDescriptorWrites[idx1], false);
463 }
464 }
465 return skip;
466}
467
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600468bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
469 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600470 bool skip = false;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600471 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600472
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600473 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter",
474 kVUIDUndefined);
475 skip |= DeviceValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
476 "VUID-vkResetDescriptorPool-descriptorPool-parameter",
477 "VUID-vkResetDescriptorPool-descriptorPool-parent");
478 for (const auto &itr : device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet]) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600479 if (itr.second->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600480 skip |= DeviceValidateDestroyObject(device, (VkDescriptorSet)(itr.first), kVulkanObjectTypeDescriptorSet, nullptr,
481 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600482 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600483 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600484 return skip;
485}
486
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600487void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
488 VkDescriptorPoolResetFlags flags) {
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600489 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
490
491 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
492 // our descriptorSet map.
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600493 auto itr = device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].begin();
494 while (itr != device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600495 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600496 auto del_itr = itr++;
497 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600498 DeviceRecordDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600499 }
500 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600501}
502
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600503bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_buffer,
504 const VkCommandBufferBeginInfo *begin_info) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600505 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(command_buffer), layer_data_map);
506 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600507 skip |= DeviceValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
508 "VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600509 if (begin_info) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600510 ObjTrackState *pNode = device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600511 if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
512 (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600513 skip |= DeviceValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer,
514 true, "VUID-VkCommandBufferBeginInfo-flags-00055",
515 "VUID-VkCommandBufferInheritanceInfo-commonparent");
516 skip |= DeviceValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass,
517 false, "VUID-VkCommandBufferBeginInfo-flags-00053",
518 "VUID-VkCommandBufferInheritanceInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600519 }
520 }
Mark Lobodzinski0de500d2018-09-14 15:14:01 -0600521 return skip;
522}
523
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600524bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
525 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600526 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600527 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkGetSwapchainImagesKHR-device-parameter",
528 "VUID-vkGetSwapchainImagesKHR-commonparent");
529 skip |= DeviceValidateObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, false,
530 "VUID-vkGetSwapchainImagesKHR-swapchain-parameter", "VUID-vkGetSwapchainImagesKHR-commonparent");
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600531 return skip;
532}
533
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600534void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
535 VkImage *pSwapchainImages) {
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600536 if (pSwapchainImages != NULL) {
537 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
538 CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
539 }
540 }
541}
542
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600543bool ObjectLifetimes::PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
544 const VkAllocationCallbacks *pAllocator,
545 VkDescriptorSetLayout *pSetLayout) {
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100546 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600547 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false,
548 "VUID-vkCreateDescriptorSetLayout-device-parameter", kVUIDUndefined);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600549 if (pCreateInfo) {
550 if (pCreateInfo->pBindings) {
551 for (uint32_t binding_index = 0; binding_index < pCreateInfo->bindingCount; ++binding_index) {
552 const VkDescriptorSetLayoutBinding &binding = pCreateInfo->pBindings[binding_index];
553 const bool is_sampler_type = binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
554 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
555 if (binding.pImmutableSamplers && is_sampler_type) {
556 for (uint32_t index2 = 0; index2 < binding.descriptorCount; ++index2) {
557 const VkSampler sampler = binding.pImmutableSamplers[index2];
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600558 skip |= DeviceValidateObject(device, sampler, kVulkanObjectTypeSampler, false,
559 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Petr Kraus42f6f8d2017-12-17 17:37:33 +0100560 }
561 }
562 }
563 }
564 }
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600565 return skip;
566}
567
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600568void ObjectLifetimes::PostCallRecordCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
569 const VkAllocationCallbacks *pAllocator,
570 VkDescriptorSetLayout *pSetLayout) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600571 DeviceCreateObject(device, *pSetLayout, kVulkanObjectTypeDescriptorSetLayout, pAllocator);
Mark Lobodzinskibe4b3452018-09-14 16:14:33 -0600572}
573
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600574bool ObjectLifetimes::ValidateSamplerObjects(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo) {
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600575 bool skip = false;
576 if (pCreateInfo->pBindings) {
577 for (uint32_t index1 = 0; index1 < pCreateInfo->bindingCount; ++index1) {
578 for (uint32_t index2 = 0; index2 < pCreateInfo->pBindings[index1].descriptorCount; ++index2) {
579 if (pCreateInfo->pBindings[index1].pImmutableSamplers) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600580 skip |= DeviceValidateObject(device, pCreateInfo->pBindings[index1].pImmutableSamplers[index2],
581 kVulkanObjectTypeSampler, true,
582 "VUID-VkDescriptorSetLayoutBinding-descriptorType-00282", kVUIDUndefined);
Mark Lobodzinski88a1a662018-07-02 14:09:39 -0600583 }
584 }
585 }
586 }
587 return skip;
588}
589
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600590bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupport(VkDevice device,
591 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
592 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600593 bool skip = DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false,
594 "VUID-vkGetDescriptorSetLayoutSupport-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600595 if (pCreateInfo) {
596 skip |= ValidateSamplerObjects(device, pCreateInfo);
597 }
598 return skip;
599}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600600bool ObjectLifetimes::PreCallValidateGetDescriptorSetLayoutSupportKHR(VkDevice device,
601 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
602 VkDescriptorSetLayoutSupport *pSupport) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600603 bool skip = DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false,
604 "VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600605 if (pCreateInfo) {
606 skip |= ValidateSamplerObjects(device, pCreateInfo);
607 }
608 return skip;
609}
610
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600611bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
612 uint32_t *pQueueFamilyPropertyCount,
613 VkQueueFamilyProperties *pQueueFamilyProperties) {
614 return InstanceValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
615 "VUID-vkGetPhysicalDeviceQueueFamilyProperties-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600616}
Mark Lobodzinski63902f02018-09-21 10:36:44 -0600617
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600618void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
619 uint32_t *pQueueFamilyPropertyCount,
620 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600621 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600622 auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
623 if (instance_data->objdata.queue_family_properties.size() < *pQueueFamilyPropertyCount) {
624 instance_data->objdata.queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600625 }
626 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600627 instance_data->objdata.queue_family_properties[i] = pQueueFamilyProperties[i];
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600628 }
629 }
630}
631
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600632void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
633 VkInstance *pInstance) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600634 InstanceCreateObject(*pInstance, *pInstance, kVulkanObjectTypeInstance, pAllocator);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600635}
636
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600637bool ObjectLifetimes::PreCallValidateAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
638 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600639 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600640 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateCommandBuffers-device-parameter",
641 kVUIDUndefined);
642 skip |= DeviceValidateObject(device, pAllocateInfo->commandPool, kVulkanObjectTypeCommandPool, false,
643 "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,
648 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600649 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
650 AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], pAllocateInfo->level);
651 }
652}
653
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600654bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
655 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600656 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600657 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
658 kVUIDUndefined);
659 skip |= DeviceValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
660 "VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter",
661 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600662 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600663 skip |= DeviceValidateObject(device, pAllocateInfo->pSetLayouts[i], kVulkanObjectTypeDescriptorSetLayout, false,
664 "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter",
665 "VUID-VkDescriptorSetAllocateInfo-commonparent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600666 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600667 return skip;
668}
669
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600670void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
671 VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600672 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
673 AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600674 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600675}
676
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600677bool ObjectLifetimes::PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
678 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600679 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600680 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeCommandBuffers-device-parameter",
681 kVUIDUndefined);
682 skip |= DeviceValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, false,
683 "VUID-vkFreeCommandBuffers-commandPool-parameter", "VUID-vkFreeCommandBuffers-commandPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600684 for (uint32_t i = 0; i < commandBufferCount; i++) {
685 if (pCommandBuffers[i] != VK_NULL_HANDLE) {
686 skip |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600687 skip |= DeviceValidateDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined,
688 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600689 }
690 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600691 return skip;
692}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600693
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600694void ObjectLifetimes::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
695 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600696 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600697 DeviceRecordDestroyObject(device, pCommandBuffers[i], kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600698 }
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600699}
700
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600701bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
702 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600703 return DeviceValidateDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR, pAllocator,
704 "VUID-vkDestroySwapchainKHR-swapchain-01283", "VUID-vkDestroySwapchainKHR-swapchain-01284");
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600705}
706
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600707void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
708 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600709 DeviceRecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600710 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600711 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = device_data->objdata.swapchainImageMap.begin();
712 while (itr != device_data->objdata.swapchainImageMap.end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600713 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600714 if (pNode->parent_object == HandleToUint64(swapchain)) {
715 delete pNode;
716 auto delete_item = itr++;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600717 device_data->objdata.swapchainImageMap.erase(delete_item);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600718 } else {
719 ++itr;
720 }
721 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600722}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600723
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600724bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
725 uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600726 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600727 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
728 kVUIDUndefined);
729 skip |= DeviceValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, false,
730 "VUID-vkFreeDescriptorSets-descriptorPool-parameter",
731 "VUID-vkFreeDescriptorSets-descriptorPool-parent");
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600732 for (uint32_t i = 0; i < descriptorSetCount; i++) {
733 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
734 skip |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600735 skip |= DeviceValidateDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
736 kVUIDUndefined);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600737 }
738 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600739 return skip;
740}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600741void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
742 const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600743 for (uint32_t i = 0; i < descriptorSetCount; i++) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600744 DeviceRecordDestroyObject(device, pDescriptorSets[i], kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600745 }
Mark Lobodzinski1c7fa372018-09-17 11:35:00 -0600746}
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600747
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600748bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
749 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600750 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600751 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600752 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
753 kVUIDUndefined);
754 skip |= DeviceValidateObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, true,
755 "VUID-vkDestroyDescriptorPool-descriptorPool-parameter",
756 "VUID-vkDestroyDescriptorPool-descriptorPool-parent");
757 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr =
758 device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].begin();
759 while (itr != device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600760 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600761 auto del_itr = itr++;
762 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600763 skip |= DeviceValidateDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet,
764 nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600765 }
766 }
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600767 skip |= DeviceValidateDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool, pAllocator,
768 "VUID-vkDestroyDescriptorPool-descriptorPool-00304",
769 "VUID-vkDestroyDescriptorPool-descriptorPool-00305");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600770 return skip;
771}
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600772void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
773 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600774 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600775 std::unordered_map<uint64_t, ObjTrackState *>::iterator itr =
776 device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].begin();
777 while (itr != device_data->objdata.object_map[kVulkanObjectTypeDescriptorSet].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600778 ObjTrackState *pNode = (*itr).second;
779 auto del_itr = itr++;
780 if (pNode->parent_object == HandleToUint64(descriptorPool)) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600781 DeviceRecordDestroyObject(device, (VkDescriptorSet)((*del_itr).first), kVulkanObjectTypeDescriptorSet);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600782 }
783 }
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600784 DeviceRecordDestroyObject(device, descriptorPool, kVulkanObjectTypeDescriptorPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600785}
786
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600787bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
788 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600789 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
790 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600791 skip |= DeviceValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyCommandPool-device-parameter",
792 kVUIDUndefined);
793 skip |= DeviceValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
794 "VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
795 auto itr = device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600796 auto del_itr = itr;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600797 while (itr != device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskiefc64392017-07-18 13:15:47 -0600798 ObjTrackState *pNode = (*itr).second;
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600799 del_itr = itr++;
800 if (pNode->parent_object == HandleToUint64(commandPool)) {
801 skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600802 skip |= DeviceValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
803 kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600804 }
805 }
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600806 skip |=
807 DeviceValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
808 "VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600809 return skip;
810}
811
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600812void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
813 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600814 layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600815 auto itr = device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer].begin();
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600816 auto del_itr = itr;
817 // A CommandPool's cmd buffers are implicitly deleted when pool is deleted. Remove this pool's cmdBuffers from cmd buffer map.
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600818 while (itr != device_data->objdata.object_map[kVulkanObjectTypeCommandBuffer].end()) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600819 ObjTrackState *pNode = (*itr).second;
820 del_itr = itr++;
821 if (pNode->parent_object == HandleToUint64(commandPool)) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600822 DeviceRecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600823 }
824 }
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600825 DeviceRecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600826}
827
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600828bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
829 uint32_t *pQueueFamilyPropertyCount,
830 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600831 return InstanceValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
832 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600833}
834
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600835bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
836 uint32_t *pQueueFamilyPropertyCount,
837 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
838 return InstanceValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
839 "VUID-vkGetPhysicalDeviceQueueFamilyProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
840}
841
842void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
843 uint32_t *pQueueFamilyPropertyCount,
844 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600845 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600846 if (pQueueFamilyProperties != NULL) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600847 if (instance_data->objdata.queue_family_properties.size() < *pQueueFamilyPropertyCount) {
848 instance_data->objdata.queue_family_properties.resize(*pQueueFamilyPropertyCount);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600849 }
850 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600851 instance_data->objdata.queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600852 }
853 }
854}
855
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600856void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
857 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
858 instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
859 if (pQueueFamilyProperties != NULL) {
860 if (instance_data->objdata.queue_family_properties.size() < *pQueueFamilyPropertyCount) {
861 instance_data->objdata.queue_family_properties.resize(*pQueueFamilyPropertyCount);
862 }
863 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
864 instance_data->objdata.queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
865 }
866 }
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600867}
868
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600869bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
870 uint32_t *pPropertyCount,
871 VkDisplayPropertiesKHR *pProperties) {
872 return InstanceValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
873 "VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
874}
875
876void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
877 VkDisplayPropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600878 if (pProperties) {
879 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600880 InstanceCreateObject(physicalDevice, pProperties[i].display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -0600881 }
882 }
883}
884
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600885bool ObjectLifetimes::PreCallValidateGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
886 uint32_t *pPropertyCount,
887 VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600888 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600889 skip |= InstanceValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
890 "VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter", kVUIDUndefined);
891 skip |= InstanceValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
892 "VUID-vkGetDisplayModePropertiesKHR-display-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600893
894 return skip;
895}
896
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600897void ObjectLifetimes::PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
898 uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600899 if (pProperties) {
Tony-LunarGcd0c6b02018-10-26 14:56:44 -0600900 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600901 InstanceCreateObject(physicalDevice, pProperties[i].displayMode, kVulkanObjectTypeDisplayModeKHR, nullptr);
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600902 }
903 }
Shannon McPherson9d5167f2018-05-02 15:24:37 -0600904}
905
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600906bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
907 uint32_t *pPropertyCount,
908 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600909 return InstanceValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
910 "VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600911}
912
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600913void ObjectLifetimes::PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
914 uint32_t *pPropertyCount,
915 VkDisplayProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600916 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600917 InstanceCreateObject(physicalDevice, pProperties[index].displayProperties.display, kVulkanObjectTypeDisplayKHR, nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600918 }
919}
920
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600921bool ObjectLifetimes::PreCallValidateGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
922 uint32_t *pPropertyCount,
923 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600924 bool skip = false;
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600925 skip |= InstanceValidateObject(physicalDevice, physicalDevice, kVulkanObjectTypePhysicalDevice, false,
926 "VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter", kVUIDUndefined);
927 skip |= InstanceValidateObject(physicalDevice, display, kVulkanObjectTypeDisplayKHR, false,
928 "VUID-vkGetDisplayModeProperties2KHR-display-parameter", kVUIDUndefined);
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600929
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600930 return skip;
931}
932
Mark Lobodzinski0c668462018-09-27 10:13:19 -0600933void ObjectLifetimes::PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
934 uint32_t *pPropertyCount,
935 VkDisplayModeProperties2KHR *pProperties) {
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600936 for (uint32_t index = 0; index < *pPropertyCount; ++index) {
Mark Lobodzinskic3ff7a92018-09-20 11:05:57 -0600937 InstanceCreateObject(physicalDevice, pProperties[index].displayModeProperties.displayMode, kVulkanObjectTypeDisplayModeKHR,
938 nullptr);
Mark Lobodzinskia2e97362018-09-17 13:58:32 -0600939 }
940}