blob: a069b6b1e9db537f2550760f430d92746477cd8b [file] [log] [blame]
sfricke-samsung486a51e2021-01-02 00:10:15 -08001/* Copyright (c) 2015-2021 The Khronos Group Inc.
2 * Copyright (c) 2015-2021 Valve Corporation
3 * Copyright (c) 2015-2021 LunarG, Inc.
4 * Copyright (C) 2015-2021 Google Inc.
Tobias Hector6663c9b2020-11-05 10:18:02 +00005 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
locke-lunargd556cc32019-09-17 01:21:23 -06006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * Author: Mark Lobodzinski <mark@lunarg.com>
20 * Author: Dave Houlton <daveh@lunarg.com>
21 * Shannon McPherson <shannon@lunarg.com>
Tobias Hector6663c9b2020-11-05 10:18:02 +000022 * Author: Tobias Hector <tobias.hector@amd.com>
locke-lunargd556cc32019-09-17 01:21:23 -060023 */
24
David Zhao Akeley44139b12021-04-26 16:16:13 -070025#include <algorithm>
locke-lunargd556cc32019-09-17 01:21:23 -060026#include <cmath>
locke-lunargd556cc32019-09-17 01:21:23 -060027
28#include "vk_enum_string_helper.h"
29#include "vk_format_utils.h"
30#include "vk_layer_data.h"
31#include "vk_layer_utils.h"
32#include "vk_layer_logging.h"
33#include "vk_typemap_helper.h"
34
35#include "chassis.h"
36#include "state_tracker.h"
37#include "shader_validation.h"
Jeremy Gebben74aa7622020-12-15 11:18:00 -070038#include "sync_utils.h"
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060039#include "cmd_buffer_state.h"
40#include "render_pass_state.h"
locke-lunarg4189aa22020-10-21 00:23:48 -060041
Mark Lobodzinskib4ab6ac2020-04-02 13:12:06 -060042void ValidationStateTracker::InitDeviceValidationObject(bool add_obj, ValidationObject *inst_obj, ValidationObject *dev_obj) {
43 if (add_obj) {
44 instance_state = reinterpret_cast<ValidationStateTracker *>(GetValidationObject(inst_obj->object_dispatch, container_type));
45 // Call base class
46 ValidationObject::InitDeviceValidationObject(add_obj, inst_obj, dev_obj);
47 }
48}
49
John Zulauf2bc1fde2020-04-24 15:09:51 -060050// NOTE: Beware the lifespan of the rp_begin when holding the return. If the rp_begin isn't a "safe" copy, "IMAGELESS"
51// attachments won't persist past the API entry point exit.
Jeremy Gebben88f58142021-06-01 10:07:52 -060052static std::pair<uint32_t, const VkImageView *> GetFramebufferAttachments(const VkRenderPassBeginInfo &rp_begin,
53 const FRAMEBUFFER_STATE &fb_state) {
John Zulauf2bc1fde2020-04-24 15:09:51 -060054 const VkImageView *attachments = fb_state.createInfo.pAttachments;
55 uint32_t count = fb_state.createInfo.attachmentCount;
56 if (fb_state.createInfo.flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -070057 const auto *framebuffer_attachments = LvlFindInChain<VkRenderPassAttachmentBeginInfo>(rp_begin.pNext);
John Zulauf2bc1fde2020-04-24 15:09:51 -060058 if (framebuffer_attachments) {
59 attachments = framebuffer_attachments->pAttachments;
60 count = framebuffer_attachments->attachmentCount;
61 }
62 }
63 return std::make_pair(count, attachments);
64}
65
John Zulauf64ffe552021-02-06 10:25:07 -070066template <typename ImageViewPointer, typename Get>
67std::vector<ImageViewPointer> GetAttachmentViewsImpl(const VkRenderPassBeginInfo &rp_begin, const FRAMEBUFFER_STATE &fb_state,
68 const Get &get_fn) {
69 std::vector<ImageViewPointer> views;
John Zulauf2bc1fde2020-04-24 15:09:51 -060070
71 const auto count_attachment = GetFramebufferAttachments(rp_begin, fb_state);
72 const auto attachment_count = count_attachment.first;
73 const auto *attachments = count_attachment.second;
74 views.resize(attachment_count, nullptr);
75 for (uint32_t i = 0; i < attachment_count; i++) {
76 if (attachments[i] != VK_NULL_HANDLE) {
John Zulauf64ffe552021-02-06 10:25:07 -070077 views[i] = get_fn(attachments[i]);
John Zulauf2bc1fde2020-04-24 15:09:51 -060078 }
79 }
80 return views;
81}
82
John Zulauf64ffe552021-02-06 10:25:07 -070083std::vector<std::shared_ptr<const IMAGE_VIEW_STATE>> ValidationStateTracker::GetSharedAttachmentViews(
84 const VkRenderPassBeginInfo &rp_begin, const FRAMEBUFFER_STATE &fb_state) const {
85 auto get_fn = [this](VkImageView handle) { return this->GetShared<IMAGE_VIEW_STATE>(handle); };
86 return GetAttachmentViewsImpl<std::shared_ptr<const IMAGE_VIEW_STATE>>(rp_begin, fb_state, get_fn);
87}
88
locke-lunargd556cc32019-09-17 01:21:23 -060089#ifdef VK_USE_PLATFORM_ANDROID_KHR
90// Android-specific validation that uses types defined only with VK_USE_PLATFORM_ANDROID_KHR
91// This could also move into a seperate core_validation_android.cpp file... ?
92
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -060093template <typename CreateInfo>
94VkFormatFeatureFlags ValidationStateTracker::GetExternalFormatFeaturesANDROID(const CreateInfo *create_info) const {
95 VkFormatFeatureFlags format_features = 0;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -070096 const VkExternalFormatANDROID *ext_fmt_android = LvlFindInChain<VkExternalFormatANDROID>(create_info->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -060097 if (ext_fmt_android && (0 != ext_fmt_android->externalFormat)) {
Spencer Fricke6bba8c72020-04-06 07:41:21 -070098 // VUID 01894 will catch if not found in map
99 auto it = ahb_ext_formats_map.find(ext_fmt_android->externalFormat);
100 if (it != ahb_ext_formats_map.end()) {
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600101 format_features = it->second;
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700102 }
locke-lunargd556cc32019-09-17 01:21:23 -0600103 }
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600104 return format_features;
locke-lunargd556cc32019-09-17 01:21:23 -0600105}
106
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700107void ValidationStateTracker::PostCallRecordGetAndroidHardwareBufferPropertiesANDROID(
108 VkDevice device, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties, VkResult result) {
109 if (VK_SUCCESS != result) return;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700110 auto ahb_format_props = LvlFindInChain<VkAndroidHardwareBufferFormatPropertiesANDROID>(pProperties->pNext);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700111 if (ahb_format_props) {
Jeremy Gebbenfc6f8152021-03-18 16:58:55 -0600112 ahb_ext_formats_map.emplace(ahb_format_props->externalFormat, ahb_format_props->formatFeatures);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700113 }
114}
115
locke-lunargd556cc32019-09-17 01:21:23 -0600116#else
117
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600118template <typename CreateInfo>
119VkFormatFeatureFlags ValidationStateTracker::GetExternalFormatFeaturesANDROID(const CreateInfo *create_info) const {
120 return 0;
121}
locke-lunargd556cc32019-09-17 01:21:23 -0600122
123#endif // VK_USE_PLATFORM_ANDROID_KHR
124
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600125VkFormatFeatureFlags GetImageFormatFeatures(VkPhysicalDevice physical_device, VkDevice device, VkImage image, VkFormat format,
126 VkImageTiling tiling) {
127 VkFormatFeatureFlags format_features = 0;
Petr Kraus44f1c482020-04-25 20:09:25 +0200128 // Add feature support according to Image Format Features (vkspec.html#resources-image-format-features)
129 // if format is AHB external format then the features are already set
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600130 if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
131 VkImageDrmFormatModifierPropertiesEXT drm_format_properties = {VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
132 nullptr};
133 DispatchGetImageDrmFormatModifierPropertiesEXT(device, image, &drm_format_properties);
Petr Kraus44f1c482020-04-25 20:09:25 +0200134
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600135 VkFormatProperties2 format_properties_2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, nullptr};
136 VkDrmFormatModifierPropertiesListEXT drm_properties_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
137 nullptr};
138 format_properties_2.pNext = (void *)&drm_properties_list;
139 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
140 std::vector<VkDrmFormatModifierPropertiesEXT> drm_properties;
141 drm_properties.resize(drm_properties_list.drmFormatModifierCount);
142 drm_properties_list.pDrmFormatModifierProperties = &drm_properties[0];
143 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
Petr Kraus44f1c482020-04-25 20:09:25 +0200144
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600145 for (uint32_t i = 0; i < drm_properties_list.drmFormatModifierCount; i++) {
146 if (drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifier == drm_format_properties.drmFormatModifier) {
147 format_features = drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
148 break;
Petr Kraus44f1c482020-04-25 20:09:25 +0200149 }
Petr Kraus44f1c482020-04-25 20:09:25 +0200150 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600151 } else {
152 VkFormatProperties format_properties;
153 DispatchGetPhysicalDeviceFormatProperties(physical_device, format, &format_properties);
154 format_features =
155 (tiling == VK_IMAGE_TILING_LINEAR) ? format_properties.linearTilingFeatures : format_properties.optimalTilingFeatures;
Petr Kraus44f1c482020-04-25 20:09:25 +0200156 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600157 return format_features;
Petr Kraus44f1c482020-04-25 20:09:25 +0200158}
159
locke-lunargd556cc32019-09-17 01:21:23 -0600160void ValidationStateTracker::PostCallRecordCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
161 const VkAllocationCallbacks *pAllocator, VkImage *pImage, VkResult result) {
162 if (VK_SUCCESS != result) return;
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600163 VkFormatFeatureFlags format_features = 0;
locke-lunargd556cc32019-09-17 01:21:23 -0600164 if (device_extensions.vk_android_external_memory_android_hardware_buffer) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600165 format_features = GetExternalFormatFeaturesANDROID(pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -0600166 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600167 if (format_features == 0) {
168 format_features = GetImageFormatFeatures(physical_device, device, *pImage, pCreateInfo->format, pCreateInfo->tiling);
locke-lunargd556cc32019-09-17 01:21:23 -0600169 }
170
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600171 auto is_node = std::make_shared<IMAGE_STATE>(device, *pImage, pCreateInfo, format_features);
locke-lunargd556cc32019-09-17 01:21:23 -0600172 // Record the memory requirements in case they won't be queried
sfricke-samsung013f1ef2020-05-14 22:56:20 -0700173 // External AHB memory can't be queried until after memory is bound
Jeremy Gebben6fbf8242021-06-21 09:14:46 -0600174 if (is_node->IsExternalAHB() == false) {
sfricke-samsung71bc6572020-04-29 15:49:43 -0700175 if (is_node->disjoint == false) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -0600176 DispatchGetImageMemoryRequirements(device, *pImage, &is_node->requirements[0]);
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700177 } else {
178 uint32_t plane_count = FormatPlaneCount(pCreateInfo->format);
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600179 static const std::array<VkImageAspectFlagBits, 3> aspects{VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT,
180 VK_IMAGE_ASPECT_PLANE_2_BIT};
181 assert(plane_count <= aspects.size());
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700182 VkImagePlaneMemoryRequirementsInfo image_plane_req = {VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, nullptr};
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600183 VkImageMemoryRequirementsInfo2 mem_req_info2 = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, &image_plane_req,
184 *pImage};
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700185
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600186 for (uint32_t i = 0; i < plane_count; i++) {
187 VkMemoryRequirements2 mem_reqs2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, nullptr};
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700188
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600189 image_plane_req.planeAspect = aspects[i];
Jeremy Gebbenb9b07b62021-08-16 11:38:47 -0600190 switch (device_extensions.vk_khr_get_memory_requirements2) {
191 case kEnabledByApiLevel:
192 DispatchGetImageMemoryRequirements2(device, &mem_req_info2, &mem_reqs2);
193 break;
194 case kEnabledByCreateinfo:
195 DispatchGetImageMemoryRequirements2KHR(device, &mem_req_info2, &mem_reqs2);
196 break;
197 default:
198 // The VK_KHR_sampler_ycbcr_conversion extension requires VK_KHR_get_memory_requirements2,
199 // so validation of this vkCreateImage call should have already failed.
200 assert(false);
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600201 }
202 is_node->requirements[i] = mem_reqs2.memoryRequirements;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700203 }
204 }
locke-lunargd556cc32019-09-17 01:21:23 -0600205 }
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700206
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600207 imageMap[*pImage] = std::move(is_node);
locke-lunargd556cc32019-09-17 01:21:23 -0600208}
209
210void ValidationStateTracker::PreCallRecordDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
211 if (!image) return;
212 IMAGE_STATE *image_state = GetImageState(image);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600213 if (!image_state) return;
214
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600215 image_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600216 imageMap.erase(image);
217}
218
219void ValidationStateTracker::PreCallRecordCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
220 VkImageLayout imageLayout, const VkClearColorValue *pColor,
221 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600222
223 if (disabled[command_buffer_state]) return;
224
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600225 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600226 auto image_state = GetImageState(image);
227 if (cb_node && image_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600228 cb_node->AddChild(image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600229 }
230}
231
232void ValidationStateTracker::PreCallRecordCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
233 VkImageLayout imageLayout,
234 const VkClearDepthStencilValue *pDepthStencil,
235 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600236 if (disabled[command_buffer_state]) return;
237
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600238 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600239 auto image_state = GetImageState(image);
240 if (cb_node && image_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600241 cb_node->AddChild(image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600242 }
243}
244
245void ValidationStateTracker::PreCallRecordCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
246 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
247 uint32_t regionCount, const VkImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600248 if (disabled[command_buffer_state]) return;
249
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600250 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600251 auto src_image_state = GetImageState(srcImage);
252 auto dst_image_state = GetImageState(dstImage);
253
254 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600255 cb_node->AddChild(src_image_state);
256 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600257}
258
Jeff Leger178b1e52020-10-05 12:22:23 -0400259void ValidationStateTracker::PreCallRecordCmdCopyImage2KHR(VkCommandBuffer commandBuffer,
260 const VkCopyImageInfo2KHR *pCopyImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600261 if (disabled[command_buffer_state]) return;
262
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600263 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Leger178b1e52020-10-05 12:22:23 -0400264 auto src_image_state = GetImageState(pCopyImageInfo->srcImage);
265 auto dst_image_state = GetImageState(pCopyImageInfo->dstImage);
266
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600267 cb_node->AddChild(src_image_state);
268 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400269}
270
locke-lunargd556cc32019-09-17 01:21:23 -0600271void ValidationStateTracker::PreCallRecordCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
272 VkImageLayout srcImageLayout, VkImage dstImage,
273 VkImageLayout dstImageLayout, uint32_t regionCount,
274 const VkImageResolve *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600275 if (disabled[command_buffer_state]) return;
276
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600277 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600278 auto src_image_state = GetImageState(srcImage);
279 auto dst_image_state = GetImageState(dstImage);
280
281 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600282 cb_node->AddChild(src_image_state);
283 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600284}
285
Jeff Leger178b1e52020-10-05 12:22:23 -0400286void ValidationStateTracker::PreCallRecordCmdResolveImage2KHR(VkCommandBuffer commandBuffer,
287 const VkResolveImageInfo2KHR *pResolveImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600288 if (disabled[command_buffer_state]) return;
289
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600290 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Leger178b1e52020-10-05 12:22:23 -0400291 auto src_image_state = GetImageState(pResolveImageInfo->srcImage);
292 auto dst_image_state = GetImageState(pResolveImageInfo->dstImage);
293
294 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600295 cb_node->AddChild(src_image_state);
296 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400297}
298
locke-lunargd556cc32019-09-17 01:21:23 -0600299void ValidationStateTracker::PreCallRecordCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
300 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
301 uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600302 if (disabled[command_buffer_state]) return;
303
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600304 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600305 auto src_image_state = GetImageState(srcImage);
306 auto dst_image_state = GetImageState(dstImage);
307
308 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600309 cb_node->AddChild(src_image_state);
310 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600311}
312
Jeff Leger178b1e52020-10-05 12:22:23 -0400313void ValidationStateTracker::PreCallRecordCmdBlitImage2KHR(VkCommandBuffer commandBuffer,
314 const VkBlitImageInfo2KHR *pBlitImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600315 if (disabled[command_buffer_state]) return;
316
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600317 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Leger178b1e52020-10-05 12:22:23 -0400318 auto src_image_state = GetImageState(pBlitImageInfo->srcImage);
319 auto dst_image_state = GetImageState(pBlitImageInfo->dstImage);
320
321 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600322 cb_node->AddChild(src_image_state);
323 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400324}
325
locke-lunargd556cc32019-09-17 01:21:23 -0600326void ValidationStateTracker::PostCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
327 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer,
328 VkResult result) {
329 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600330
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500331 auto buffer_state = std::make_shared<BUFFER_STATE>(*pBuffer, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -0600332
James Rumble2f6e7bb2021-07-13 15:21:20 +0100333 if (pCreateInfo) {
334 const auto *opaque_capture_address = LvlFindInChain<VkBufferOpaqueCaptureAddressCreateInfo>(pCreateInfo->pNext);
335 if (opaque_capture_address) {
336 // address is used for GPU-AV and ray tracing buffer validation
337 buffer_state->deviceAddress = opaque_capture_address->opaqueCaptureAddress;
338 buffer_address_map_.emplace(opaque_capture_address->opaqueCaptureAddress, buffer_state.get());
339 }
340 }
341
locke-lunargd556cc32019-09-17 01:21:23 -0600342 // Get a set of requirements in the case the app does not
sfricke-samsungad90e722020-07-08 20:54:24 -0700343 DispatchGetBufferMemoryRequirements(device, *pBuffer, &buffer_state->requirements);
locke-lunargd556cc32019-09-17 01:21:23 -0600344
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700345 bufferMap.emplace(*pBuffer, std::move(buffer_state));
locke-lunargd556cc32019-09-17 01:21:23 -0600346}
347
348void ValidationStateTracker::PostCallRecordCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
349 const VkAllocationCallbacks *pAllocator, VkBufferView *pView,
350 VkResult result) {
351 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600352
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500353 auto buffer_state = GetBufferShared(pCreateInfo->buffer);
locke-lunarg25b6c352020-08-06 17:44:18 -0600354
355 VkFormatProperties format_properties;
356 DispatchGetPhysicalDeviceFormatProperties(physical_device, pCreateInfo->format, &format_properties);
locke-lunarg25b6c352020-08-06 17:44:18 -0600357
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600358 bufferViewMap[*pView] =
359 std::make_shared<BUFFER_VIEW_STATE>(buffer_state, *pView, pCreateInfo, format_properties.bufferFeatures);
locke-lunargd556cc32019-09-17 01:21:23 -0600360}
361
362void ValidationStateTracker::PostCallRecordCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
363 const VkAllocationCallbacks *pAllocator, VkImageView *pView,
364 VkResult result) {
365 if (result != VK_SUCCESS) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500366 auto image_state = GetImageShared(pCreateInfo->image);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700367
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600368 VkFormatFeatureFlags format_features = 0;
369 if (image_state->HasAHBFormat() == true) {
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700370 // The ImageView uses same Image's format feature since they share same AHB
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600371 format_features = image_state->format_features;
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700372 } else {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600373 format_features = GetImageFormatFeatures(physical_device, device, image_state->image(), pCreateInfo->format,
374 image_state->createInfo.tiling);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700375 }
376
locke-lunarg9939d4b2020-10-26 20:11:08 -0600377 // filter_cubic_props is used in CmdDraw validation. But it takes a lot of performance if it does in CmdDraw.
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600378 auto filter_cubic_props = LvlInitStruct<VkFilterCubicImageViewImageFormatPropertiesEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600379 if (IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700380 auto imageview_format_info = LvlInitStruct<VkPhysicalDeviceImageViewImageFormatInfoEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600381 imageview_format_info.imageViewType = pCreateInfo->viewType;
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700382 auto image_format_info = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>(&imageview_format_info);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600383 image_format_info.type = image_state->createInfo.imageType;
384 image_format_info.format = image_state->createInfo.format;
385 image_format_info.tiling = image_state->createInfo.tiling;
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600386 auto usage_create_info = LvlFindInChain<VkImageViewUsageCreateInfo>(pCreateInfo->pNext);
387 image_format_info.usage = usage_create_info ? usage_create_info->usage : image_state->createInfo.usage;
locke-lunarg9939d4b2020-10-26 20:11:08 -0600388 image_format_info.flags = image_state->createInfo.flags;
389
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600390 auto image_format_properties = LvlInitStruct<VkImageFormatProperties2>(&filter_cubic_props);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600391
392 DispatchGetPhysicalDeviceImageFormatProperties2(physical_device, &image_format_info, &image_format_properties);
393 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600394
395 imageViewMap[*pView] =
396 std::make_shared<IMAGE_VIEW_STATE>(image_state, *pView, pCreateInfo, format_features, filter_cubic_props);
locke-lunargd556cc32019-09-17 01:21:23 -0600397}
398
399void ValidationStateTracker::PreCallRecordCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
400 uint32_t regionCount, const VkBufferCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600401 if (disabled[command_buffer_state]) return;
402
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600403 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600404 auto src_buffer_state = GetBufferState(srcBuffer);
405 auto dst_buffer_state = GetBufferState(dstBuffer);
406
407 // Update bindings between buffers and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600408 cb_node->AddChild(src_buffer_state);
409 cb_node->AddChild(dst_buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600410}
411
Jeff Leger178b1e52020-10-05 12:22:23 -0400412void ValidationStateTracker::PreCallRecordCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
413 const VkCopyBufferInfo2KHR *pCopyBufferInfos) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600414 if (disabled[command_buffer_state]) return;
415
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600416 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Leger178b1e52020-10-05 12:22:23 -0400417 auto src_buffer_state = GetBufferState(pCopyBufferInfos->srcBuffer);
418 auto dst_buffer_state = GetBufferState(pCopyBufferInfos->dstBuffer);
419
420 // Update bindings between buffers and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600421 cb_node->AddChild(src_buffer_state);
422 cb_node->AddChild(dst_buffer_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400423}
424
locke-lunargd556cc32019-09-17 01:21:23 -0600425void ValidationStateTracker::PreCallRecordDestroyImageView(VkDevice device, VkImageView imageView,
426 const VkAllocationCallbacks *pAllocator) {
427 IMAGE_VIEW_STATE *image_view_state = GetImageViewState(imageView);
428 if (!image_view_state) return;
locke-lunargd556cc32019-09-17 01:21:23 -0600429
430 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600431 image_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600432 imageViewMap.erase(imageView);
433}
434
435void ValidationStateTracker::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
436 if (!buffer) return;
437 auto buffer_state = GetBufferState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600438
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600439 buffer_state->Destroy();
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600440 bufferMap.erase(buffer_state->buffer());
locke-lunargd556cc32019-09-17 01:21:23 -0600441}
442
443void ValidationStateTracker::PreCallRecordDestroyBufferView(VkDevice device, VkBufferView bufferView,
444 const VkAllocationCallbacks *pAllocator) {
445 if (!bufferView) return;
446 auto buffer_view_state = GetBufferViewState(bufferView);
locke-lunargd556cc32019-09-17 01:21:23 -0600447
448 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600449 buffer_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600450 bufferViewMap.erase(bufferView);
451}
452
453void ValidationStateTracker::PreCallRecordCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
454 VkDeviceSize size, uint32_t data) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600455 if (disabled[command_buffer_state]) return;
456
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600457 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600458 auto buffer_state = GetBufferState(dstBuffer);
459 // Update bindings between buffer and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600460 cb_node->AddChild(buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600461}
462
463void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
464 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
465 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600466 if (disabled[command_buffer_state]) return;
467
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600468 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600469 auto src_image_state = GetImageState(srcImage);
470 auto dst_buffer_state = GetBufferState(dstBuffer);
471
472 // Update bindings between buffer/image and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600473 cb_node->AddChild(src_image_state);
474 cb_node->AddChild(dst_buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600475}
476
Jeff Leger178b1e52020-10-05 12:22:23 -0400477void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
478 const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600479 if (disabled[command_buffer_state]) return;
480
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600481 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Leger178b1e52020-10-05 12:22:23 -0400482 auto src_image_state = GetImageState(pCopyImageToBufferInfo->srcImage);
483 auto dst_buffer_state = GetBufferState(pCopyImageToBufferInfo->dstBuffer);
484
485 // Update bindings between buffer/image and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600486 cb_node->AddChild(src_image_state);
487 cb_node->AddChild(dst_buffer_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400488}
489
locke-lunargd556cc32019-09-17 01:21:23 -0600490void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
491 VkImageLayout dstImageLayout, uint32_t regionCount,
492 const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600493 if (disabled[command_buffer_state]) return;
494
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600495 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600496 auto src_buffer_state = GetBufferState(srcBuffer);
497 auto dst_image_state = GetImageState(dstImage);
498
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600499 cb_node->AddChild(src_buffer_state);
500 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600501}
502
Jeff Leger178b1e52020-10-05 12:22:23 -0400503void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
504 const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600505
506 if (disabled[command_buffer_state]) return;
507
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600508 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Leger178b1e52020-10-05 12:22:23 -0400509 auto src_buffer_state = GetBufferState(pCopyBufferToImageInfo->srcBuffer);
510 auto dst_image_state = GetImageState(pCopyBufferToImageInfo->dstImage);
511
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600512 cb_node->AddChild(src_buffer_state);
513 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400514}
515
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600516QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) {
517 auto it = queueMap.find(queue);
518 if (it == queueMap.end()) {
519 return nullptr;
520 }
521 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600522}
523
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600524const QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) const {
525 auto it = queueMap.find(queue);
526 if (it == queueMap.cend()) {
527 return nullptr;
528 }
529 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600530}
531
locke-lunargd556cc32019-09-17 01:21:23 -0600532const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) const {
533 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
534 auto it = phys_dev_map->find(phys);
535 if (it == phys_dev_map->end()) {
536 return nullptr;
537 }
538 return &it->second;
539}
540
541PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) {
542 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
543 auto it = phys_dev_map->find(phys);
544 if (it == phys_dev_map->end()) {
545 return nullptr;
546 }
547 return &it->second;
548}
549
550PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() { return physical_device_state; }
551const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() const { return physical_device_state; }
552
553// Return ptr to memory binding for given handle of specified type
554template <typename State, typename Result>
555static Result GetObjectMemBindingImpl(State state, const VulkanTypedHandle &typed_handle) {
556 switch (typed_handle.type) {
557 case kVulkanObjectTypeImage:
558 return state->GetImageState(typed_handle.Cast<VkImage>());
559 case kVulkanObjectTypeBuffer:
560 return state->GetBufferState(typed_handle.Cast<VkBuffer>());
561 case kVulkanObjectTypeAccelerationStructureNV:
sourav parmarcd5fb182020-07-17 12:58:44 -0700562 return state->GetAccelerationStructureStateNV(typed_handle.Cast<VkAccelerationStructureNV>());
locke-lunargd556cc32019-09-17 01:21:23 -0600563 default:
564 break;
565 }
566 return nullptr;
567}
568
569const BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) const {
570 return GetObjectMemBindingImpl<const ValidationStateTracker *, const BINDABLE *>(this, typed_handle);
571}
572
573BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) {
574 return GetObjectMemBindingImpl<ValidationStateTracker *, BINDABLE *>(this, typed_handle);
575}
576
locke-lunargd556cc32019-09-17 01:21:23 -0600577// Remove set from setMap and delete the set
578void ValidationStateTracker::FreeDescriptorSet(cvdescriptorset::DescriptorSet *descriptor_set) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500579 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600580 descriptor_set->Destroy();
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500581
locke-lunargd556cc32019-09-17 01:21:23 -0600582 setMap.erase(descriptor_set->GetSet());
583}
584
585// Free all DS Pools including their Sets & related sub-structs
586// NOTE : Calls to this function should be wrapped in mutex
587void ValidationStateTracker::DeleteDescriptorSetPools() {
588 for (auto ii = descriptorPoolMap.begin(); ii != descriptorPoolMap.end();) {
589 // Remove this pools' sets from setMap and delete them
John Zulauf79f06582021-02-27 18:38:39 -0700590 for (auto *ds : ii->second->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -0600591 FreeDescriptorSet(ds);
592 }
593 ii->second->sets.clear();
594 ii = descriptorPoolMap.erase(ii);
595 }
596}
597
598// For given object struct return a ptr of BASE_NODE type for its wrapping struct
599BASE_NODE *ValidationStateTracker::GetStateStructPtrFromObject(const VulkanTypedHandle &object_struct) {
Jeff Bolzadbfa852019-10-04 13:53:30 -0500600 if (object_struct.node) {
601#ifdef _DEBUG
602 // assert that lookup would find the same object
603 VulkanTypedHandle other = object_struct;
604 other.node = nullptr;
605 assert(object_struct.node == GetStateStructPtrFromObject(other));
606#endif
607 return object_struct.node;
608 }
locke-lunargd556cc32019-09-17 01:21:23 -0600609 BASE_NODE *base_ptr = nullptr;
610 switch (object_struct.type) {
611 case kVulkanObjectTypeDescriptorSet: {
612 base_ptr = GetSetNode(object_struct.Cast<VkDescriptorSet>());
613 break;
614 }
615 case kVulkanObjectTypeSampler: {
616 base_ptr = GetSamplerState(object_struct.Cast<VkSampler>());
617 break;
618 }
619 case kVulkanObjectTypeQueryPool: {
620 base_ptr = GetQueryPoolState(object_struct.Cast<VkQueryPool>());
621 break;
622 }
623 case kVulkanObjectTypePipeline: {
624 base_ptr = GetPipelineState(object_struct.Cast<VkPipeline>());
625 break;
626 }
627 case kVulkanObjectTypeBuffer: {
628 base_ptr = GetBufferState(object_struct.Cast<VkBuffer>());
629 break;
630 }
631 case kVulkanObjectTypeBufferView: {
632 base_ptr = GetBufferViewState(object_struct.Cast<VkBufferView>());
633 break;
634 }
635 case kVulkanObjectTypeImage: {
636 base_ptr = GetImageState(object_struct.Cast<VkImage>());
637 break;
638 }
639 case kVulkanObjectTypeImageView: {
640 base_ptr = GetImageViewState(object_struct.Cast<VkImageView>());
641 break;
642 }
643 case kVulkanObjectTypeEvent: {
644 base_ptr = GetEventState(object_struct.Cast<VkEvent>());
645 break;
646 }
647 case kVulkanObjectTypeDescriptorPool: {
648 base_ptr = GetDescriptorPoolState(object_struct.Cast<VkDescriptorPool>());
649 break;
650 }
651 case kVulkanObjectTypeCommandPool: {
652 base_ptr = GetCommandPoolState(object_struct.Cast<VkCommandPool>());
653 break;
654 }
655 case kVulkanObjectTypeFramebuffer: {
656 base_ptr = GetFramebufferState(object_struct.Cast<VkFramebuffer>());
657 break;
658 }
659 case kVulkanObjectTypeRenderPass: {
660 base_ptr = GetRenderPassState(object_struct.Cast<VkRenderPass>());
661 break;
662 }
663 case kVulkanObjectTypeDeviceMemory: {
664 base_ptr = GetDevMemState(object_struct.Cast<VkDeviceMemory>());
665 break;
666 }
667 case kVulkanObjectTypeAccelerationStructureNV: {
sourav parmarcd5fb182020-07-17 12:58:44 -0700668 base_ptr = GetAccelerationStructureStateNV(object_struct.Cast<VkAccelerationStructureNV>());
669 break;
670 }
671 case kVulkanObjectTypeAccelerationStructureKHR: {
672 base_ptr = GetAccelerationStructureStateKHR(object_struct.Cast<VkAccelerationStructureKHR>());
locke-lunargd556cc32019-09-17 01:21:23 -0600673 break;
674 }
Jeff Bolzadbfa852019-10-04 13:53:30 -0500675 case kVulkanObjectTypeUnknown:
676 // This can happen if an element of the object_bindings vector has been
677 // zeroed out, after an object is destroyed.
678 break;
locke-lunargd556cc32019-09-17 01:21:23 -0600679 default:
680 // TODO : Any other objects to be handled here?
681 assert(0);
682 break;
683 }
684 return base_ptr;
685}
686
sfricke-samsungbf1a2ed2020-06-14 23:31:00 -0700687// Gets union of all features defined by Potential Format Features
688// except, does not handle the external format case for AHB as that only can be used for sampled images
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700689VkFormatFeatureFlags ValidationStateTracker::GetPotentialFormatFeatures(VkFormat format) const {
690 VkFormatFeatureFlags format_features = 0;
691
692 if (format != VK_FORMAT_UNDEFINED) {
693 VkFormatProperties format_properties;
694 DispatchGetPhysicalDeviceFormatProperties(physical_device, format, &format_properties);
695 format_features |= format_properties.linearTilingFeatures;
696 format_features |= format_properties.optimalTilingFeatures;
697 if (device_extensions.vk_ext_image_drm_format_modifier) {
698 // VK_KHR_get_physical_device_properties2 is required in this case
699 VkFormatProperties2 format_properties_2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
700 VkDrmFormatModifierPropertiesListEXT drm_properties_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
701 nullptr};
702 format_properties_2.pNext = (void *)&drm_properties_list;
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100703
704 // First call is to get the number of modifiers compatible with the queried format
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700705 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100706
707 std::vector<VkDrmFormatModifierPropertiesEXT> drm_properties;
708 drm_properties.resize(drm_properties_list.drmFormatModifierCount);
709 drm_properties_list.pDrmFormatModifierProperties = drm_properties.data();
710
711 // Second call, now with an allocated array in pDrmFormatModifierProperties, is to get the modifiers
712 // compatible with the queried format
713 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
714
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700715 for (uint32_t i = 0; i < drm_properties_list.drmFormatModifierCount; i++) {
716 format_features |= drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
717 }
718 }
719 }
720
721 return format_features;
722}
723
locke-lunargd556cc32019-09-17 01:21:23 -0600724void ValidationStateTracker::PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
725 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
726 VkResult result) {
727 if (VK_SUCCESS != result) return;
728
Locke Linf3873542021-04-26 11:25:10 -0600729 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
730 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
731 ValidationStateTracker *state_tracker = static_cast<ValidationStateTracker *>(validation_data);
732
locke-lunargd556cc32019-09-17 01:21:23 -0600733 const VkPhysicalDeviceFeatures *enabled_features_found = pCreateInfo->pEnabledFeatures;
734 if (nullptr == enabled_features_found) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700735 const auto *features2 = LvlFindInChain<VkPhysicalDeviceFeatures2>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600736 if (features2) {
737 enabled_features_found = &(features2->features);
Locke Linf3873542021-04-26 11:25:10 -0600738
739 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(features2->pNext);
740 if (provoking_vertex_features) {
741 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
742 }
locke-lunargd556cc32019-09-17 01:21:23 -0600743 }
744 }
745
locke-lunargd556cc32019-09-17 01:21:23 -0600746 if (nullptr == enabled_features_found) {
747 state_tracker->enabled_features.core = {};
748 } else {
749 state_tracker->enabled_features.core = *enabled_features_found;
750 }
751
752 // Make sure that queue_family_properties are obtained for this device's physical_device, even if the app has not
753 // previously set them through an explicit API call.
754 uint32_t count;
755 auto pd_state = GetPhysicalDeviceState(gpu);
756 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
757 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
758 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, &pd_state->queue_family_properties[0]);
759 // Save local link to this device's physical device state
760 state_tracker->physical_device_state = pd_state;
761
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700762 const auto *vulkan_12_features = LvlFindInChain<VkPhysicalDeviceVulkan12Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700763 if (vulkan_12_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700764 state_tracker->enabled_features.core12 = *vulkan_12_features;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700765 } else {
sfricke-samsung27c70722020-05-02 08:42:39 -0700766 // Set Extension Feature Aliases to false as there is no struct to check
767 state_tracker->enabled_features.core12.drawIndirectCount = VK_FALSE;
768 state_tracker->enabled_features.core12.samplerMirrorClampToEdge = VK_FALSE;
769 state_tracker->enabled_features.core12.descriptorIndexing = VK_FALSE;
770 state_tracker->enabled_features.core12.samplerFilterMinmax = VK_FALSE;
771 state_tracker->enabled_features.core12.shaderOutputLayer = VK_FALSE;
772 state_tracker->enabled_features.core12.shaderOutputViewportIndex = VK_FALSE;
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800773 state_tracker->enabled_features.core12.subgroupBroadcastDynamicId = VK_FALSE;
sfricke-samsung27c70722020-05-02 08:42:39 -0700774
775 // These structs are only allowed in pNext chain if there is no VkPhysicalDeviceVulkan12Features
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700776
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700777 const auto *eight_bit_storage_features = LvlFindInChain<VkPhysicalDevice8BitStorageFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700778 if (eight_bit_storage_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700779 state_tracker->enabled_features.core12.storageBuffer8BitAccess = eight_bit_storage_features->storageBuffer8BitAccess;
780 state_tracker->enabled_features.core12.uniformAndStorageBuffer8BitAccess =
781 eight_bit_storage_features->uniformAndStorageBuffer8BitAccess;
782 state_tracker->enabled_features.core12.storagePushConstant8 = eight_bit_storage_features->storagePushConstant8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700783 }
784
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700785 const auto *float16_int8_features = LvlFindInChain<VkPhysicalDeviceShaderFloat16Int8Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700786 if (float16_int8_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700787 state_tracker->enabled_features.core12.shaderFloat16 = float16_int8_features->shaderFloat16;
788 state_tracker->enabled_features.core12.shaderInt8 = float16_int8_features->shaderInt8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700789 }
790
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700791 const auto *descriptor_indexing_features = LvlFindInChain<VkPhysicalDeviceDescriptorIndexingFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700792 if (descriptor_indexing_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700793 state_tracker->enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing =
794 descriptor_indexing_features->shaderInputAttachmentArrayDynamicIndexing;
795 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing =
796 descriptor_indexing_features->shaderUniformTexelBufferArrayDynamicIndexing;
797 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing =
798 descriptor_indexing_features->shaderStorageTexelBufferArrayDynamicIndexing;
799 state_tracker->enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing =
800 descriptor_indexing_features->shaderUniformBufferArrayNonUniformIndexing;
801 state_tracker->enabled_features.core12.shaderSampledImageArrayNonUniformIndexing =
802 descriptor_indexing_features->shaderSampledImageArrayNonUniformIndexing;
803 state_tracker->enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing =
804 descriptor_indexing_features->shaderStorageBufferArrayNonUniformIndexing;
805 state_tracker->enabled_features.core12.shaderStorageImageArrayNonUniformIndexing =
806 descriptor_indexing_features->shaderStorageImageArrayNonUniformIndexing;
807 state_tracker->enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing =
808 descriptor_indexing_features->shaderInputAttachmentArrayNonUniformIndexing;
809 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing =
810 descriptor_indexing_features->shaderUniformTexelBufferArrayNonUniformIndexing;
811 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing =
812 descriptor_indexing_features->shaderStorageTexelBufferArrayNonUniformIndexing;
813 state_tracker->enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind =
814 descriptor_indexing_features->descriptorBindingUniformBufferUpdateAfterBind;
815 state_tracker->enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind =
816 descriptor_indexing_features->descriptorBindingSampledImageUpdateAfterBind;
817 state_tracker->enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind =
818 descriptor_indexing_features->descriptorBindingStorageImageUpdateAfterBind;
819 state_tracker->enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind =
820 descriptor_indexing_features->descriptorBindingStorageBufferUpdateAfterBind;
821 state_tracker->enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind =
822 descriptor_indexing_features->descriptorBindingUniformTexelBufferUpdateAfterBind;
823 state_tracker->enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind =
824 descriptor_indexing_features->descriptorBindingStorageTexelBufferUpdateAfterBind;
825 state_tracker->enabled_features.core12.descriptorBindingUpdateUnusedWhilePending =
826 descriptor_indexing_features->descriptorBindingUpdateUnusedWhilePending;
827 state_tracker->enabled_features.core12.descriptorBindingPartiallyBound =
828 descriptor_indexing_features->descriptorBindingPartiallyBound;
829 state_tracker->enabled_features.core12.descriptorBindingVariableDescriptorCount =
830 descriptor_indexing_features->descriptorBindingVariableDescriptorCount;
831 state_tracker->enabled_features.core12.runtimeDescriptorArray = descriptor_indexing_features->runtimeDescriptorArray;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700832 }
833
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700834 const auto *scalar_block_layout_features = LvlFindInChain<VkPhysicalDeviceScalarBlockLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700835 if (scalar_block_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700836 state_tracker->enabled_features.core12.scalarBlockLayout = scalar_block_layout_features->scalarBlockLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700837 }
838
839 const auto *imageless_framebuffer_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700840 LvlFindInChain<VkPhysicalDeviceImagelessFramebufferFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700841 if (imageless_framebuffer_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700842 state_tracker->enabled_features.core12.imagelessFramebuffer = imageless_framebuffer_features->imagelessFramebuffer;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700843 }
844
845 const auto *uniform_buffer_standard_layout_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700846 LvlFindInChain<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700847 if (uniform_buffer_standard_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700848 state_tracker->enabled_features.core12.uniformBufferStandardLayout =
849 uniform_buffer_standard_layout_features->uniformBufferStandardLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700850 }
851
852 const auto *subgroup_extended_types_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700853 LvlFindInChain<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700854 if (subgroup_extended_types_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700855 state_tracker->enabled_features.core12.shaderSubgroupExtendedTypes =
856 subgroup_extended_types_features->shaderSubgroupExtendedTypes;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700857 }
858
859 const auto *separate_depth_stencil_layouts_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700860 LvlFindInChain<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700861 if (separate_depth_stencil_layouts_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700862 state_tracker->enabled_features.core12.separateDepthStencilLayouts =
863 separate_depth_stencil_layouts_features->separateDepthStencilLayouts;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700864 }
865
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700866 const auto *host_query_reset_features = LvlFindInChain<VkPhysicalDeviceHostQueryResetFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700867 if (host_query_reset_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700868 state_tracker->enabled_features.core12.hostQueryReset = host_query_reset_features->hostQueryReset;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700869 }
870
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700871 const auto *timeline_semaphore_features = LvlFindInChain<VkPhysicalDeviceTimelineSemaphoreFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700872 if (timeline_semaphore_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700873 state_tracker->enabled_features.core12.timelineSemaphore = timeline_semaphore_features->timelineSemaphore;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700874 }
875
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700876 const auto *buffer_device_address = LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700877 if (buffer_device_address) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700878 state_tracker->enabled_features.core12.bufferDeviceAddress = buffer_device_address->bufferDeviceAddress;
879 state_tracker->enabled_features.core12.bufferDeviceAddressCaptureReplay =
880 buffer_device_address->bufferDeviceAddressCaptureReplay;
881 state_tracker->enabled_features.core12.bufferDeviceAddressMultiDevice =
882 buffer_device_address->bufferDeviceAddressMultiDevice;
883 }
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800884
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700885 const auto *atomic_int64_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicInt64Features>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800886 if (atomic_int64_features) {
887 state_tracker->enabled_features.core12.shaderBufferInt64Atomics = atomic_int64_features->shaderBufferInt64Atomics;
888 state_tracker->enabled_features.core12.shaderSharedInt64Atomics = atomic_int64_features->shaderSharedInt64Atomics;
889 }
890
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700891 const auto *memory_model_features = LvlFindInChain<VkPhysicalDeviceVulkanMemoryModelFeatures>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800892 if (memory_model_features) {
893 state_tracker->enabled_features.core12.vulkanMemoryModel = memory_model_features->vulkanMemoryModel;
894 state_tracker->enabled_features.core12.vulkanMemoryModelDeviceScope =
895 memory_model_features->vulkanMemoryModelDeviceScope;
896 state_tracker->enabled_features.core12.vulkanMemoryModelAvailabilityVisibilityChains =
897 memory_model_features->vulkanMemoryModelAvailabilityVisibilityChains;
898 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700899 }
900
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700901 const auto *vulkan_11_features = LvlFindInChain<VkPhysicalDeviceVulkan11Features>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700902 if (vulkan_11_features) {
903 state_tracker->enabled_features.core11 = *vulkan_11_features;
904 } else {
905 // These structs are only allowed in pNext chain if there is no kPhysicalDeviceVulkan11Features
906
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700907 const auto *sixteen_bit_storage_features = LvlFindInChain<VkPhysicalDevice16BitStorageFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700908 if (sixteen_bit_storage_features) {
909 state_tracker->enabled_features.core11.storageBuffer16BitAccess =
910 sixteen_bit_storage_features->storageBuffer16BitAccess;
911 state_tracker->enabled_features.core11.uniformAndStorageBuffer16BitAccess =
912 sixteen_bit_storage_features->uniformAndStorageBuffer16BitAccess;
913 state_tracker->enabled_features.core11.storagePushConstant16 = sixteen_bit_storage_features->storagePushConstant16;
914 state_tracker->enabled_features.core11.storageInputOutput16 = sixteen_bit_storage_features->storageInputOutput16;
915 }
916
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700917 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700918 if (multiview_features) {
919 state_tracker->enabled_features.core11.multiview = multiview_features->multiview;
920 state_tracker->enabled_features.core11.multiviewGeometryShader = multiview_features->multiviewGeometryShader;
921 state_tracker->enabled_features.core11.multiviewTessellationShader = multiview_features->multiviewTessellationShader;
922 }
923
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700924 const auto *variable_pointers_features = LvlFindInChain<VkPhysicalDeviceVariablePointersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700925 if (variable_pointers_features) {
926 state_tracker->enabled_features.core11.variablePointersStorageBuffer =
927 variable_pointers_features->variablePointersStorageBuffer;
928 state_tracker->enabled_features.core11.variablePointers = variable_pointers_features->variablePointers;
929 }
930
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700931 const auto *protected_memory_features = LvlFindInChain<VkPhysicalDeviceProtectedMemoryFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700932 if (protected_memory_features) {
933 state_tracker->enabled_features.core11.protectedMemory = protected_memory_features->protectedMemory;
934 }
935
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700936 const auto *ycbcr_conversion_features = LvlFindInChain<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700937 if (ycbcr_conversion_features) {
938 state_tracker->enabled_features.core11.samplerYcbcrConversion = ycbcr_conversion_features->samplerYcbcrConversion;
939 }
940
941 const auto *shader_draw_parameters_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700942 LvlFindInChain<VkPhysicalDeviceShaderDrawParametersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700943 if (shader_draw_parameters_features) {
944 state_tracker->enabled_features.core11.shaderDrawParameters = shader_draw_parameters_features->shaderDrawParameters;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700945 }
946 }
947
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700948 const auto *device_group_ci = LvlFindInChain<VkDeviceGroupDeviceCreateInfo>(pCreateInfo->pNext);
Tony-LunarGca4891a2020-08-10 15:46:46 -0600949 if (device_group_ci) {
950 state_tracker->physical_device_count = device_group_ci->physicalDeviceCount;
951 state_tracker->device_group_create_info = *device_group_ci;
952 } else {
953 state_tracker->physical_device_count = 1;
954 }
locke-lunargd556cc32019-09-17 01:21:23 -0600955
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700956 const auto *exclusive_scissor_features = LvlFindInChain<VkPhysicalDeviceExclusiveScissorFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600957 if (exclusive_scissor_features) {
958 state_tracker->enabled_features.exclusive_scissor = *exclusive_scissor_features;
959 }
960
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700961 const auto *shading_rate_image_features = LvlFindInChain<VkPhysicalDeviceShadingRateImageFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600962 if (shading_rate_image_features) {
963 state_tracker->enabled_features.shading_rate_image = *shading_rate_image_features;
964 }
965
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700966 const auto *mesh_shader_features = LvlFindInChain<VkPhysicalDeviceMeshShaderFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600967 if (mesh_shader_features) {
968 state_tracker->enabled_features.mesh_shader = *mesh_shader_features;
969 }
970
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700971 const auto *inline_uniform_block_features = LvlFindInChain<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600972 if (inline_uniform_block_features) {
973 state_tracker->enabled_features.inline_uniform_block = *inline_uniform_block_features;
974 }
975
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700976 const auto *transform_feedback_features = LvlFindInChain<VkPhysicalDeviceTransformFeedbackFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600977 if (transform_feedback_features) {
978 state_tracker->enabled_features.transform_feedback_features = *transform_feedback_features;
979 }
980
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700981 const auto *vtx_attrib_div_features = LvlFindInChain<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600982 if (vtx_attrib_div_features) {
983 state_tracker->enabled_features.vtx_attrib_divisor_features = *vtx_attrib_div_features;
984 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700985
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700986 const auto *buffer_device_address_ext = LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>(pCreateInfo->pNext);
Jeff Bolz4563f2a2019-12-10 13:30:30 -0600987 if (buffer_device_address_ext) {
Jeff Bolz33fc6722020-03-31 12:58:16 -0500988 state_tracker->enabled_features.buffer_device_address_ext = *buffer_device_address_ext;
locke-lunargd556cc32019-09-17 01:21:23 -0600989 }
990
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700991 const auto *cooperative_matrix_features = LvlFindInChain<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600992 if (cooperative_matrix_features) {
993 state_tracker->enabled_features.cooperative_matrix_features = *cooperative_matrix_features;
994 }
995
locke-lunargd556cc32019-09-17 01:21:23 -0600996 const auto *compute_shader_derivatives_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700997 LvlFindInChain<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600998 if (compute_shader_derivatives_features) {
999 state_tracker->enabled_features.compute_shader_derivatives_features = *compute_shader_derivatives_features;
1000 }
1001
1002 const auto *fragment_shader_barycentric_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001003 LvlFindInChain<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001004 if (fragment_shader_barycentric_features) {
1005 state_tracker->enabled_features.fragment_shader_barycentric_features = *fragment_shader_barycentric_features;
1006 }
1007
1008 const auto *shader_image_footprint_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001009 LvlFindInChain<VkPhysicalDeviceShaderImageFootprintFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001010 if (shader_image_footprint_features) {
1011 state_tracker->enabled_features.shader_image_footprint_features = *shader_image_footprint_features;
1012 }
1013
1014 const auto *fragment_shader_interlock_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001015 LvlFindInChain<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001016 if (fragment_shader_interlock_features) {
1017 state_tracker->enabled_features.fragment_shader_interlock_features = *fragment_shader_interlock_features;
1018 }
1019
1020 const auto *demote_to_helper_invocation_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001021 LvlFindInChain<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001022 if (demote_to_helper_invocation_features) {
1023 state_tracker->enabled_features.demote_to_helper_invocation_features = *demote_to_helper_invocation_features;
1024 }
1025
1026 const auto *texel_buffer_alignment_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001027 LvlFindInChain<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001028 if (texel_buffer_alignment_features) {
1029 state_tracker->enabled_features.texel_buffer_alignment_features = *texel_buffer_alignment_features;
1030 }
1031
locke-lunargd556cc32019-09-17 01:21:23 -06001032 const auto *pipeline_exe_props_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001033 LvlFindInChain<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001034 if (pipeline_exe_props_features) {
1035 state_tracker->enabled_features.pipeline_exe_props_features = *pipeline_exe_props_features;
1036 }
1037
Jeff Bolz82f854d2019-09-17 14:56:47 -05001038 const auto *dedicated_allocation_image_aliasing_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001039 LvlFindInChain<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>(pCreateInfo->pNext);
Jeff Bolz82f854d2019-09-17 14:56:47 -05001040 if (dedicated_allocation_image_aliasing_features) {
1041 state_tracker->enabled_features.dedicated_allocation_image_aliasing_features =
1042 *dedicated_allocation_image_aliasing_features;
1043 }
1044
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001045 const auto *performance_query_features = LvlFindInChain<VkPhysicalDevicePerformanceQueryFeaturesKHR>(pCreateInfo->pNext);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001046 if (performance_query_features) {
1047 state_tracker->enabled_features.performance_query_features = *performance_query_features;
1048 }
1049
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001050 const auto *device_coherent_memory_features = LvlFindInChain<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(pCreateInfo->pNext);
Tobias Hector782bcde2019-11-28 16:19:42 +00001051 if (device_coherent_memory_features) {
1052 state_tracker->enabled_features.device_coherent_memory_features = *device_coherent_memory_features;
1053 }
1054
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001055 const auto *ycbcr_image_array_features = LvlFindInChain<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsungcead0802020-01-30 22:20:10 -08001056 if (ycbcr_image_array_features) {
1057 state_tracker->enabled_features.ycbcr_image_array_features = *ycbcr_image_array_features;
1058 }
1059
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001060 const auto *ray_query_features = LvlFindInChain<VkPhysicalDeviceRayQueryFeaturesKHR>(pCreateInfo->pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07001061 if (ray_query_features) {
1062 state_tracker->enabled_features.ray_query_features = *ray_query_features;
1063 }
1064
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001065 const auto *ray_tracing_pipeline_features = LvlFindInChain<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>(pCreateInfo->pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07001066 if (ray_tracing_pipeline_features) {
1067 state_tracker->enabled_features.ray_tracing_pipeline_features = *ray_tracing_pipeline_features;
1068 }
1069
1070 const auto *ray_tracing_acceleration_structure_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001071 LvlFindInChain<VkPhysicalDeviceAccelerationStructureFeaturesKHR>(pCreateInfo->pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07001072 if (ray_tracing_acceleration_structure_features) {
1073 state_tracker->enabled_features.ray_tracing_acceleration_structure_features = *ray_tracing_acceleration_structure_features;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001074 }
1075
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001076 const auto *robustness2_features = LvlFindInChain<VkPhysicalDeviceRobustness2FeaturesEXT>(pCreateInfo->pNext);
Jeff Bolz165818a2020-05-08 11:19:03 -05001077 if (robustness2_features) {
1078 state_tracker->enabled_features.robustness2_features = *robustness2_features;
1079 }
1080
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001081 const auto *fragment_density_map_features = LvlFindInChain<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(pCreateInfo->pNext);
janharaldfredriksen-arm3b793772020-05-12 18:55:53 +02001082 if (fragment_density_map_features) {
1083 state_tracker->enabled_features.fragment_density_map_features = *fragment_density_map_features;
1084 }
1085
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001086 const auto *fragment_density_map_features2 = LvlFindInChain<VkPhysicalDeviceFragmentDensityMap2FeaturesEXT>(pCreateInfo->pNext);
janharaldfredriksen-arm36e17572020-07-07 13:59:28 +02001087 if (fragment_density_map_features2) {
1088 state_tracker->enabled_features.fragment_density_map2_features = *fragment_density_map_features2;
1089 }
1090
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001091 const auto *astc_decode_features = LvlFindInChain<VkPhysicalDeviceASTCDecodeFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsung0c4a06f2020-06-27 01:24:32 -07001092 if (astc_decode_features) {
1093 state_tracker->enabled_features.astc_decode_features = *astc_decode_features;
1094 }
1095
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001096 const auto *custom_border_color_features = LvlFindInChain<VkPhysicalDeviceCustomBorderColorFeaturesEXT>(pCreateInfo->pNext);
Tony-LunarG7337b312020-04-15 16:40:25 -06001097 if (custom_border_color_features) {
1098 state_tracker->enabled_features.custom_border_color_features = *custom_border_color_features;
1099 }
1100
sfricke-samsungfd661d62020-05-16 00:57:27 -07001101 const auto *pipeline_creation_cache_control_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001102 LvlFindInChain<VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsungfd661d62020-05-16 00:57:27 -07001103 if (pipeline_creation_cache_control_features) {
1104 state_tracker->enabled_features.pipeline_creation_cache_control_features = *pipeline_creation_cache_control_features;
1105 }
1106
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001107 const auto *fragment_shading_rate_features = LvlFindInChain<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>(pCreateInfo->pNext);
Tobias Hector6663c9b2020-11-05 10:18:02 +00001108 if (fragment_shading_rate_features) {
1109 state_tracker->enabled_features.fragment_shading_rate_features = *fragment_shading_rate_features;
1110 }
1111
Piers Daniell39842ee2020-07-10 16:42:33 -06001112 const auto *extended_dynamic_state_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001113 LvlFindInChain<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>(pCreateInfo->pNext);
Piers Daniell39842ee2020-07-10 16:42:33 -06001114 if (extended_dynamic_state_features) {
1115 state_tracker->enabled_features.extended_dynamic_state_features = *extended_dynamic_state_features;
1116 }
1117
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07001118 const auto *extended_dynamic_state2_features =
1119 LvlFindInChain<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>(pCreateInfo->pNext);
1120 if (extended_dynamic_state2_features) {
1121 state_tracker->enabled_features.extended_dynamic_state2_features = *extended_dynamic_state2_features;
1122 }
1123
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001124 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
locke-lunarg3fa463a2020-10-23 16:39:04 -06001125 if (multiview_features) {
1126 state_tracker->enabled_features.multiview_features = *multiview_features;
1127 }
1128
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001129 const auto *portability_features = LvlFindInChain<VkPhysicalDevicePortabilitySubsetFeaturesKHR>(pCreateInfo->pNext);
Nathaniel Cesariob3f2d702020-11-09 09:20:49 -07001130 if (portability_features) {
1131 state_tracker->enabled_features.portability_subset_features = *portability_features;
1132 }
1133
sfricke-samsung0065ce02020-12-03 22:46:37 -08001134 const auto *shader_integer_functions2_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001135 LvlFindInChain<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001136 if (shader_integer_functions2_features) {
1137 state_tracker->enabled_features.shader_integer_functions2_features = *shader_integer_functions2_features;
1138 }
1139
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001140 const auto *shader_sm_builtins_feature = LvlFindInChain<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001141 if (shader_sm_builtins_feature) {
1142 state_tracker->enabled_features.shader_sm_builtins_feature = *shader_sm_builtins_feature;
1143 }
1144
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001145 const auto *shader_atomic_float_feature = LvlFindInChain<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001146 if (shader_atomic_float_feature) {
1147 state_tracker->enabled_features.shader_atomic_float_feature = *shader_atomic_float_feature;
1148 }
1149
1150 const auto *shader_image_atomic_int64_feature =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001151 LvlFindInChain<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001152 if (shader_image_atomic_int64_feature) {
1153 state_tracker->enabled_features.shader_image_atomic_int64_feature = *shader_image_atomic_int64_feature;
1154 }
1155
sfricke-samsung486a51e2021-01-02 00:10:15 -08001156 const auto *shader_clock_feature = LvlFindInChain<VkPhysicalDeviceShaderClockFeaturesKHR>(pCreateInfo->pNext);
1157 if (shader_clock_feature) {
1158 state_tracker->enabled_features.shader_clock_feature = *shader_clock_feature;
1159 }
1160
Jeremy Gebben5f585ae2021-02-02 09:03:06 -07001161 const auto *conditional_rendering_features =
1162 LvlFindInChain<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(pCreateInfo->pNext);
1163 if (conditional_rendering_features) {
1164 state_tracker->enabled_features.conditional_rendering = *conditional_rendering_features;
1165 }
1166
Shannon McPhersondb287d42021-02-02 15:27:32 -07001167 const auto *workgroup_memory_explicit_layout_features =
1168 LvlFindInChain<VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>(pCreateInfo->pNext);
1169 if (workgroup_memory_explicit_layout_features) {
1170 state_tracker->enabled_features.workgroup_memory_explicit_layout_features = *workgroup_memory_explicit_layout_features;
1171 }
1172
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001173 const auto *synchronization2_features =
1174 LvlFindInChain<VkPhysicalDeviceSynchronization2FeaturesKHR>(pCreateInfo->pNext);
1175 if (synchronization2_features) {
1176 state_tracker->enabled_features.synchronization2_features = *synchronization2_features;
1177 }
1178
Locke Linf3873542021-04-26 11:25:10 -06001179 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(pCreateInfo->pNext);
1180 if (provoking_vertex_features) {
1181 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
1182 }
1183
Piers Daniellcb6d8032021-04-19 18:51:26 -06001184 const auto *vertex_input_dynamic_state_features =
1185 LvlFindInChain<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>(pCreateInfo->pNext);
1186 if (vertex_input_dynamic_state_features) {
1187 state_tracker->enabled_features.vertex_input_dynamic_state_features = *vertex_input_dynamic_state_features;
1188 }
1189
David Zhao Akeley44139b12021-04-26 16:16:13 -07001190 const auto *inherited_viewport_scissor_features =
1191 LvlFindInChain<VkPhysicalDeviceInheritedViewportScissorFeaturesNV>(pCreateInfo->pNext);
1192 if (inherited_viewport_scissor_features) {
1193 state_tracker->enabled_features.inherited_viewport_scissor_features = *inherited_viewport_scissor_features;
1194 }
1195
Tony-LunarG4490de42021-06-21 15:49:19 -06001196 const auto *multi_draw_features = LvlFindInChain<VkPhysicalDeviceMultiDrawFeaturesEXT>(pCreateInfo->pNext);
1197 if (multi_draw_features) {
1198 state_tracker->enabled_features.multi_draw_features = *multi_draw_features;
1199 }
1200
ziga-lunarg29ba2b92021-07-20 21:51:45 +02001201 const auto *color_write_features = LvlFindInChain<VkPhysicalDeviceColorWriteEnableFeaturesEXT>(pCreateInfo->pNext);
1202 if (color_write_features) {
1203 state_tracker->enabled_features.color_write_features = *color_write_features;
1204 }
1205
Mike Schuchardtb3870ea2021-07-20 18:56:51 -07001206 const auto *shader_atomic_float2_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>(pCreateInfo->pNext);
1207 if (shader_atomic_float2_features) {
1208 state_tracker->enabled_features.shader_atomic_float2_features = *shader_atomic_float2_features;
1209 }
1210
Tony-LunarG6f887e52021-07-27 11:23:14 -06001211 const auto *present_id_features = LvlFindInChain<VkPhysicalDevicePresentIdFeaturesKHR>(pCreateInfo->pNext);
1212 if (present_id_features) {
1213 state_tracker->enabled_features.present_id_features = *present_id_features;
1214 }
1215
1216 const auto *present_wait_features = LvlFindInChain<VkPhysicalDevicePresentWaitFeaturesKHR>(pCreateInfo->pNext);
1217 if (present_wait_features) {
1218 state_tracker->enabled_features.present_wait_features = *present_wait_features;
1219 }
1220
locke-lunargd556cc32019-09-17 01:21:23 -06001221 // Store physical device properties and physical device mem limits into CoreChecks structs
1222 DispatchGetPhysicalDeviceMemoryProperties(gpu, &state_tracker->phys_dev_mem_props);
1223 DispatchGetPhysicalDeviceProperties(gpu, &state_tracker->phys_dev_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001224 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1225 &state_tracker->phys_dev_props_core11);
1226 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1227 &state_tracker->phys_dev_props_core12);
locke-lunargd556cc32019-09-17 01:21:23 -06001228
1229 const auto &dev_ext = state_tracker->device_extensions;
1230 auto *phys_dev_props = &state_tracker->phys_dev_ext_props;
1231
1232 if (dev_ext.vk_khr_push_descriptor) {
1233 // Get the needed push_descriptor limits
1234 VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor_prop;
1235 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_push_descriptor, &push_descriptor_prop);
1236 phys_dev_props->max_push_descriptors = push_descriptor_prop.maxPushDescriptors;
1237 }
1238
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001239 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_ext_descriptor_indexing) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001240 VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing_prop;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001241 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_descriptor_indexing, &descriptor_indexing_prop);
1242 state_tracker->phys_dev_props_core12.maxUpdateAfterBindDescriptorsInAllPools =
1243 descriptor_indexing_prop.maxUpdateAfterBindDescriptorsInAllPools;
1244 state_tracker->phys_dev_props_core12.shaderUniformBufferArrayNonUniformIndexingNative =
1245 descriptor_indexing_prop.shaderUniformBufferArrayNonUniformIndexingNative;
1246 state_tracker->phys_dev_props_core12.shaderSampledImageArrayNonUniformIndexingNative =
1247 descriptor_indexing_prop.shaderSampledImageArrayNonUniformIndexingNative;
1248 state_tracker->phys_dev_props_core12.shaderStorageBufferArrayNonUniformIndexingNative =
1249 descriptor_indexing_prop.shaderStorageBufferArrayNonUniformIndexingNative;
1250 state_tracker->phys_dev_props_core12.shaderStorageImageArrayNonUniformIndexingNative =
1251 descriptor_indexing_prop.shaderStorageImageArrayNonUniformIndexingNative;
1252 state_tracker->phys_dev_props_core12.shaderInputAttachmentArrayNonUniformIndexingNative =
1253 descriptor_indexing_prop.shaderInputAttachmentArrayNonUniformIndexingNative;
1254 state_tracker->phys_dev_props_core12.robustBufferAccessUpdateAfterBind =
1255 descriptor_indexing_prop.robustBufferAccessUpdateAfterBind;
1256 state_tracker->phys_dev_props_core12.quadDivergentImplicitLod = descriptor_indexing_prop.quadDivergentImplicitLod;
1257 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSamplers =
1258 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSamplers;
1259 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindUniformBuffers =
1260 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindUniformBuffers;
1261 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageBuffers =
1262 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageBuffers;
1263 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSampledImages =
1264 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSampledImages;
1265 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageImages =
1266 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageImages;
1267 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindInputAttachments =
1268 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindInputAttachments;
1269 state_tracker->phys_dev_props_core12.maxPerStageUpdateAfterBindResources =
1270 descriptor_indexing_prop.maxPerStageUpdateAfterBindResources;
1271 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSamplers =
1272 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSamplers;
1273 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffers =
1274 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffers;
1275 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
1276 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
1277 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffers =
1278 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffers;
1279 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
1280 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
1281 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSampledImages =
1282 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSampledImages;
1283 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageImages =
1284 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageImages;
1285 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindInputAttachments =
1286 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindInputAttachments;
1287 }
1288
locke-lunargd556cc32019-09-17 01:21:23 -06001289 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_shading_rate_image, &phys_dev_props->shading_rate_image_props);
1290 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_mesh_shader, &phys_dev_props->mesh_shader_props);
1291 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_inline_uniform_block, &phys_dev_props->inline_uniform_block_props);
1292 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_vertex_attribute_divisor, &phys_dev_props->vtx_attrib_divisor_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001293
1294 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_khr_depth_stencil_resolve) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001295 VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve_props;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001296 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_depth_stencil_resolve, &depth_stencil_resolve_props);
1297 state_tracker->phys_dev_props_core12.supportedDepthResolveModes = depth_stencil_resolve_props.supportedDepthResolveModes;
1298 state_tracker->phys_dev_props_core12.supportedStencilResolveModes =
1299 depth_stencil_resolve_props.supportedStencilResolveModes;
1300 state_tracker->phys_dev_props_core12.independentResolveNone = depth_stencil_resolve_props.independentResolveNone;
1301 state_tracker->phys_dev_props_core12.independentResolve = depth_stencil_resolve_props.independentResolve;
1302 }
1303
locke-lunargd556cc32019-09-17 01:21:23 -06001304 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_transform_feedback, &phys_dev_props->transform_feedback_props);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001305 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_ray_tracing, &phys_dev_props->ray_tracing_propsNV);
sourav parmarcd5fb182020-07-17 12:58:44 -07001306 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_ray_tracing_pipeline, &phys_dev_props->ray_tracing_propsKHR);
1307 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_acceleration_structure, &phys_dev_props->acc_structure_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001308 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_texel_buffer_alignment, &phys_dev_props->texel_buffer_alignment_props);
1309 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map, &phys_dev_props->fragment_density_map_props);
Mike Schuchardtc57de4a2021-07-20 17:26:32 -07001310 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map2, &phys_dev_props->fragment_density_map2_props);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001311 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_performance_query, &phys_dev_props->performance_query_props);
sfricke-samsung8f658d42020-05-03 20:12:24 -07001312 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_sample_locations, &phys_dev_props->sample_locations_props);
Tony-LunarG7337b312020-04-15 16:40:25 -06001313 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_custom_border_color, &phys_dev_props->custom_border_color_props);
locke-lunarg3fa463a2020-10-23 16:39:04 -06001314 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_multiview, &phys_dev_props->multiview_props);
Nathaniel Cesario3291c912020-11-17 16:54:41 -07001315 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_portability_subset, &phys_dev_props->portability_props);
Locke Lin016d8482021-05-27 12:11:31 -06001316 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_provoking_vertex, &phys_dev_props->provoking_vertex_props);
Tony-LunarG4490de42021-06-21 15:49:19 -06001317 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_multi_draw, &phys_dev_props->multi_draw_props);
ziga-lunarg128904a2021-07-30 13:49:01 +02001318 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_discard_rectangles, &phys_dev_props->discard_rectangle_props);
ziga-lunarg86492812021-08-05 23:58:16 +02001319 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_blend_operation_advanced, &phys_dev_props->blend_operation_advanced_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001320
1321 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_khr_timeline_semaphore) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001322 VkPhysicalDeviceTimelineSemaphoreProperties timeline_semaphore_props;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001323 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_timeline_semaphore, &timeline_semaphore_props);
1324 state_tracker->phys_dev_props_core12.maxTimelineSemaphoreValueDifference =
1325 timeline_semaphore_props.maxTimelineSemaphoreValueDifference;
1326 }
1327
1328 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_khr_shader_float_controls) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001329 VkPhysicalDeviceFloatControlsProperties float_controls_props;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001330 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_shader_float_controls, &float_controls_props);
1331 state_tracker->phys_dev_props_core12.denormBehaviorIndependence = float_controls_props.denormBehaviorIndependence;
1332 state_tracker->phys_dev_props_core12.roundingModeIndependence = float_controls_props.roundingModeIndependence;
1333 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat16 =
1334 float_controls_props.shaderSignedZeroInfNanPreserveFloat16;
1335 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat32 =
1336 float_controls_props.shaderSignedZeroInfNanPreserveFloat32;
1337 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat64 =
1338 float_controls_props.shaderSignedZeroInfNanPreserveFloat64;
1339 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat16 = float_controls_props.shaderDenormPreserveFloat16;
1340 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat32 = float_controls_props.shaderDenormPreserveFloat32;
1341 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat64 = float_controls_props.shaderDenormPreserveFloat64;
1342 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat16 = float_controls_props.shaderDenormFlushToZeroFloat16;
1343 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat32 = float_controls_props.shaderDenormFlushToZeroFloat32;
1344 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat64 = float_controls_props.shaderDenormFlushToZeroFloat64;
1345 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat16 = float_controls_props.shaderRoundingModeRTEFloat16;
1346 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat32 = float_controls_props.shaderRoundingModeRTEFloat32;
1347 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat64 = float_controls_props.shaderRoundingModeRTEFloat64;
1348 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat16 = float_controls_props.shaderRoundingModeRTZFloat16;
1349 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat32 = float_controls_props.shaderRoundingModeRTZFloat32;
1350 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat64 = float_controls_props.shaderRoundingModeRTZFloat64;
1351 }
Mark Lobodzinskie4a2b7f2019-12-20 12:51:30 -07001352
locke-lunargd556cc32019-09-17 01:21:23 -06001353 if (state_tracker->device_extensions.vk_nv_cooperative_matrix) {
1354 // Get the needed cooperative_matrix properties
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001355 auto cooperative_matrix_props = LvlInitStruct<VkPhysicalDeviceCooperativeMatrixPropertiesNV>();
1356 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&cooperative_matrix_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001357 instance_dispatch_table.GetPhysicalDeviceProperties2KHR(gpu, &prop2);
1358 state_tracker->phys_dev_ext_props.cooperative_matrix_props = cooperative_matrix_props;
1359
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001360 uint32_t num_cooperative_matrix_properties = 0;
1361 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties, NULL);
1362 state_tracker->cooperative_matrix_properties.resize(num_cooperative_matrix_properties,
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001363 LvlInitStruct<VkCooperativeMatrixPropertiesNV>());
locke-lunargd556cc32019-09-17 01:21:23 -06001364
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001365 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties,
locke-lunargd556cc32019-09-17 01:21:23 -06001366 state_tracker->cooperative_matrix_properties.data());
1367 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001368 if (!state_tracker->device_extensions.vk_feature_version_1_2 && state_tracker->api_version >= VK_API_VERSION_1_1) {
locke-lunargd556cc32019-09-17 01:21:23 -06001369 // Get the needed subgroup limits
Locke Lin016d8482021-05-27 12:11:31 -06001370 auto subgroup_prop = LvlInitStruct<VkPhysicalDeviceSubgroupProperties>();
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001371 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&subgroup_prop);
locke-lunargd556cc32019-09-17 01:21:23 -06001372 instance_dispatch_table.GetPhysicalDeviceProperties2(gpu, &prop2);
1373
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001374 state_tracker->phys_dev_props_core11.subgroupSize = subgroup_prop.subgroupSize;
1375 state_tracker->phys_dev_props_core11.subgroupSupportedStages = subgroup_prop.supportedStages;
1376 state_tracker->phys_dev_props_core11.subgroupSupportedOperations = subgroup_prop.supportedOperations;
1377 state_tracker->phys_dev_props_core11.subgroupQuadOperationsInAllStages = subgroup_prop.quadOperationsInAllStages;
locke-lunargd556cc32019-09-17 01:21:23 -06001378 }
1379
Tobias Hector6663c9b2020-11-05 10:18:02 +00001380 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_fragment_shading_rate, &phys_dev_props->fragment_shading_rate_props);
1381
locke-lunargd556cc32019-09-17 01:21:23 -06001382 // Store queue family data
1383 if (pCreateInfo->pQueueCreateInfos != nullptr) {
1384 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
sfricke-samsung590ae1e2020-04-25 01:18:05 -07001385 const VkDeviceQueueCreateInfo &queue_create_info = pCreateInfo->pQueueCreateInfos[i];
sfricke-samsungb585ec12021-05-06 03:10:13 -07001386 state_tracker->queue_family_index_set.insert(queue_create_info.queueFamilyIndex);
1387 state_tracker->device_queue_info_list.push_back(
1388 {i, queue_create_info.queueFamilyIndex, queue_create_info.flags, queue_create_info.queueCount});
locke-lunargd556cc32019-09-17 01:21:23 -06001389 }
1390 }
1391}
1392
1393void ValidationStateTracker::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
1394 if (!device) return;
1395
locke-lunargd556cc32019-09-17 01:21:23 -06001396 // Reset all command buffers before destroying them, to unlink object_bindings.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001397 for (auto &command_buffer : commandBufferMap) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001398 command_buffer.second->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06001399 }
Jeff Bolzadbfa852019-10-04 13:53:30 -05001400 pipelineMap.clear();
1401 renderPassMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001402 commandBufferMap.clear();
1403
1404 // This will also delete all sets in the pool & remove them from setMap
1405 DeleteDescriptorSetPools();
1406 // All sets should be removed
1407 assert(setMap.empty());
1408 descriptorSetLayoutMap.clear();
Jeremy Gebben5a542f52021-07-21 15:25:52 -06001409 // Because swapchains are associated with Surfaces, which are at instance level,
1410 // they need to be explicitly destroyed here to avoid continued references to
1411 // the device we're destroying.
1412 for (auto &entry : swapchainMap) {
1413 entry.second->Destroy();
1414 }
1415 swapchainMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001416 imageViewMap.clear();
1417 imageMap.clear();
1418 bufferViewMap.clear();
1419 bufferMap.clear();
1420 // Queues persist until device is destroyed
1421 queueMap.clear();
1422}
1423
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001424void ValidationStateTracker::RetireWorkOnQueue(QUEUE_STATE *pQueue, uint64_t seq) {
Jeremy Gebbencbf22862021-03-03 12:01:22 -07001425 layer_data::unordered_map<VkQueue, uint64_t> other_queue_seqs;
1426 layer_data::unordered_map<VkSemaphore, uint64_t> timeline_semaphore_counters;
locke-lunargd556cc32019-09-17 01:21:23 -06001427
1428 // Roll this queue forward, one submission at a time.
1429 while (pQueue->seq < seq) {
1430 auto &submission = pQueue->submissions.front();
1431
1432 for (auto &wait : submission.waitSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001433 auto semaphore_state = GetSemaphoreState(wait.semaphore);
1434 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001435 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001436 }
Mike Schuchardt2df08912020-12-15 16:28:09 -08001437 if (wait.type == VK_SEMAPHORE_TYPE_TIMELINE) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001438 auto &last_counter = timeline_semaphore_counters[wait.semaphore];
1439 last_counter = std::max(last_counter, wait.payload);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001440 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001441 auto &last_seq = other_queue_seqs[wait.queue];
1442 last_seq = std::max(last_seq, wait.seq);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001443 }
locke-lunargd556cc32019-09-17 01:21:23 -06001444 }
1445
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001446 for (auto &signal : submission.signalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001447 auto semaphore_state = GetSemaphoreState(signal.semaphore);
1448 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001449 semaphore_state->EndUse();
Mike Schuchardt2df08912020-12-15 16:28:09 -08001450 if (semaphore_state->type == VK_SEMAPHORE_TYPE_TIMELINE && semaphore_state->payload < signal.payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001451 semaphore_state->payload = signal.payload;
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001452 }
locke-lunargd556cc32019-09-17 01:21:23 -06001453 }
1454 }
1455
1456 for (auto &semaphore : submission.externalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001457 auto semaphore_state = GetSemaphoreState(semaphore);
1458 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001459 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001460 }
1461 }
1462
1463 for (auto cb : submission.cbs) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06001464 auto cb_node = Get<CMD_BUFFER_STATE>(cb);
locke-lunargd556cc32019-09-17 01:21:23 -06001465 if (!cb_node) {
1466 continue;
1467 }
1468 // First perform decrement on general case bound objects
locke-lunargd556cc32019-09-17 01:21:23 -06001469 for (auto event : cb_node->writeEventsBeforeWait) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001470 auto event_node = eventMap.find(event);
1471 if (event_node != eventMap.end()) {
John Zulauf48057322020-12-02 11:59:31 -07001472 event_node->second->write_in_use--;
locke-lunargd556cc32019-09-17 01:21:23 -06001473 }
1474 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001475 QueryMap local_query_to_state_map;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001476 VkQueryPool first_pool = VK_NULL_HANDLE;
Jeff Bolz310775c2019-10-09 00:46:33 -05001477 for (auto &function : cb_node->queryUpdates) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001478 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
Jeff Bolz310775c2019-10-09 00:46:33 -05001479 }
1480
John Zulauf79f06582021-02-27 18:38:39 -07001481 for (const auto &query_state_pair : local_query_to_state_map) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001482 if (query_state_pair.second == QUERYSTATE_ENDED) {
1483 queryToStateMap[query_state_pair.first] = QUERYSTATE_AVAILABLE;
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001484 }
locke-lunargd556cc32019-09-17 01:21:23 -06001485 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001486 if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
1487 cb_node->EndUse();
1488 }
locke-lunargd556cc32019-09-17 01:21:23 -06001489 }
1490
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001491 auto fence_state = GetFenceState(submission.fence);
1492 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1493 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001494 }
1495
1496 pQueue->submissions.pop_front();
1497 pQueue->seq++;
1498 }
1499
1500 // Roll other queues forward to the highest seq we saw a wait for
John Zulauf79f06582021-02-27 18:38:39 -07001501 for (const auto &qs : other_queue_seqs) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001502 RetireWorkOnQueue(GetQueueState(qs.first), qs.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001503 }
John Zulauf79f06582021-02-27 18:38:39 -07001504 for (const auto &sc : timeline_semaphore_counters) {
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001505 RetireTimelineSemaphore(sc.first, sc.second);
1506 }
locke-lunargd556cc32019-09-17 01:21:23 -06001507}
1508
1509// Submit a fence to a queue, delimiting previous fences and previous untracked
1510// work by it.
1511static void SubmitFence(QUEUE_STATE *pQueue, FENCE_STATE *pFence, uint64_t submitCount) {
1512 pFence->state = FENCE_INFLIGHT;
1513 pFence->signaler.first = pQueue->queue;
1514 pFence->signaler.second = pQueue->seq + pQueue->submissions.size() + submitCount;
1515}
1516
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001517uint64_t ValidationStateTracker::RecordSubmitFence(QUEUE_STATE *queue_state, VkFence fence, uint32_t submit_count) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001518 auto fence_state = GetFenceState(fence);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001519 uint64_t early_retire_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001520 if (fence_state) {
1521 if (fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06001522 // Mark fence in use
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001523 SubmitFence(queue_state, fence_state, std::max(1u, submit_count));
1524 if (!submit_count) {
locke-lunargd556cc32019-09-17 01:21:23 -06001525 // If no submissions, but just dropping a fence on the end of the queue,
1526 // record an empty submission with just the fence, so we can determine
1527 // its completion.
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001528 CB_SUBMISSION submission;
1529 submission.fence = fence;
1530 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001531 }
1532 } else {
1533 // Retire work up until this fence early, we will not see the wait that corresponds to this signal
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001534 early_retire_seq = queue_state->seq + queue_state->submissions.size();
locke-lunargd556cc32019-09-17 01:21:23 -06001535 }
1536 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001537 return early_retire_seq;
1538}
1539
1540void ValidationStateTracker::RecordSubmitCommandBuffer(CB_SUBMISSION &submission, VkCommandBuffer command_buffer) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06001541 auto cb_node = Get<CMD_BUFFER_STATE>(command_buffer);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001542 if (cb_node) {
1543 submission.cbs.push_back(command_buffer);
John Zulauf79f06582021-02-27 18:38:39 -07001544 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001545 submission.cbs.push_back(secondary_cmd_buffer->commandBuffer());
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001546 secondary_cmd_buffer->IncrementResources();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001547 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001548 cb_node->IncrementResources();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001549 // increment use count for all bound objects including secondary cbs
1550 cb_node->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001551
1552 VkQueryPool first_pool = VK_NULL_HANDLE;
1553 EventToStageMap local_event_to_stage_map;
1554 QueryMap local_query_to_state_map;
1555 for (auto &function : cb_node->queryUpdates) {
1556 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
1557 }
1558
John Zulauf79f06582021-02-27 18:38:39 -07001559 for (const auto &query_state_pair : local_query_to_state_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001560 queryToStateMap[query_state_pair.first] = query_state_pair.second;
1561 }
1562
John Zulauf79f06582021-02-27 18:38:39 -07001563 for (const auto &function : cb_node->eventUpdates) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001564 function(nullptr, /*do_validate*/ false, &local_event_to_stage_map);
1565 }
1566
John Zulauf79f06582021-02-27 18:38:39 -07001567 for (const auto &eventStagePair : local_event_to_stage_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001568 eventMap[eventStagePair.first]->stageMask = eventStagePair.second;
1569 }
1570 }
1571}
1572
1573void ValidationStateTracker::RecordSubmitWaitSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1574 uint64_t value, uint64_t next_seq) {
1575 auto semaphore_state = GetSemaphoreState(semaphore);
1576 if (semaphore_state) {
1577 if (semaphore_state->scope == kSyncScopeInternal) {
1578 SEMAPHORE_WAIT wait;
1579 wait.semaphore = semaphore;
1580 wait.type = semaphore_state->type;
1581 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1582 if (semaphore_state->signaler.first != VK_NULL_HANDLE) {
1583 wait.queue = semaphore_state->signaler.first;
1584 wait.seq = semaphore_state->signaler.second;
1585 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001586 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001587 }
1588 semaphore_state->signaler.first = VK_NULL_HANDLE;
1589 semaphore_state->signaled = false;
1590 } else if (semaphore_state->payload < value) {
1591 wait.queue = queue;
1592 wait.seq = next_seq;
1593 wait.payload = value;
1594 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001595 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001596 }
1597 } else {
1598 submission.externalSemaphores.push_back(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001599 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001600 if (semaphore_state->scope == kSyncScopeExternalTemporary) {
1601 semaphore_state->scope = kSyncScopeInternal;
1602 }
1603 }
1604 }
1605}
1606
1607bool ValidationStateTracker::RecordSubmitSignalSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1608 uint64_t value, uint64_t next_seq) {
1609 bool retire_early = false;
1610 auto semaphore_state = GetSemaphoreState(semaphore);
1611 if (semaphore_state) {
1612 if (semaphore_state->scope == kSyncScopeInternal) {
1613 SEMAPHORE_SIGNAL signal;
1614 signal.semaphore = semaphore;
1615 signal.seq = next_seq;
1616 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1617 semaphore_state->signaler.first = queue;
1618 semaphore_state->signaler.second = next_seq;
1619 semaphore_state->signaled = true;
1620 } else {
1621 signal.payload = value;
1622 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001623 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001624 submission.signalSemaphores.emplace_back(std::move(signal));
1625 } else {
1626 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1627 retire_early = true;
1628 }
1629 }
1630 return retire_early;
1631}
1632
1633void ValidationStateTracker::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
1634 VkFence fence, VkResult result) {
1635 if (result != VK_SUCCESS) return;
1636 auto queue_state = GetQueueState(queue);
1637
1638 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001639
1640 // Now process each individual submit
1641 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001642 CB_SUBMISSION submission;
locke-lunargd556cc32019-09-17 01:21:23 -06001643 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001644 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001645 auto *timeline_semaphore_submit = LvlFindInChain<VkTimelineSemaphoreSubmitInfo>(submit->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001646 for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001647 uint64_t value = 0;
1648 if (timeline_semaphore_submit && timeline_semaphore_submit->pWaitSemaphoreValues != nullptr &&
1649 (i < timeline_semaphore_submit->waitSemaphoreValueCount)) {
1650 value = timeline_semaphore_submit->pWaitSemaphoreValues[i];
1651 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001652 RecordSubmitWaitSemaphore(submission, queue, submit->pWaitSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001653 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001654
1655 bool retire_early = false;
locke-lunargd556cc32019-09-17 01:21:23 -06001656 for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001657 uint64_t value = 0;
1658 if (timeline_semaphore_submit && timeline_semaphore_submit->pSignalSemaphoreValues != nullptr &&
1659 (i < timeline_semaphore_submit->signalSemaphoreValueCount)) {
1660 value = timeline_semaphore_submit->pSignalSemaphoreValues[i];
1661 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001662 retire_early |= RecordSubmitSignalSemaphore(submission, queue, submit->pSignalSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001663 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001664 if (retire_early) {
1665 early_retire_seq = std::max(early_retire_seq, next_seq);
1666 }
1667
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001668 const auto perf_submit = LvlFindInChain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001669 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001670
locke-lunargd556cc32019-09-17 01:21:23 -06001671 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001672 RecordSubmitCommandBuffer(submission, submit->pCommandBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06001673 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001674 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1675 queue_state->submissions.emplace_back(std::move(submission));
1676 }
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001677
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001678 if (early_retire_seq) {
1679 RetireWorkOnQueue(queue_state, early_retire_seq);
1680 }
1681}
1682
1683void ValidationStateTracker::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1684 VkFence fence, VkResult result) {
1685 if (result != VK_SUCCESS) return;
1686 auto queue_state = GetQueueState(queue);
1687
1688 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
1689
1690 // Now process each individual submit
1691 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1692 CB_SUBMISSION submission;
1693 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1694 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
1695 for (uint32_t i = 0; i < submit->waitSemaphoreInfoCount; ++i) {
1696 const auto &sem_info = submit->pWaitSemaphoreInfos[i];
1697 RecordSubmitWaitSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1698 }
1699 bool retire_early = false;
1700 for (uint32_t i = 0; i < submit->signalSemaphoreInfoCount; ++i) {
1701 const auto &sem_info = submit->pSignalSemaphoreInfos[i];
1702 retire_early |= RecordSubmitSignalSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1703 }
1704 if (retire_early) {
1705 early_retire_seq = std::max(early_retire_seq, next_seq);
1706 }
1707 const auto perf_submit = lvl_find_in_chain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
1708 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
1709
1710 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1711 RecordSubmitCommandBuffer(submission, submit->pCommandBufferInfos[i].commandBuffer);
1712 }
1713 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1714 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001715 }
1716
1717 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001718 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001719 }
1720}
1721
1722void ValidationStateTracker::PostCallRecordAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
1723 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory,
1724 VkResult result) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001725 if (VK_SUCCESS != result) {
1726 return;
locke-lunargd556cc32019-09-17 01:21:23 -06001727 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001728 const auto &memory_type = phys_dev_mem_props.memoryTypes[pAllocateInfo->memoryTypeIndex];
1729 const auto &memory_heap = phys_dev_mem_props.memoryHeaps[memory_type.heapIndex];
1730 auto fake_address = fake_memory.Alloc(pAllocateInfo->allocationSize);
1731
1732 layer_data::optional<DedicatedBinding> dedicated_binding;
1733
1734 auto dedicated = LvlFindInChain<VkMemoryDedicatedAllocateInfo>(pAllocateInfo->pNext);
1735 if (dedicated) {
1736 if (dedicated->buffer) {
1737 const auto *buffer_state = GetBufferState(dedicated->buffer);
1738 assert(buffer_state);
1739 if (!buffer_state) {
1740 return;
1741 }
1742 dedicated_binding.emplace(dedicated->buffer, buffer_state->createInfo);
1743 } else if (dedicated->image) {
1744 const auto *image_state = GetImageState(dedicated->image);
1745 assert(image_state);
1746 if (!image_state) {
1747 return;
1748 }
1749 dedicated_binding.emplace(dedicated->image, image_state->createInfo);
1750 }
1751 }
1752 memObjMap[*pMemory] = std::make_shared<DEVICE_MEMORY_STATE>(*pMemory, pAllocateInfo, fake_address, memory_type, memory_heap,
1753 std::move(dedicated_binding));
locke-lunargd556cc32019-09-17 01:21:23 -06001754 return;
1755}
1756
1757void ValidationStateTracker::PreCallRecordFreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
1758 if (!mem) return;
1759 DEVICE_MEMORY_STATE *mem_info = GetDevMemState(mem);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001760 if (!mem_info) return;
locke-lunargd556cc32019-09-17 01:21:23 -06001761 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001762 mem_info->Destroy();
John Zulauf79952712020-04-07 11:25:54 -06001763 fake_memory.Free(mem_info->fake_base_address);
locke-lunargd556cc32019-09-17 01:21:23 -06001764 memObjMap.erase(mem);
1765}
1766
1767void ValidationStateTracker::PostCallRecordQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo,
1768 VkFence fence, VkResult result) {
1769 if (result != VK_SUCCESS) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001770 auto queue_state = GetQueueState(queue);
locke-lunargd556cc32019-09-17 01:21:23 -06001771
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001772 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, bindInfoCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001773
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001774 for (uint32_t bind_idx = 0; bind_idx < bindInfoCount; ++bind_idx) {
1775 const VkBindSparseInfo &bind_info = pBindInfo[bind_idx];
locke-lunargd556cc32019-09-17 01:21:23 -06001776 // Track objects tied to memory
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001777 for (uint32_t j = 0; j < bind_info.bufferBindCount; j++) {
1778 for (uint32_t k = 0; k < bind_info.pBufferBinds[j].bindCount; k++) {
1779 auto sparse_binding = bind_info.pBufferBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001780 auto buffer_state = GetBufferState(bind_info.pBufferBinds[j].buffer);
1781 auto mem_state = GetDevMemShared(sparse_binding.memory);
1782 if (buffer_state && mem_state) {
1783 buffer_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1784 }
locke-lunargd556cc32019-09-17 01:21:23 -06001785 }
1786 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001787 for (uint32_t j = 0; j < bind_info.imageOpaqueBindCount; j++) {
1788 for (uint32_t k = 0; k < bind_info.pImageOpaqueBinds[j].bindCount; k++) {
1789 auto sparse_binding = bind_info.pImageOpaqueBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001790 auto image_state = GetImageState(bind_info.pImageOpaqueBinds[j].image);
1791 auto mem_state = GetDevMemShared(sparse_binding.memory);
1792 if (image_state && mem_state) {
1793 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1794 }
locke-lunargd556cc32019-09-17 01:21:23 -06001795 }
1796 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001797 for (uint32_t j = 0; j < bind_info.imageBindCount; j++) {
1798 for (uint32_t k = 0; k < bind_info.pImageBinds[j].bindCount; k++) {
1799 auto sparse_binding = bind_info.pImageBinds[j].pBinds[k];
locke-lunargd556cc32019-09-17 01:21:23 -06001800 // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data
1801 VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001802 auto image_state = GetImageState(bind_info.pImageBinds[j].image);
1803 auto mem_state = GetDevMemShared(sparse_binding.memory);
1804 if (image_state && mem_state) {
1805 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, size);
1806 }
locke-lunargd556cc32019-09-17 01:21:23 -06001807 }
1808 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001809 CB_SUBMISSION submission;
1810 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001811 for (uint32_t i = 0; i < bind_info.waitSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001812 RecordSubmitWaitSemaphore(submission, queue, bind_info.pWaitSemaphores[i], 0, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001813 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001814 bool retire_early = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001815 for (uint32_t i = 0; i < bind_info.signalSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001816 retire_early |= RecordSubmitSignalSemaphore(submission, queue, bind_info.pSignalSemaphores[i], 0, next_seq);
1817 }
1818 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1819 if (retire_early) {
1820 early_retire_seq = std::max(early_retire_seq, queue_state->seq + queue_state->submissions.size() + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06001821 }
1822
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001823 submission.fence = bind_idx == (bindInfoCount - 1) ? fence : VK_NULL_HANDLE;
1824 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001825 }
1826
1827 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001828 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001829 }
1830}
1831
1832void ValidationStateTracker::PostCallRecordCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
1833 const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore,
1834 VkResult result) {
1835 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001836 semaphoreMap[*pSemaphore] = std::make_shared<SEMAPHORE_STATE>(*pSemaphore, LvlFindInChain<VkSemaphoreTypeCreateInfo>(pCreateInfo->pNext));
locke-lunargd556cc32019-09-17 01:21:23 -06001837}
1838
Mike Schuchardt2df08912020-12-15 16:28:09 -08001839void ValidationStateTracker::RecordImportSemaphoreState(VkSemaphore semaphore, VkExternalSemaphoreHandleTypeFlagBits handle_type,
1840 VkSemaphoreImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06001841 SEMAPHORE_STATE *sema_node = GetSemaphoreState(semaphore);
1842 if (sema_node && sema_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001843 if ((handle_type == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06001844 sema_node->scope == kSyncScopeInternal) {
1845 sema_node->scope = kSyncScopeExternalTemporary;
1846 } else {
1847 sema_node->scope = kSyncScopeExternalPermanent;
1848 }
1849 }
1850}
1851
Mike Schuchardt2df08912020-12-15 16:28:09 -08001852void ValidationStateTracker::PostCallRecordSignalSemaphoreKHR(VkDevice device, const VkSemaphoreSignalInfo *pSignalInfo,
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001853 VkResult result) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001854 auto *semaphore_state = GetSemaphoreState(pSignalInfo->semaphore);
1855 semaphore_state->payload = pSignalInfo->value;
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001856}
1857
locke-lunargd556cc32019-09-17 01:21:23 -06001858void ValidationStateTracker::RecordMappedMemory(VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, void **ppData) {
1859 auto mem_info = GetDevMemState(mem);
1860 if (mem_info) {
1861 mem_info->mapped_range.offset = offset;
1862 mem_info->mapped_range.size = size;
1863 mem_info->p_driver_data = *ppData;
1864 }
1865}
1866
1867void ValidationStateTracker::RetireFence(VkFence fence) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001868 auto fence_state = GetFenceState(fence);
1869 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1870 if (fence_state->signaler.first != VK_NULL_HANDLE) {
locke-lunargd556cc32019-09-17 01:21:23 -06001871 // Fence signaller is a queue -- use this as proof that prior operations on that queue have completed.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001872 RetireWorkOnQueue(GetQueueState(fence_state->signaler.first), fence_state->signaler.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001873 } else {
1874 // Fence signaller is the WSI. We're not tracking what the WSI op actually /was/ in CV yet, but we need to mark
1875 // the fence as retired.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001876 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001877 }
1878 }
1879}
1880
1881void ValidationStateTracker::PostCallRecordWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
1882 VkBool32 waitAll, uint64_t timeout, VkResult result) {
1883 if (VK_SUCCESS != result) return;
1884
1885 // When we know that all fences are complete we can clean/remove their CBs
1886 if ((VK_TRUE == waitAll) || (1 == fenceCount)) {
1887 for (uint32_t i = 0; i < fenceCount; i++) {
1888 RetireFence(pFences[i]);
1889 }
1890 }
1891 // NOTE : Alternate case not handled here is when some fences have completed. In
1892 // this case for app to guarantee which fences completed it will have to call
1893 // vkGetFenceStatus() at which point we'll clean/remove their CBs if complete.
1894}
1895
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001896void ValidationStateTracker::RetireTimelineSemaphore(VkSemaphore semaphore, uint64_t until_payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001897 auto semaphore_state = GetSemaphoreState(semaphore);
1898 if (semaphore_state) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001899 for (auto &pair : queueMap) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001900 QUEUE_STATE &queue_state = pair.second;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001901 uint64_t max_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001902 for (const auto &submission : queue_state.submissions) {
1903 for (const auto &signal_semaphore : submission.signalSemaphores) {
1904 if (signal_semaphore.semaphore == semaphore && signal_semaphore.payload <= until_payload) {
1905 if (signal_semaphore.seq > max_seq) {
1906 max_seq = signal_semaphore.seq;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001907 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001908 }
1909 }
1910 }
Tony-LunarG47d5e272020-04-07 15:35:55 -06001911 if (max_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001912 RetireWorkOnQueue(&queue_state, max_seq);
Tony-LunarG47d5e272020-04-07 15:35:55 -06001913 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001914 }
1915 }
1916}
1917
John Zulauff89de662020-04-13 18:57:34 -06001918void ValidationStateTracker::RecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1919 VkResult result) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001920 if (VK_SUCCESS != result) return;
1921
1922 for (uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++) {
1923 RetireTimelineSemaphore(pWaitInfo->pSemaphores[i], pWaitInfo->pValues[i]);
1924 }
1925}
1926
John Zulauff89de662020-04-13 18:57:34 -06001927void ValidationStateTracker::PostCallRecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1928 VkResult result) {
1929 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1930}
1931
1932void ValidationStateTracker::PostCallRecordWaitSemaphoresKHR(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo,
1933 uint64_t timeout, VkResult result) {
1934 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1935}
1936
Adrian Coca Lorentec7d76102020-09-28 13:58:16 +02001937void ValidationStateTracker::RecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1938 VkResult result) {
1939 if (VK_SUCCESS != result) return;
1940
1941 RetireTimelineSemaphore(semaphore, *pValue);
1942}
1943
1944void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1945 VkResult result) {
1946 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1947}
1948void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1949 VkResult result) {
1950 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1951}
1952
locke-lunargd556cc32019-09-17 01:21:23 -06001953void ValidationStateTracker::PostCallRecordGetFenceStatus(VkDevice device, VkFence fence, VkResult result) {
1954 if (VK_SUCCESS != result) return;
1955 RetireFence(fence);
1956}
1957
1958void ValidationStateTracker::RecordGetDeviceQueueState(uint32_t queue_family_index, VkQueue queue) {
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06001959 queueMap.emplace(queue, QUEUE_STATE(queue, queue_family_index));
locke-lunargd556cc32019-09-17 01:21:23 -06001960}
1961
1962void ValidationStateTracker::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
1963 VkQueue *pQueue) {
1964 RecordGetDeviceQueueState(queueFamilyIndex, *pQueue);
1965}
1966
1967void ValidationStateTracker::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
1968 RecordGetDeviceQueueState(pQueueInfo->queueFamilyIndex, *pQueue);
1969}
1970
1971void ValidationStateTracker::PostCallRecordQueueWaitIdle(VkQueue queue, VkResult result) {
1972 if (VK_SUCCESS != result) return;
1973 QUEUE_STATE *queue_state = GetQueueState(queue);
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001974 RetireWorkOnQueue(queue_state, queue_state->seq + queue_state->submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001975}
1976
1977void ValidationStateTracker::PostCallRecordDeviceWaitIdle(VkDevice device, VkResult result) {
1978 if (VK_SUCCESS != result) return;
1979 for (auto &queue : queueMap) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001980 RetireWorkOnQueue(&queue.second, queue.second.seq + queue.second.submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001981 }
1982}
1983
1984void ValidationStateTracker::PreCallRecordDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
1985 if (!fence) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001986 auto fence_state = GetFenceState(fence);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001987 fence_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06001988 fenceMap.erase(fence);
1989}
1990
1991void ValidationStateTracker::PreCallRecordDestroySemaphore(VkDevice device, VkSemaphore semaphore,
1992 const VkAllocationCallbacks *pAllocator) {
1993 if (!semaphore) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001994 auto semaphore_state = GetSemaphoreState(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001995 semaphore_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06001996 semaphoreMap.erase(semaphore);
1997}
1998
1999void ValidationStateTracker::PreCallRecordDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
2000 if (!event) return;
John Zulauf48057322020-12-02 11:59:31 -07002001 EVENT_STATE *event_state = Get<EVENT_STATE>(event);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002002 event_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002003 eventMap.erase(event);
2004}
2005
2006void ValidationStateTracker::PreCallRecordDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
2007 const VkAllocationCallbacks *pAllocator) {
2008 if (!queryPool) return;
2009 QUERY_POOL_STATE *qp_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002010 qp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002011 queryPoolMap.erase(queryPool);
2012}
2013
locke-lunargd556cc32019-09-17 01:21:23 -06002014void ValidationStateTracker::UpdateBindBufferMemoryState(VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memoryOffset) {
2015 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2016 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002017 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002018 auto mem_state = GetDevMemShared(mem);
2019 if (mem_state) {
2020 buffer_state->SetMemBinding(mem_state, memoryOffset);
2021 }
locke-lunargd556cc32019-09-17 01:21:23 -06002022 }
2023}
2024
2025void ValidationStateTracker::PostCallRecordBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
2026 VkDeviceSize memoryOffset, VkResult result) {
2027 if (VK_SUCCESS != result) return;
2028 UpdateBindBufferMemoryState(buffer, mem, memoryOffset);
2029}
2030
2031void ValidationStateTracker::PostCallRecordBindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002032 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002033 for (uint32_t i = 0; i < bindInfoCount; i++) {
2034 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2035 }
2036}
2037
2038void ValidationStateTracker::PostCallRecordBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002039 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002040 for (uint32_t i = 0; i < bindInfoCount; i++) {
2041 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2042 }
2043}
2044
Spencer Fricke6c127102020-04-16 06:25:20 -07002045void ValidationStateTracker::RecordGetBufferMemoryRequirementsState(VkBuffer buffer) {
locke-lunargd556cc32019-09-17 01:21:23 -06002046 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2047 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002048 buffer_state->memory_requirements_checked = true;
2049 }
2050}
2051
2052void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
2053 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002054 RecordGetBufferMemoryRequirementsState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002055}
2056
2057void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002058 const VkBufferMemoryRequirementsInfo2 *pInfo,
2059 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002060 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002061}
2062
2063void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2KHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002064 const VkBufferMemoryRequirementsInfo2 *pInfo,
2065 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002066 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002067}
2068
Spencer Fricke6c127102020-04-16 06:25:20 -07002069void ValidationStateTracker::RecordGetImageMemoryRequirementsState(VkImage image, const VkImageMemoryRequirementsInfo2 *pInfo) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002070 const VkImagePlaneMemoryRequirementsInfo *plane_info =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002071 (pInfo == nullptr) ? nullptr : LvlFindInChain<VkImagePlaneMemoryRequirementsInfo>(pInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06002072 IMAGE_STATE *image_state = GetImageState(image);
2073 if (image_state) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002074 if (plane_info != nullptr) {
2075 // Multi-plane image
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002076 if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_0_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002077 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002078 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_1_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002079 image_state->memory_requirements_checked[1] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002080 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_2_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002081 image_state->memory_requirements_checked[2] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002082 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002083 } else if (!image_state->disjoint) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002084 // Single Plane image
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002085 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002086 }
locke-lunargd556cc32019-09-17 01:21:23 -06002087 }
2088}
2089
2090void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements(VkDevice device, VkImage image,
2091 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002092 RecordGetImageMemoryRequirementsState(image, nullptr);
locke-lunargd556cc32019-09-17 01:21:23 -06002093}
2094
2095void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo,
2096 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002097 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002098}
2099
2100void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2KHR(VkDevice device,
2101 const VkImageMemoryRequirementsInfo2 *pInfo,
2102 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002103 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002104}
2105
2106static void RecordGetImageSparseMemoryRequirementsState(IMAGE_STATE *image_state,
2107 VkSparseImageMemoryRequirements *sparse_image_memory_requirements) {
2108 image_state->sparse_requirements.emplace_back(*sparse_image_memory_requirements);
2109 if (sparse_image_memory_requirements->formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) {
2110 image_state->sparse_metadata_required = true;
2111 }
2112}
2113
2114void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements(
2115 VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
2116 VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
2117 auto image_state = GetImageState(image);
2118 image_state->get_sparse_reqs_called = true;
2119 if (!pSparseMemoryRequirements) return;
2120 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2121 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i]);
2122 }
2123}
2124
2125void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002126 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2127 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002128 auto image_state = GetImageState(pInfo->image);
2129 image_state->get_sparse_reqs_called = true;
2130 if (!pSparseMemoryRequirements) return;
2131 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2132 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2133 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2134 }
2135}
2136
2137void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002138 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2139 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002140 auto image_state = GetImageState(pInfo->image);
2141 image_state->get_sparse_reqs_called = true;
2142 if (!pSparseMemoryRequirements) return;
2143 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2144 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2145 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2146 }
2147}
2148
2149void ValidationStateTracker::PreCallRecordDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
2150 const VkAllocationCallbacks *pAllocator) {
2151 if (!shaderModule) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002152 auto shader_module_state = GetShaderModuleState(shaderModule);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002153 shader_module_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002154 shaderModuleMap.erase(shaderModule);
2155}
2156
2157void ValidationStateTracker::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline,
2158 const VkAllocationCallbacks *pAllocator) {
2159 if (!pipeline) return;
2160 PIPELINE_STATE *pipeline_state = GetPipelineState(pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06002161 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002162 pipeline_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002163 pipelineMap.erase(pipeline);
2164}
2165
2166void ValidationStateTracker::PreCallRecordDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
2167 const VkAllocationCallbacks *pAllocator) {
2168 if (!pipelineLayout) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002169 auto pipeline_layout_state = GetPipelineLayout(pipelineLayout);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002170 pipeline_layout_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002171 pipelineLayoutMap.erase(pipelineLayout);
2172}
2173
2174void ValidationStateTracker::PreCallRecordDestroySampler(VkDevice device, VkSampler sampler,
2175 const VkAllocationCallbacks *pAllocator) {
2176 if (!sampler) return;
2177 SAMPLER_STATE *sampler_state = GetSamplerState(sampler);
locke-lunargd556cc32019-09-17 01:21:23 -06002178 // Any bound cmd buffers are now invalid
2179 if (sampler_state) {
Yuly Novikov424cdd52020-05-26 16:45:12 -04002180 if (sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2181 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
2182 custom_border_color_sampler_count--;
2183 }
2184
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002185 sampler_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002186 }
2187 samplerMap.erase(sampler);
2188}
2189
2190void ValidationStateTracker::PreCallRecordDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
2191 const VkAllocationCallbacks *pAllocator) {
2192 if (!descriptorSetLayout) return;
2193 auto layout_it = descriptorSetLayoutMap.find(descriptorSetLayout);
2194 if (layout_it != descriptorSetLayoutMap.end()) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002195 layout_it->second.get()->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002196 descriptorSetLayoutMap.erase(layout_it);
2197 }
2198}
2199
2200void ValidationStateTracker::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2201 const VkAllocationCallbacks *pAllocator) {
2202 if (!descriptorPool) return;
2203 DESCRIPTOR_POOL_STATE *desc_pool_state = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002204 if (desc_pool_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002205 // Free sets that were in this pool
John Zulauf79f06582021-02-27 18:38:39 -07002206 for (auto *ds : desc_pool_state->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002207 FreeDescriptorSet(ds);
2208 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002209 desc_pool_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002210 descriptorPoolMap.erase(descriptorPool);
2211 }
2212}
2213
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002214// Free all command buffers in given list, removing all references/links to them using CMD_BUFFER_STATE::Reset
locke-lunargd556cc32019-09-17 01:21:23 -06002215void ValidationStateTracker::FreeCommandBufferStates(COMMAND_POOL_STATE *pool_state, const uint32_t command_buffer_count,
2216 const VkCommandBuffer *command_buffers) {
2217 for (uint32_t i = 0; i < command_buffer_count; i++) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002218 auto cb_state = Get<CMD_BUFFER_STATE>(command_buffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002219 // Remove references to command buffer's state and delete
2220 if (cb_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002221 cb_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002222 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002223 // Remove CBState from CB map
2224 pool_state->commandBuffers.erase(command_buffers[i]);
2225 commandBufferMap.erase(command_buffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002226 }
2227}
2228
2229void ValidationStateTracker::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
2230 uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002231 auto pool = GetCommandPoolState(commandPool);
2232 FreeCommandBufferStates(pool, commandBufferCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06002233}
2234
2235void ValidationStateTracker::PostCallRecordCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
2236 const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool,
2237 VkResult result) {
2238 if (VK_SUCCESS != result) return;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06002239 auto queue_flags = GetPhysicalDeviceState()->queue_family_properties[pCreateInfo->queueFamilyIndex].queueFlags;
2240 commandPoolMap[*pCommandPool] = std::make_shared<COMMAND_POOL_STATE>(*pCommandPool, pCreateInfo, queue_flags);
locke-lunargd556cc32019-09-17 01:21:23 -06002241}
2242
2243void ValidationStateTracker::PostCallRecordCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
2244 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool,
2245 VkResult result) {
2246 if (VK_SUCCESS != result) return;
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002247
2248 uint32_t index_count = 0, n_perf_pass = 0;
2249 bool has_cb = false, has_rb = false;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002250 if (pCreateInfo->queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002251 const auto *perf = LvlFindInChain<VkQueryPoolPerformanceCreateInfoKHR>(pCreateInfo->pNext);
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002252 index_count = perf->counterIndexCount;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002253
Mark Lobodzinski7e948e42020-09-09 10:23:36 -06002254 const QUEUE_FAMILY_PERF_COUNTERS &counters = *physical_device_state->perf_counters[perf->queueFamilyIndex];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002255 for (uint32_t i = 0; i < perf->counterIndexCount; i++) {
2256 const auto &counter = counters.counters[perf->pCounterIndices[i]];
2257 switch (counter.scope) {
2258 case VK_QUERY_SCOPE_COMMAND_BUFFER_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002259 has_cb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002260 break;
2261 case VK_QUERY_SCOPE_RENDER_PASS_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002262 has_rb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002263 break;
2264 default:
2265 break;
2266 }
2267 }
2268
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002269 DispatchGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physical_device_state->phys_device, perf, &n_perf_pass);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002270 }
2271
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002272 queryPoolMap[*pQueryPool] =
2273 std::make_shared<QUERY_POOL_STATE>(*pQueryPool, pCreateInfo, index_count, n_perf_pass, has_cb, has_rb);
locke-lunargd556cc32019-09-17 01:21:23 -06002274
2275 QueryObject query_obj{*pQueryPool, 0u};
2276 for (uint32_t i = 0; i < pCreateInfo->queryCount; ++i) {
2277 query_obj.query = i;
2278 queryToStateMap[query_obj] = QUERYSTATE_UNKNOWN;
2279 }
2280}
2281
2282void ValidationStateTracker::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
2283 const VkAllocationCallbacks *pAllocator) {
2284 if (!commandPool) return;
2285 COMMAND_POOL_STATE *cp_state = GetCommandPoolState(commandPool);
2286 // Remove cmdpool from cmdpoolmap, after freeing layer data for the command buffers
2287 // "When a pool is destroyed, all command buffers allocated from the pool are freed."
2288 if (cp_state) {
2289 // Create a vector, as FreeCommandBufferStates deletes from cp_state->commandBuffers during iteration.
2290 std::vector<VkCommandBuffer> cb_vec{cp_state->commandBuffers.begin(), cp_state->commandBuffers.end()};
2291 FreeCommandBufferStates(cp_state, static_cast<uint32_t>(cb_vec.size()), cb_vec.data());
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002292 cp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002293 commandPoolMap.erase(commandPool);
2294 }
2295}
2296
2297void ValidationStateTracker::PostCallRecordResetCommandPool(VkDevice device, VkCommandPool commandPool,
2298 VkCommandPoolResetFlags flags, VkResult result) {
2299 if (VK_SUCCESS != result) return;
2300 // Reset all of the CBs allocated from this pool
2301 auto command_pool_state = GetCommandPoolState(commandPool);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002302 for (auto cmd_buffer : command_pool_state->commandBuffers) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002303 auto cb_state = Get<CMD_BUFFER_STATE>(cmd_buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002304 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002305 }
2306}
2307
2308void ValidationStateTracker::PostCallRecordResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
2309 VkResult result) {
2310 for (uint32_t i = 0; i < fenceCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002311 auto fence_state = GetFenceState(pFences[i]);
2312 if (fence_state) {
2313 if (fence_state->scope == kSyncScopeInternal) {
2314 fence_state->state = FENCE_UNSIGNALED;
2315 } else if (fence_state->scope == kSyncScopeExternalTemporary) {
2316 fence_state->scope = kSyncScopeInternal;
locke-lunargd556cc32019-09-17 01:21:23 -06002317 }
2318 }
2319 }
2320}
2321
locke-lunargd556cc32019-09-17 01:21:23 -06002322void ValidationStateTracker::PreCallRecordDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
2323 const VkAllocationCallbacks *pAllocator) {
2324 if (!framebuffer) return;
2325 FRAMEBUFFER_STATE *framebuffer_state = GetFramebufferState(framebuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002326 framebuffer_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002327 frameBufferMap.erase(framebuffer);
2328}
2329
2330void ValidationStateTracker::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
2331 const VkAllocationCallbacks *pAllocator) {
2332 if (!renderPass) return;
2333 RENDER_PASS_STATE *rp_state = GetRenderPassState(renderPass);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002334 rp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002335 renderPassMap.erase(renderPass);
2336}
2337
2338void ValidationStateTracker::PostCallRecordCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
2339 const VkAllocationCallbacks *pAllocator, VkFence *pFence, VkResult result) {
2340 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002341 fenceMap[*pFence] = std::make_shared<FENCE_STATE>(*pFence, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002342}
2343
2344bool ValidationStateTracker::PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2345 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2346 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002347 void *cgpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002348 // Set up the state that CoreChecks, gpu_validation and later StateTracker Record will use.
2349 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2350 cgpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2351 cgpl_state->pipe_state.reserve(count);
2352 for (uint32_t i = 0; i < count; i++) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002353 cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
Jeff Bolz6ae39612019-10-11 20:57:36 -05002354 (cgpl_state->pipe_state)[i]->initGraphicsPipeline(this, &pCreateInfos[i], GetRenderPassShared(pCreateInfos[i].renderPass));
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002355 (cgpl_state->pipe_state)[i]->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002356 }
2357 return false;
2358}
2359
2360void ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2361 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2362 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2363 VkResult result, void *cgpl_state_data) {
2364 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2365 // This API may create pipelines regardless of the return value
2366 for (uint32_t i = 0; i < count; i++) {
2367 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002368 (cgpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002369 pipelineMap[pPipelines[i]] = std::move((cgpl_state->pipe_state)[i]);
2370 }
2371 }
2372 cgpl_state->pipe_state.clear();
2373}
2374
2375bool ValidationStateTracker::PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2376 const VkComputePipelineCreateInfo *pCreateInfos,
2377 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002378 void *ccpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002379 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2380 ccpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2381 ccpl_state->pipe_state.reserve(count);
2382 for (uint32_t i = 0; i < count; i++) {
2383 // Create and initialize internal tracking data structure
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002384 ccpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
locke-lunargd556cc32019-09-17 01:21:23 -06002385 ccpl_state->pipe_state.back()->initComputePipeline(this, &pCreateInfos[i]);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002386 ccpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002387 }
2388 return false;
2389}
2390
2391void ValidationStateTracker::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2392 const VkComputePipelineCreateInfo *pCreateInfos,
2393 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2394 VkResult result, void *ccpl_state_data) {
2395 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2396
2397 // This API may create pipelines regardless of the return value
2398 for (uint32_t i = 0; i < count; i++) {
2399 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002400 (ccpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002401 pipelineMap[pPipelines[i]] = std::move((ccpl_state->pipe_state)[i]);
2402 }
2403 }
2404 ccpl_state->pipe_state.clear();
2405}
2406
2407bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache,
2408 uint32_t count,
2409 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2410 const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002411 VkPipeline *pPipelines, void *crtpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002412 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2413 crtpl_state->pipe_state.reserve(count);
2414 for (uint32_t i = 0; i < count; i++) {
2415 // Create and initialize internal tracking data structure
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002416 crtpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002417 crtpl_state->pipe_state.back()->initRayTracingPipeline(this, &pCreateInfos[i]);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002418 crtpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002419 }
2420 return false;
2421}
2422
2423void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(
2424 VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2425 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines, VkResult result, void *crtpl_state_data) {
2426 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2427 // This API may create pipelines regardless of the return value
2428 for (uint32_t i = 0; i < count; i++) {
2429 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002430 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002431 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2432 }
2433 }
2434 crtpl_state->pipe_state.clear();
2435}
2436
sourav parmarcd5fb182020-07-17 12:58:44 -07002437bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2438 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002439 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2440 const VkAllocationCallbacks *pAllocator,
2441 VkPipeline *pPipelines, void *crtpl_state_data) const {
2442 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2443 crtpl_state->pipe_state.reserve(count);
2444 for (uint32_t i = 0; i < count; i++) {
2445 // Create and initialize internal tracking data structure
2446 crtpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
2447 crtpl_state->pipe_state.back()->initRayTracingPipeline(this, &pCreateInfos[i]);
2448 crtpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
2449 }
2450 return false;
2451}
2452
sourav parmarcd5fb182020-07-17 12:58:44 -07002453void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2454 VkPipelineCache pipelineCache, uint32_t count,
2455 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2456 const VkAllocationCallbacks *pAllocator,
2457 VkPipeline *pPipelines, VkResult result,
2458 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002459 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2460 // This API may create pipelines regardless of the return value
2461 for (uint32_t i = 0; i < count; i++) {
2462 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002463 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002464 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2465 }
2466 }
2467 crtpl_state->pipe_state.clear();
2468}
2469
locke-lunargd556cc32019-09-17 01:21:23 -06002470void ValidationStateTracker::PostCallRecordCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
2471 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler,
2472 VkResult result) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002473 samplerMap[*pSampler] = std::make_shared<SAMPLER_STATE>(pSampler, pCreateInfo);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002474 if (pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2475 pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
Tony-LunarG7337b312020-04-15 16:40:25 -06002476 custom_border_color_sampler_count++;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002477 }
locke-lunargd556cc32019-09-17 01:21:23 -06002478}
2479
2480void ValidationStateTracker::PostCallRecordCreateDescriptorSetLayout(VkDevice device,
2481 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
2482 const VkAllocationCallbacks *pAllocator,
2483 VkDescriptorSetLayout *pSetLayout, VkResult result) {
2484 if (VK_SUCCESS != result) return;
2485 descriptorSetLayoutMap[*pSetLayout] = std::make_shared<cvdescriptorset::DescriptorSetLayout>(pCreateInfo, *pSetLayout);
2486}
2487
2488// For repeatable sorting, not very useful for "memory in range" search
2489struct PushConstantRangeCompare {
2490 bool operator()(const VkPushConstantRange *lhs, const VkPushConstantRange *rhs) const {
2491 if (lhs->offset == rhs->offset) {
2492 if (lhs->size == rhs->size) {
2493 // The comparison is arbitrary, but avoids false aliasing by comparing all fields.
2494 return lhs->stageFlags < rhs->stageFlags;
2495 }
2496 // If the offsets are the same then sorting by the end of range is useful for validation
2497 return lhs->size < rhs->size;
2498 }
2499 return lhs->offset < rhs->offset;
2500 }
2501};
2502
2503static PushConstantRangesDict push_constant_ranges_dict;
2504
2505PushConstantRangesId GetCanonicalId(const VkPipelineLayoutCreateInfo *info) {
2506 if (!info->pPushConstantRanges) {
2507 // Hand back the empty entry (creating as needed)...
2508 return push_constant_ranges_dict.look_up(PushConstantRanges());
2509 }
2510
2511 // Sort the input ranges to ensure equivalent ranges map to the same id
2512 std::set<const VkPushConstantRange *, PushConstantRangeCompare> sorted;
2513 for (uint32_t i = 0; i < info->pushConstantRangeCount; i++) {
2514 sorted.insert(info->pPushConstantRanges + i);
2515 }
2516
Jeremy Hayesf34b9fb2019-12-06 09:37:03 -07002517 PushConstantRanges ranges;
2518 ranges.reserve(sorted.size());
John Zulauf79f06582021-02-27 18:38:39 -07002519 for (const auto *range : sorted) {
locke-lunargd556cc32019-09-17 01:21:23 -06002520 ranges.emplace_back(*range);
2521 }
2522 return push_constant_ranges_dict.look_up(std::move(ranges));
2523}
2524
2525// Dictionary of canoncial form of the pipeline set layout of descriptor set layouts
2526static PipelineLayoutSetLayoutsDict pipeline_layout_set_layouts_dict;
2527
2528// Dictionary of canonical form of the "compatible for set" records
2529static PipelineLayoutCompatDict pipeline_layout_compat_dict;
2530
2531static PipelineLayoutCompatId GetCanonicalId(const uint32_t set_index, const PushConstantRangesId pcr_id,
2532 const PipelineLayoutSetLayoutsId set_layouts_id) {
2533 return pipeline_layout_compat_dict.look_up(PipelineLayoutCompatDef(set_index, pcr_id, set_layouts_id));
2534}
2535
2536void ValidationStateTracker::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
2537 const VkAllocationCallbacks *pAllocator,
2538 VkPipelineLayout *pPipelineLayout, VkResult result) {
2539 if (VK_SUCCESS != result) return;
2540
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002541 auto pipeline_layout_state = std::make_shared<PIPELINE_LAYOUT_STATE>(*pPipelineLayout);
locke-lunargd556cc32019-09-17 01:21:23 -06002542 pipeline_layout_state->set_layouts.resize(pCreateInfo->setLayoutCount);
2543 PipelineLayoutSetLayoutsDef set_layouts(pCreateInfo->setLayoutCount);
2544 for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; ++i) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05002545 pipeline_layout_state->set_layouts[i] = GetDescriptorSetLayoutShared(pCreateInfo->pSetLayouts[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002546 set_layouts[i] = pipeline_layout_state->set_layouts[i]->GetLayoutId();
2547 }
2548
2549 // Get canonical form IDs for the "compatible for set" contents
2550 pipeline_layout_state->push_constant_ranges = GetCanonicalId(pCreateInfo);
2551 auto set_layouts_id = pipeline_layout_set_layouts_dict.look_up(set_layouts);
2552 pipeline_layout_state->compat_for_set.reserve(pCreateInfo->setLayoutCount);
2553
2554 // Create table of "compatible for set N" cannonical forms for trivial accept validation
2555 for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; ++i) {
2556 pipeline_layout_state->compat_for_set.emplace_back(
2557 GetCanonicalId(i, pipeline_layout_state->push_constant_ranges, set_layouts_id));
2558 }
2559 pipelineLayoutMap[*pPipelineLayout] = std::move(pipeline_layout_state);
2560}
2561
2562void ValidationStateTracker::PostCallRecordCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
2563 const VkAllocationCallbacks *pAllocator,
2564 VkDescriptorPool *pDescriptorPool, VkResult result) {
2565 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002566 descriptorPoolMap[*pDescriptorPool] = std::make_shared<DESCRIPTOR_POOL_STATE>(*pDescriptorPool, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002567}
2568
2569void ValidationStateTracker::PostCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2570 VkDescriptorPoolResetFlags flags, VkResult result) {
2571 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002572 DESCRIPTOR_POOL_STATE *pool = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002573 // TODO: validate flags
2574 // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
John Zulauf79f06582021-02-27 18:38:39 -07002575 for (auto *ds : pool->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002576 FreeDescriptorSet(ds);
2577 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002578 pool->sets.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06002579 // Reset available count for each type and available sets for this pool
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002580 for (auto it = pool->availableDescriptorTypeCount.begin(); it != pool->availableDescriptorTypeCount.end(); ++it) {
2581 pool->availableDescriptorTypeCount[it->first] = pool->maxDescriptorTypeCount[it->first];
locke-lunargd556cc32019-09-17 01:21:23 -06002582 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002583 pool->availableSets = pool->maxSets;
locke-lunargd556cc32019-09-17 01:21:23 -06002584}
2585
2586bool ValidationStateTracker::PreCallValidateAllocateDescriptorSets(VkDevice device,
2587 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002588 VkDescriptorSet *pDescriptorSets, void *ads_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002589 // Always update common data
2590 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2591 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2592 UpdateAllocateDescriptorSetsData(pAllocateInfo, ads_state);
2593
2594 return false;
2595}
2596
2597// Allocation state was good and call down chain was made so update state based on allocating descriptor sets
2598void ValidationStateTracker::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
2599 VkDescriptorSet *pDescriptorSets, VkResult result,
2600 void *ads_state_data) {
2601 if (VK_SUCCESS != result) return;
2602 // All the updates are contained in a single cvdescriptorset function
2603 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2604 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2605 PerformAllocateDescriptorSets(pAllocateInfo, pDescriptorSets, ads_state);
2606}
2607
2608void ValidationStateTracker::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count,
2609 const VkDescriptorSet *pDescriptorSets) {
2610 DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(descriptorPool);
2611 // Update available descriptor sets in pool
2612 pool_state->availableSets += count;
2613
2614 // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
2615 for (uint32_t i = 0; i < count; ++i) {
2616 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
2617 auto descriptor_set = setMap[pDescriptorSets[i]].get();
2618 uint32_t type_index = 0, descriptor_count = 0;
2619 for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) {
2620 type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j));
2621 descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j);
2622 pool_state->availableDescriptorTypeCount[type_index] += descriptor_count;
2623 }
2624 FreeDescriptorSet(descriptor_set);
2625 pool_state->sets.erase(descriptor_set);
2626 }
2627 }
2628}
2629
2630void ValidationStateTracker::PreCallRecordUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
2631 const VkWriteDescriptorSet *pDescriptorWrites,
2632 uint32_t descriptorCopyCount,
2633 const VkCopyDescriptorSet *pDescriptorCopies) {
2634 cvdescriptorset::PerformUpdateDescriptorSets(this, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
2635 pDescriptorCopies);
2636}
2637
2638void ValidationStateTracker::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo,
2639 VkCommandBuffer *pCommandBuffer, VkResult result) {
2640 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002641 auto pool = GetCommandPoolShared(pCreateInfo->commandPool);
2642 if (pool) {
locke-lunargd556cc32019-09-17 01:21:23 -06002643 for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) {
2644 // Add command buffer to its commandPool map
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002645 pool->commandBuffers.insert(pCommandBuffer[i]);
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002646 commandBufferMap[pCommandBuffer[i]] = CreateCmdBufferState(pCommandBuffer[i], pCreateInfo, pool);
locke-lunargfc78e932020-11-19 17:06:24 -07002647 }
2648 }
2649}
2650
locke-lunargd556cc32019-09-17 01:21:23 -06002651void ValidationStateTracker::PreCallRecordBeginCommandBuffer(VkCommandBuffer commandBuffer,
2652 const VkCommandBufferBeginInfo *pBeginInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002653 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002654 if (!cb_state) return;
locke-lunargfc78e932020-11-19 17:06:24 -07002655
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002656 cb_state->Begin(pBeginInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002657}
2658
2659void ValidationStateTracker::PostCallRecordEndCommandBuffer(VkCommandBuffer commandBuffer, VkResult result) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002660 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002661 if (!cb_state) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002662
2663 cb_state->End(result);
locke-lunargd556cc32019-09-17 01:21:23 -06002664}
2665
2666void ValidationStateTracker::PostCallRecordResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags,
2667 VkResult result) {
2668 if (VK_SUCCESS == result) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002669 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002670 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002671 }
2672}
2673
2674CBStatusFlags MakeStaticStateMask(VkPipelineDynamicStateCreateInfo const *ds) {
2675 // initially assume everything is static state
2676 CBStatusFlags flags = CBSTATUS_ALL_STATE_SET;
2677
2678 if (ds) {
2679 for (uint32_t i = 0; i < ds->dynamicStateCount; i++) {
locke-lunarg4189aa22020-10-21 00:23:48 -06002680 flags &= ~ConvertToCBStatusFlagBits(ds->pDynamicStates[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002681 }
2682 }
locke-lunargd556cc32019-09-17 01:21:23 -06002683 return flags;
2684}
2685
2686// Validation cache:
2687// CV is the bottommost implementor of this extension. Don't pass calls down.
2688// utility function to set collective state for pipeline
2689void SetPipelineState(PIPELINE_STATE *pPipe) {
2690 // If any attachment used by this pipeline has blendEnable, set top-level blendEnable
2691 if (pPipe->graphicsPipelineCI.pColorBlendState) {
2692 for (size_t i = 0; i < pPipe->attachments.size(); ++i) {
2693 if (VK_TRUE == pPipe->attachments[i].blendEnable) {
2694 if (((pPipe->attachments[i].dstAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2695 (pPipe->attachments[i].dstAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2696 ((pPipe->attachments[i].dstColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2697 (pPipe->attachments[i].dstColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2698 ((pPipe->attachments[i].srcAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2699 (pPipe->attachments[i].srcAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2700 ((pPipe->attachments[i].srcColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2701 (pPipe->attachments[i].srcColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA))) {
2702 pPipe->blendConstantsEnabled = true;
2703 }
2704 }
2705 }
2706 }
sfricke-samsung8f658d42020-05-03 20:12:24 -07002707 // Check if sample location is enabled
2708 if (pPipe->graphicsPipelineCI.pMultisampleState) {
2709 const VkPipelineSampleLocationsStateCreateInfoEXT *sample_location_state =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002710 LvlFindInChain<VkPipelineSampleLocationsStateCreateInfoEXT>(pPipe->graphicsPipelineCI.pMultisampleState->pNext);
sfricke-samsung8f658d42020-05-03 20:12:24 -07002711 if (sample_location_state != nullptr) {
2712 pPipe->sample_location_enabled = sample_location_state->sampleLocationsEnable;
2713 }
2714 }
locke-lunargd556cc32019-09-17 01:21:23 -06002715}
2716
2717void ValidationStateTracker::PreCallRecordCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
2718 VkPipeline pipeline) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002719 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002720 assert(cb_state);
2721
2722 auto pipe_state = GetPipelineState(pipeline);
2723 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002724 bool rasterization_enabled = VK_FALSE == pipe_state->graphicsPipelineCI.ptr()->pRasterizationState->rasterizerDiscardEnable;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002725 const auto* viewport_state = pipe_state->graphicsPipelineCI.ptr()->pViewportState;
2726 const auto* dynamic_state = pipe_state->graphicsPipelineCI.ptr()->pDynamicState;
locke-lunargd556cc32019-09-17 01:21:23 -06002727 cb_state->status &= ~cb_state->static_status;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002728 cb_state->static_status = MakeStaticStateMask(dynamic_state);
locke-lunargd556cc32019-09-17 01:21:23 -06002729 cb_state->status |= cb_state->static_status;
locke-lunarg4189aa22020-10-21 00:23:48 -06002730 cb_state->dynamic_status = CBSTATUS_ALL_STATE_SET & (~cb_state->static_status);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002731
2732 // Used to calculate CMD_BUFFER_STATE::usedViewportScissorCount upon draw command with this graphics pipeline.
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002733 // If rasterization disabled (no viewport/scissors used), or the actual number of viewports/scissors is dynamic (unknown at
2734 // this time), then these are set to 0 to disable this checking.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002735 auto has_dynamic_viewport_count = cb_state->dynamic_status & CBSTATUS_VIEWPORT_WITH_COUNT_SET;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002736 auto has_dynamic_scissor_count = cb_state->dynamic_status & CBSTATUS_SCISSOR_WITH_COUNT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002737 cb_state->pipelineStaticViewportCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002738 has_dynamic_viewport_count || !rasterization_enabled ? 0 : viewport_state->viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002739 cb_state->pipelineStaticScissorCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002740 has_dynamic_scissor_count || !rasterization_enabled ? 0 : viewport_state->scissorCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002741
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002742 // Trash dynamic viewport/scissor state if pipeline defines static state and enabled rasterization.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002743 // akeley98 NOTE: There's a bit of an ambiguity in the spec, whether binding such a pipeline overwrites
2744 // the entire viewport (scissor) array, or only the subsection defined by the viewport (scissor) count.
2745 // I am taking the latter interpretation based on the implementation details of NVIDIA's Vulkan driver.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002746 if (!has_dynamic_viewport_count) {
2747 cb_state->trashedViewportCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002748 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_VIEWPORT_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002749 cb_state->trashedViewportMask |= (uint32_t(1) << viewport_state->viewportCount) - 1u;
2750 // should become = ~uint32_t(0) if the other interpretation is correct.
2751 }
2752 }
2753 if (!has_dynamic_scissor_count) {
2754 cb_state->trashedScissorCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002755 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_SCISSOR_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002756 cb_state->trashedScissorMask |= (uint32_t(1) << viewport_state->scissorCount) - 1u;
2757 // should become = ~uint32_t(0) if the other interpretation is correct.
2758 }
2759 }
locke-lunargd556cc32019-09-17 01:21:23 -06002760 }
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002761 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
2762 cb_state->lastBound[lv_bind_point].pipeline_state = pipe_state;
locke-lunargd556cc32019-09-17 01:21:23 -06002763 SetPipelineState(pipe_state);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002764 if (!disabled[command_buffer_state]) {
2765 cb_state->AddChild(pipe_state);
2766 }
locke-lunargb8be8222020-10-20 00:34:37 -06002767 for (auto &slot : pipe_state->active_slots) {
2768 for (auto &req : slot.second) {
2769 for (auto &sampler : req.second.samplers_used_by_image) {
2770 for (auto &des : sampler) {
2771 des.second = nullptr;
2772 }
2773 }
2774 }
2775 }
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06002776 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
locke-lunargd556cc32019-09-17 01:21:23 -06002777}
2778
2779void ValidationStateTracker::PreCallRecordCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2780 uint32_t viewportCount, const VkViewport *pViewports) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002781 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002782 uint32_t bits = ((1u << viewportCount) - 1u) << firstViewport;
2783 cb_state->viewportMask |= bits;
2784 cb_state->trashedViewportMask &= ~bits;
locke-lunargd556cc32019-09-17 01:21:23 -06002785 cb_state->status |= CBSTATUS_VIEWPORT_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06002786 cb_state->static_status &= ~CBSTATUS_VIEWPORT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002787
2788 cb_state->dynamicViewports.resize(std::max(size_t(firstViewport + viewportCount), cb_state->dynamicViewports.size()));
2789 for (size_t i = 0; i < viewportCount; ++i) {
2790 cb_state->dynamicViewports[firstViewport + i] = pViewports[i];
2791 }
locke-lunargd556cc32019-09-17 01:21:23 -06002792}
2793
2794void ValidationStateTracker::PreCallRecordCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
2795 uint32_t exclusiveScissorCount,
2796 const VkRect2D *pExclusiveScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002797 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002798 // TODO: We don't have VUIDs for validating that all exclusive scissors have been set.
2799 // cb_state->exclusiveScissorMask |= ((1u << exclusiveScissorCount) - 1u) << firstExclusiveScissor;
2800 cb_state->status |= CBSTATUS_EXCLUSIVE_SCISSOR_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06002801 cb_state->static_status &= ~CBSTATUS_EXCLUSIVE_SCISSOR_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06002802}
2803
2804void ValidationStateTracker::PreCallRecordCmdBindShadingRateImageNV(VkCommandBuffer commandBuffer, VkImageView imageView,
2805 VkImageLayout imageLayout) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002806 if (disabled[command_buffer_state]) return;
2807
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002808 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002809
2810 if (imageView != VK_NULL_HANDLE) {
2811 auto view_state = GetImageViewState(imageView);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002812 cb_state->AddChild(view_state);
locke-lunargd556cc32019-09-17 01:21:23 -06002813 }
2814}
2815
2816void ValidationStateTracker::PreCallRecordCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2817 uint32_t viewportCount,
2818 const VkShadingRatePaletteNV *pShadingRatePalettes) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002819 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002820 // TODO: We don't have VUIDs for validating that all shading rate palettes have been set.
2821 // cb_state->shadingRatePaletteMask |= ((1u << viewportCount) - 1u) << firstViewport;
2822 cb_state->status |= CBSTATUS_SHADING_RATE_PALETTE_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06002823 cb_state->static_status &= ~CBSTATUS_SHADING_RATE_PALETTE_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06002824}
2825
2826void ValidationStateTracker::PostCallRecordCreateAccelerationStructureNV(VkDevice device,
2827 const VkAccelerationStructureCreateInfoNV *pCreateInfo,
2828 const VkAllocationCallbacks *pAllocator,
2829 VkAccelerationStructureNV *pAccelerationStructure,
2830 VkResult result) {
2831 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002832 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE>(*pAccelerationStructure, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002833
2834 // Query the requirements in case the application doesn't (to avoid bind/validation time query)
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002835 auto as_memory_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002836 as_memory_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002837 as_memory_requirements_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002838 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &as_memory_requirements_info, &as_state->memory_requirements);
2839
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002840 auto scratch_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002841 scratch_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002842 scratch_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002843 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &scratch_memory_req_info,
2844 &as_state->build_scratch_memory_requirements);
2845
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002846 auto update_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002847 update_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002848 update_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002849 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &update_memory_req_info,
2850 &as_state->update_scratch_memory_requirements);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002851 as_state->allocator = pAllocator;
locke-lunargd556cc32019-09-17 01:21:23 -06002852 accelerationStructureMap[*pAccelerationStructure] = std::move(as_state);
2853}
2854
Jeff Bolz95176d02020-04-01 00:36:16 -05002855void ValidationStateTracker::PostCallRecordCreateAccelerationStructureKHR(VkDevice device,
2856 const VkAccelerationStructureCreateInfoKHR *pCreateInfo,
2857 const VkAllocationCallbacks *pAllocator,
2858 VkAccelerationStructureKHR *pAccelerationStructure,
2859 VkResult result) {
2860 if (VK_SUCCESS != result) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07002861 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE_KHR>(*pAccelerationStructure, pCreateInfo);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002862 as_state->allocator = pAllocator;
sourav parmarcd5fb182020-07-17 12:58:44 -07002863 accelerationStructureMap_khr[*pAccelerationStructure] = std::move(as_state);
Jeff Bolz95176d02020-04-01 00:36:16 -05002864}
2865
sourav parmarcd5fb182020-07-17 12:58:44 -07002866void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresKHR(
2867 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2868 const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002869 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmarcd5fb182020-07-17 12:58:44 -07002870 if (cb_state == nullptr) {
2871 return;
2872 }
2873 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002874 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002875 if (dst_as_state != nullptr) {
2876 dst_as_state->built = true;
2877 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002878 if (!disabled[command_buffer_state]) {
2879 cb_state->AddChild(dst_as_state);
2880 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002881 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002882 if (!disabled[command_buffer_state]) {
2883 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2884 if (src_as_state != nullptr) {
2885 cb_state->AddChild(src_as_state);
2886 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002887 }
2888 }
2889 cb_state->hasBuildAccelerationStructureCmd = true;
2890}
2891
2892void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresIndirectKHR(
2893 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2894 const VkDeviceAddress *pIndirectDeviceAddresses, const uint32_t *pIndirectStrides,
2895 const uint32_t *const *ppMaxPrimitiveCounts) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002896 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmarcd5fb182020-07-17 12:58:44 -07002897 if (cb_state == nullptr) {
2898 return;
2899 }
2900 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002901 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002902 if (dst_as_state != nullptr) {
2903 dst_as_state->built = true;
2904 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002905 if (!disabled[command_buffer_state]) {
2906 cb_state->AddChild(dst_as_state);
2907 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002908 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002909 if (!disabled[command_buffer_state]) {
2910 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2911 if (src_as_state != nullptr) {
2912 cb_state->AddChild(src_as_state);
2913 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002914 }
2915 }
2916 cb_state->hasBuildAccelerationStructureCmd = true;
2917}
locke-lunargd556cc32019-09-17 01:21:23 -06002918void ValidationStateTracker::PostCallRecordGetAccelerationStructureMemoryRequirementsNV(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002919 VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV *pInfo, VkMemoryRequirements2 *pMemoryRequirements) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002920 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(pInfo->accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002921 if (as_state != nullptr) {
2922 if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV) {
2923 as_state->memory_requirements = *pMemoryRequirements;
2924 as_state->memory_requirements_checked = true;
2925 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV) {
2926 as_state->build_scratch_memory_requirements = *pMemoryRequirements;
2927 as_state->build_scratch_memory_requirements_checked = true;
2928 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV) {
2929 as_state->update_scratch_memory_requirements = *pMemoryRequirements;
2930 as_state->update_scratch_memory_requirements_checked = true;
2931 }
2932 }
2933}
2934
sourav parmarcd5fb182020-07-17 12:58:44 -07002935void ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(
2936 VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002937 if (VK_SUCCESS != result) return;
2938 for (uint32_t i = 0; i < bindInfoCount; i++) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002939 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
locke-lunargd556cc32019-09-17 01:21:23 -06002940
sourav parmarcd5fb182020-07-17 12:58:44 -07002941 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(info.accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002942 if (as_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002943 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002944 auto mem_state = GetDevMemShared(info.memory);
2945 if (mem_state) {
2946 as_state->SetMemBinding(mem_state, info.memoryOffset);
2947 }
locke-lunargd556cc32019-09-17 01:21:23 -06002948
2949 // GPU validation of top level acceleration structure building needs acceleration structure handles.
Jeff Bolz95176d02020-04-01 00:36:16 -05002950 // XXX TODO: Query device address for KHR extension
sourav parmarcd5fb182020-07-17 12:58:44 -07002951 if (enabled[gpu_validation]) {
locke-lunargd556cc32019-09-17 01:21:23 -06002952 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
2953 }
2954 }
2955 }
2956}
2957
2958void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructureNV(
2959 VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset,
2960 VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002961 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002962 if (cb_state == nullptr) {
2963 return;
2964 }
2965
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002966 auto *dst_as_state = GetAccelerationStructureStateNV(dst);
locke-lunargd556cc32019-09-17 01:21:23 -06002967 if (dst_as_state != nullptr) {
2968 dst_as_state->built = true;
2969 dst_as_state->build_info.initialize(pInfo);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002970 if (!disabled[command_buffer_state]) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002971 cb_state->AddChild(dst_as_state);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002972 }
locke-lunargd556cc32019-09-17 01:21:23 -06002973 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002974 if (!disabled[command_buffer_state]) {
2975 auto *src_as_state = GetAccelerationStructureStateNV(src);
2976 if (src_as_state != nullptr) {
2977 cb_state->AddChild(src_as_state);
2978 }
locke-lunargd556cc32019-09-17 01:21:23 -06002979 }
2980 cb_state->hasBuildAccelerationStructureCmd = true;
2981}
2982
2983void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureNV(VkCommandBuffer commandBuffer,
2984 VkAccelerationStructureNV dst,
2985 VkAccelerationStructureNV src,
2986 VkCopyAccelerationStructureModeNV mode) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002987 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002988 if (cb_state) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002989 ACCELERATION_STRUCTURE_STATE *src_as_state = GetAccelerationStructureStateNV(src);
2990 ACCELERATION_STRUCTURE_STATE *dst_as_state = GetAccelerationStructureStateNV(dst);
locke-lunargd556cc32019-09-17 01:21:23 -06002991 if (dst_as_state != nullptr && src_as_state != nullptr) {
2992 dst_as_state->built = true;
2993 dst_as_state->build_info = src_as_state->build_info;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002994 if (!disabled[command_buffer_state]) {
2995 cb_state->AddChild(dst_as_state);
2996 cb_state->AddChild(src_as_state);
2997 }
locke-lunargd556cc32019-09-17 01:21:23 -06002998 }
2999 }
3000}
3001
Jeff Bolz95176d02020-04-01 00:36:16 -05003002void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureKHR(VkDevice device,
3003 VkAccelerationStructureKHR accelerationStructure,
3004 const VkAllocationCallbacks *pAllocator) {
locke-lunargd556cc32019-09-17 01:21:23 -06003005 if (!accelerationStructure) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07003006 auto *as_state = GetAccelerationStructureStateKHR(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06003007 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003008 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07003009 accelerationStructureMap_khr.erase(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06003010 }
3011}
3012
Jeff Bolz95176d02020-04-01 00:36:16 -05003013void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureNV(VkDevice device,
3014 VkAccelerationStructureNV accelerationStructure,
3015 const VkAllocationCallbacks *pAllocator) {
sourav parmarcd5fb182020-07-17 12:58:44 -07003016 if (!accelerationStructure) return;
3017 auto *as_state = GetAccelerationStructureStateNV(accelerationStructure);
3018 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003019 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07003020 accelerationStructureMap.erase(accelerationStructure);
3021 }
Jeff Bolz95176d02020-04-01 00:36:16 -05003022}
3023
Chris Mayer9ded5eb2019-09-19 16:33:26 +02003024void ValidationStateTracker::PreCallRecordCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
3025 uint32_t viewportCount,
3026 const VkViewportWScalingNV *pViewportWScalings) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003027 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Chris Mayer9ded5eb2019-09-19 16:33:26 +02003028 cb_state->status |= CBSTATUS_VIEWPORT_W_SCALING_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003029 cb_state->static_status &= ~CBSTATUS_VIEWPORT_W_SCALING_SET;
Chris Mayer9ded5eb2019-09-19 16:33:26 +02003030}
3031
locke-lunargd556cc32019-09-17 01:21:23 -06003032void ValidationStateTracker::PreCallRecordCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003033 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003034 cb_state->status |= CBSTATUS_LINE_WIDTH_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003035 cb_state->static_status &= ~CBSTATUS_LINE_WIDTH_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003036}
3037
3038void ValidationStateTracker::PreCallRecordCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
3039 uint16_t lineStipplePattern) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003040 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003041 cb_state->status |= CBSTATUS_LINE_STIPPLE_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003042 cb_state->static_status &= ~CBSTATUS_LINE_STIPPLE_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003043}
3044
3045void ValidationStateTracker::PreCallRecordCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
3046 float depthBiasClamp, float depthBiasSlopeFactor) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003047 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003048 cb_state->status |= CBSTATUS_DEPTH_BIAS_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003049 cb_state->static_status &= ~CBSTATUS_DEPTH_BIAS_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003050}
3051
Lionel Landwerlinc7420912019-05-23 00:33:42 +01003052void ValidationStateTracker::PreCallRecordCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
3053 const VkRect2D *pScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003054 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07003055 uint32_t bits = ((1u << scissorCount) - 1u) << firstScissor;
3056 cb_state->scissorMask |= bits;
3057 cb_state->trashedScissorMask &= ~bits;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01003058 cb_state->status |= CBSTATUS_SCISSOR_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003059 cb_state->static_status &= ~CBSTATUS_SCISSOR_SET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01003060}
3061
locke-lunargd556cc32019-09-17 01:21:23 -06003062void ValidationStateTracker::PreCallRecordCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003063 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003064 cb_state->status |= CBSTATUS_BLEND_CONSTANTS_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003065 cb_state->static_status &= ~CBSTATUS_BLEND_CONSTANTS_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003066}
3067
3068void ValidationStateTracker::PreCallRecordCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
3069 float maxDepthBounds) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003070 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003071 cb_state->status |= CBSTATUS_DEPTH_BOUNDS_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003072 cb_state->static_status &= ~CBSTATUS_DEPTH_BOUNDS_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003073}
3074
3075void ValidationStateTracker::PreCallRecordCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3076 uint32_t compareMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003077 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003078 cb_state->status |= CBSTATUS_STENCIL_READ_MASK_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003079 cb_state->static_status &= ~CBSTATUS_STENCIL_READ_MASK_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003080}
3081
3082void ValidationStateTracker::PreCallRecordCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3083 uint32_t writeMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003084 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003085 cb_state->status |= CBSTATUS_STENCIL_WRITE_MASK_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003086 cb_state->static_status &= ~CBSTATUS_STENCIL_WRITE_MASK_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003087}
3088
3089void ValidationStateTracker::PreCallRecordCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3090 uint32_t reference) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003091 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003092 cb_state->status |= CBSTATUS_STENCIL_REFERENCE_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003093 cb_state->static_status &= ~CBSTATUS_STENCIL_REFERENCE_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003094}
3095
locke-lunargd556cc32019-09-17 01:21:23 -06003096
3097// Update the bound state for the bind point, including the effects of incompatible pipeline layouts
3098void ValidationStateTracker::PreCallRecordCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
3099 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3100 uint32_t firstSet, uint32_t setCount,
3101 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
3102 const uint32_t *pDynamicOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003103 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003104 auto pipeline_layout = GetPipelineLayout(layout);
3105
3106 // Resize binding arrays
3107 uint32_t last_set_index = firstSet + setCount - 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003108 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
3109 if (last_set_index >= cb_state->lastBound[lv_bind_point].per_set.size()) {
3110 cb_state->lastBound[lv_bind_point].per_set.resize(last_set_index + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06003111 }
3112
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003113 cb_state->UpdateLastBoundDescriptorSets(pipelineBindPoint, pipeline_layout, firstSet, setCount, pDescriptorSets, nullptr,
3114 dynamicOffsetCount, pDynamicOffsets);
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003115 cb_state->lastBound[lv_bind_point].pipeline_layout = layout;
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06003116 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06003117}
3118
locke-lunargd556cc32019-09-17 01:21:23 -06003119void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
3120 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3121 uint32_t set, uint32_t descriptorWriteCount,
3122 const VkWriteDescriptorSet *pDescriptorWrites) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003123 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003124 auto pipeline_layout = GetPipelineLayout(layout);
3125 cb_state->PushDescriptorSetState(pipelineBindPoint, pipeline_layout, set, descriptorWriteCount, pDescriptorWrites);
locke-lunargd556cc32019-09-17 01:21:23 -06003126}
3127
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003128void ValidationStateTracker::PostCallRecordCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
3129 VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
3130 const void *pValues) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003131 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003132 if (cb_state != nullptr) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003133 cb_state->ResetPushConstantDataIfIncompatible(GetPipelineLayout(layout));
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003134
3135 auto &push_constant_data = cb_state->push_constant_data;
3136 assert((offset + size) <= static_cast<uint32_t>(push_constant_data.size()));
3137 std::memcpy(push_constant_data.data() + offset, pValues, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003138 cb_state->push_constant_pipeline_layout_set = layout;
3139
3140 auto flags = stageFlags;
3141 uint32_t bit_shift = 0;
3142 while (flags) {
3143 if (flags & 1) {
3144 VkShaderStageFlagBits flag = static_cast<VkShaderStageFlagBits>(1 << bit_shift);
3145 const auto it = cb_state->push_constant_data_update.find(flag);
3146
3147 if (it != cb_state->push_constant_data_update.end()) {
locke-lunarg3d8b8f32020-10-26 17:04:16 -06003148 std::memset(it->second.data() + offset, PC_Byte_Updated, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003149 }
3150 }
3151 flags = flags >> 1;
3152 ++bit_shift;
3153 }
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003154 }
3155}
3156
locke-lunargd556cc32019-09-17 01:21:23 -06003157void ValidationStateTracker::PreCallRecordCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
3158 VkIndexType indexType) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003159 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003160
3161 cb_state->status |= CBSTATUS_INDEX_BUFFER_BOUND;
Piers Daniell39842ee2020-07-10 16:42:33 -06003162 cb_state->static_status &= ~CBSTATUS_INDEX_BUFFER_BOUND;
locke-lunarg1ae57d62020-11-18 10:49:19 -07003163 cb_state->index_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(buffer);
3164 cb_state->index_buffer_binding.size = cb_state->index_buffer_binding.buffer_state->createInfo.size;
locke-lunargd556cc32019-09-17 01:21:23 -06003165 cb_state->index_buffer_binding.offset = offset;
3166 cb_state->index_buffer_binding.index_type = indexType;
3167 // Add binding for this index buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003168 if (!disabled[command_buffer_state]) {
3169 cb_state->AddChild(cb_state->index_buffer_binding.buffer_state.get());
3170 }
locke-lunargd556cc32019-09-17 01:21:23 -06003171}
3172
3173void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
3174 uint32_t bindingCount, const VkBuffer *pBuffers,
3175 const VkDeviceSize *pOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003176 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003177
3178 uint32_t end = firstBinding + bindingCount;
3179 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
3180 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
3181 }
3182
3183 for (uint32_t i = 0; i < bindingCount; ++i) {
3184 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07003185 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003186 vertex_buffer_binding.offset = pOffsets[i];
Piers Daniell39842ee2020-07-10 16:42:33 -06003187 vertex_buffer_binding.size = VK_WHOLE_SIZE;
3188 vertex_buffer_binding.stride = 0;
locke-lunargd556cc32019-09-17 01:21:23 -06003189 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003190 if (pBuffers[i] && !disabled[command_buffer_state]) {
3191 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Jeff Bolz165818a2020-05-08 11:19:03 -05003192 }
locke-lunargd556cc32019-09-17 01:21:23 -06003193 }
3194}
3195
3196void ValidationStateTracker::PostCallRecordCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
3197 VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003198 if (disabled[command_buffer_state]) return;
3199
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003200 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003201 auto dst_buffer_state = GetBufferState(dstBuffer);
3202
3203 // Update bindings between buffer and cmd buffer
Jeremy Gebben5570abe2021-05-16 18:35:13 -06003204 if (cb_state && dst_buffer_state) {
3205 cb_state->AddChild(dst_buffer_state);
3206 }
locke-lunargd556cc32019-09-17 01:21:23 -06003207}
3208
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06003209static bool SetEventStageMask(VkEvent event, VkPipelineStageFlags2KHR stageMask,
Jeff Bolz310775c2019-10-09 00:46:33 -05003210 EventToStageMap *localEventToStageMap) {
3211 (*localEventToStageMap)[event] = stageMask;
locke-lunargd556cc32019-09-17 01:21:23 -06003212 return false;
3213}
3214
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003215void ValidationStateTracker::RecordCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR stageMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003216 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003217 if (!disabled[command_buffer_state]) {
3218 auto event_state = GetEventState(event);
3219 if (event_state) {
3220 cb_state->AddChild(event_state);
3221 }
locke-lunargd556cc32019-09-17 01:21:23 -06003222 }
3223 cb_state->events.push_back(event);
3224 if (!cb_state->waitedEvents.count(event)) {
3225 cb_state->writeEventsBeforeWait.push_back(event);
3226 }
Jeff Bolz310775c2019-10-09 00:46:33 -05003227 cb_state->eventUpdates.emplace_back(
3228 [event, stageMask](const ValidationStateTracker *device_data, bool do_validate, EventToStageMap *localEventToStageMap) {
3229 return SetEventStageMask(event, stageMask, localEventToStageMap);
3230 });
locke-lunargd556cc32019-09-17 01:21:23 -06003231}
3232
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003233void ValidationStateTracker::PreCallRecordCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3234 VkPipelineStageFlags stageMask) {
3235 RecordCmdSetEvent(commandBuffer, event, stageMask);
3236}
3237
3238void ValidationStateTracker::PreCallRecordCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3239 const VkDependencyInfoKHR *pDependencyInfo) {
3240 auto stage_masks = sync_utils::GetGlobalStageMasks(*pDependencyInfo);
3241
3242 RecordCmdSetEvent(commandBuffer, event, stage_masks.src);
Jeremy Gebben79649152021-06-22 14:46:24 -06003243
3244 RecordBarriers(commandBuffer, pDependencyInfo);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003245}
3246
3247void ValidationStateTracker::RecordCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3248 VkPipelineStageFlags2KHR stageMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003249 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003250 if (!disabled[command_buffer_state]) {
3251 auto event_state = GetEventState(event);
3252 if (event_state) {
3253 cb_state->AddChild(event_state);
3254 }
locke-lunargd556cc32019-09-17 01:21:23 -06003255 }
3256 cb_state->events.push_back(event);
3257 if (!cb_state->waitedEvents.count(event)) {
3258 cb_state->writeEventsBeforeWait.push_back(event);
3259 }
3260
3261 cb_state->eventUpdates.emplace_back(
Jeff Bolz310775c2019-10-09 00:46:33 -05003262 [event](const ValidationStateTracker *, bool do_validate, EventToStageMap *localEventToStageMap) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003263 return SetEventStageMask(event, VkPipelineStageFlags2KHR(0), localEventToStageMap);
Jeff Bolz310775c2019-10-09 00:46:33 -05003264 });
locke-lunargd556cc32019-09-17 01:21:23 -06003265}
3266
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003267void ValidationStateTracker::PreCallRecordCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3268 VkPipelineStageFlags stageMask) {
3269 RecordCmdResetEvent(commandBuffer, event, stageMask);
3270}
3271
3272void ValidationStateTracker::PreCallRecordCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3273 VkPipelineStageFlags2KHR stageMask) {
3274 RecordCmdResetEvent(commandBuffer, event, stageMask);
3275}
3276
3277void ValidationStateTracker::RecordCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003278 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003279 for (uint32_t i = 0; i < eventCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003280 if (!disabled[command_buffer_state]) {
3281 auto event_state = GetEventState(pEvents[i]);
3282 if (event_state) {
3283 cb_state->AddChild(event_state);
3284 }
locke-lunargd556cc32019-09-17 01:21:23 -06003285 }
3286 cb_state->waitedEvents.insert(pEvents[i]);
3287 cb_state->events.push_back(pEvents[i]);
3288 }
3289}
3290
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003291void ValidationStateTracker::PreCallRecordCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
3292 VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
3293 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3294 uint32_t bufferMemoryBarrierCount,
3295 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3296 uint32_t imageMemoryBarrierCount,
3297 const VkImageMemoryBarrier *pImageMemoryBarriers) {
3298 RecordCmdWaitEvents(commandBuffer, eventCount, pEvents);
Jeremy Gebben79649152021-06-22 14:46:24 -06003299 RecordBarriers(commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3300 imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003301}
3302
3303void ValidationStateTracker::PreCallRecordCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount,
3304 const VkEvent *pEvents, const VkDependencyInfoKHR *pDependencyInfos) {
3305 RecordCmdWaitEvents(commandBuffer, eventCount, pEvents);
Jeremy Gebben79649152021-06-22 14:46:24 -06003306 for (uint32_t i = 0; i < eventCount; i++) {
3307 RecordBarriers(commandBuffer, &pDependencyInfos[i]);
3308 }
3309}
3310
3311void ValidationStateTracker::PostCallRecordCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
3312 VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
3313 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3314 uint32_t bufferMemoryBarrierCount,
3315 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3316 uint32_t imageMemoryBarrierCount,
3317 const VkImageMemoryBarrier *pImageMemoryBarriers) {
3318 RecordBarriers(commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3319 imageMemoryBarrierCount, pImageMemoryBarriers);
3320}
3321
3322void ValidationStateTracker::PreCallRecordCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
3323 const VkDependencyInfoKHR *pDependencyInfo) {
3324 RecordBarriers(commandBuffer, pDependencyInfo);
3325}
3326
3327void ValidationStateTracker::RecordBarriers(VkCommandBuffer commandBuffer, uint32_t memoryBarrierCount,
3328 const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
3329 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
3330 const VkImageMemoryBarrier *pImageMemoryBarriers) {
3331 if (disabled[command_buffer_state]) return;
3332
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003333 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben79649152021-06-22 14:46:24 -06003334 for (uint32_t i = 0; i < bufferMemoryBarrierCount; i++) {
3335 auto buffer_state = GetBufferState(pBufferMemoryBarriers[i].buffer);
3336 if (buffer_state) {
3337 cb_state->AddChild(buffer_state);
3338 }
3339 }
3340 for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
3341 auto image_state = GetImageState(pImageMemoryBarriers[i].image);
3342 if (image_state) {
3343 cb_state->AddChild(image_state);
3344 }
3345 }
3346}
3347
3348void ValidationStateTracker::RecordBarriers(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR *pDependencyInfo) {
3349 if (disabled[command_buffer_state]) return;
3350
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003351 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben79649152021-06-22 14:46:24 -06003352 for (uint32_t i = 0; i < pDependencyInfo->bufferMemoryBarrierCount; i++) {
3353 auto buffer_state = GetBufferState(pDependencyInfo->pBufferMemoryBarriers[i].buffer);
3354 if (buffer_state) {
3355 cb_state->AddChild(buffer_state);
3356 }
3357 }
3358 for (uint32_t i = 0; i < pDependencyInfo->imageMemoryBarrierCount; i++) {
3359 auto image_state = GetImageState(pDependencyInfo->pImageMemoryBarriers[i].image);
3360 if (image_state) {
3361 cb_state->AddChild(image_state);
3362 }
3363 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003364}
3365
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003366QueryState ValidationStateTracker::GetQueryState(const QueryMap *localQueryToStateMap, VkQueryPool queryPool, uint32_t queryIndex,
3367 uint32_t perfPass) const {
3368 QueryObject query = QueryObject(QueryObject(queryPool, queryIndex), perfPass);
locke-lunargd556cc32019-09-17 01:21:23 -06003369
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003370 auto iter = localQueryToStateMap->find(query);
3371 if (iter != localQueryToStateMap->end()) return iter->second;
Jeff Bolz310775c2019-10-09 00:46:33 -05003372
Jeff Bolz310775c2019-10-09 00:46:33 -05003373 return QUERYSTATE_UNKNOWN;
locke-lunargd556cc32019-09-17 01:21:23 -06003374}
3375
locke-lunargd556cc32019-09-17 01:21:23 -06003376void ValidationStateTracker::PostCallRecordCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot,
3377 VkFlags flags) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003378 if (disabled[query_validation]) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003379
locke-lunargd556cc32019-09-17 01:21:23 -06003380 QueryObject query = {queryPool, slot};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003381 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003382 if (!disabled[query_validation]) {
3383 cb_state->BeginQuery(query);
3384 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003385 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003386 auto pool_state = GetQueryPoolState(query.pool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003387 cb_state->AddChild(pool_state);
3388 }
locke-lunargd556cc32019-09-17 01:21:23 -06003389}
3390
3391void ValidationStateTracker::PostCallRecordCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003392 if (disabled[query_validation]) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003393 QueryObject query_obj = {queryPool, slot};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003394 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003395 if (!disabled[query_validation]) {
3396 cb_state->EndQuery(query_obj);
3397 }
3398 if (!disabled[command_buffer_state]) {
3399 auto pool_state = GetQueryPoolState(query_obj.pool);
3400 cb_state->AddChild(pool_state);
3401 }
locke-lunargd556cc32019-09-17 01:21:23 -06003402}
3403
3404void ValidationStateTracker::PostCallRecordCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3405 uint32_t firstQuery, uint32_t queryCount) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003406 if (disabled[query_validation]) return;
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003407 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003408
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003409 cb_state->ResetQueryPool(queryPool, firstQuery, queryCount);
Lionel Landwerlinb1e5a422020-02-18 16:49:09 +02003410
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003411 if (!disabled[command_buffer_state]) {
3412 auto pool_state = GetQueryPoolState(queryPool);
3413 cb_state->AddChild(pool_state);
3414 }
locke-lunargd556cc32019-09-17 01:21:23 -06003415}
3416
3417void ValidationStateTracker::PostCallRecordCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3418 uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer,
3419 VkDeviceSize dstOffset, VkDeviceSize stride,
3420 VkQueryResultFlags flags) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003421 if (disabled[query_validation] || disabled[command_buffer_state]) return;
3422
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003423 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003424 auto dst_buff_state = GetBufferState(dstBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003425 cb_state->AddChild(dst_buff_state);
Jeff Bolzadbfa852019-10-04 13:53:30 -05003426 auto pool_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003427 cb_state->AddChild(pool_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003428}
3429
3430void ValidationStateTracker::PostCallRecordCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
3431 VkQueryPool queryPool, uint32_t slot) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003432 PostCallRecordCmdWriteTimestamp2KHR(commandBuffer, pipelineStage, queryPool, slot);
3433}
3434
3435void ValidationStateTracker::PostCallRecordCmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer,
3436 VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool,
3437 uint32_t slot) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003438 if (disabled[query_validation]) return;
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003439 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003440 if (!disabled[command_buffer_state]) {
3441 auto pool_state = GetQueryPoolState(queryPool);
3442 cb_state->AddChild(pool_state);
3443 }
locke-lunargd556cc32019-09-17 01:21:23 -06003444 QueryObject query = {queryPool, slot};
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003445 cb_state->EndQuery(query);
locke-lunargd556cc32019-09-17 01:21:23 -06003446}
3447
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003448void ValidationStateTracker::PostCallRecordCmdWriteAccelerationStructuresPropertiesKHR(
3449 VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR *pAccelerationStructures,
3450 VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery) {
3451 if (disabled[query_validation]) return;
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003452 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003453 if (!disabled[command_buffer_state]) {
3454 auto pool_state = GetQueryPoolState(queryPool);
3455 cb_state->AddChild(pool_state);
3456 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003457 cb_state->EndQueries(queryPool, firstQuery, accelerationStructureCount);
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003458}
3459
locke-lunargd556cc32019-09-17 01:21:23 -06003460void ValidationStateTracker::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
3461 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
3462 VkResult result) {
3463 if (VK_SUCCESS != result) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003464
Jeremy Gebben88f58142021-06-01 10:07:52 -06003465 std::vector<std::shared_ptr<IMAGE_VIEW_STATE>> views;
Mike Schuchardt2df08912020-12-15 16:28:09 -08003466 if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) == 0) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003467 views.resize(pCreateInfo->attachmentCount);
locke-lunarg1ae57d62020-11-18 10:49:19 -07003468
locke-lunargd556cc32019-09-17 01:21:23 -06003469 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003470 views[i] = GetShared<IMAGE_VIEW_STATE>(pCreateInfo->pAttachments[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003471 }
3472 }
Jeremy Gebben88f58142021-06-01 10:07:52 -06003473
3474 frameBufferMap[*pFramebuffer] = std::make_shared<FRAMEBUFFER_STATE>(
3475 *pFramebuffer, pCreateInfo, GetRenderPassShared(pCreateInfo->renderPass), std::move(views));
locke-lunargd556cc32019-09-17 01:21:23 -06003476}
3477
locke-lunargd556cc32019-09-17 01:21:23 -06003478void ValidationStateTracker::PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
3479 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3480 VkResult result) {
3481 if (VK_SUCCESS != result) return;
Jeremy Gebben88f58142021-06-01 10:07:52 -06003482 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06003483}
3484
Mike Schuchardt2df08912020-12-15 16:28:09 -08003485void ValidationStateTracker::PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003486 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3487 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003488 if (VK_SUCCESS != result) return;
3489
3490 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003491}
3492
Mike Schuchardt2df08912020-12-15 16:28:09 -08003493void ValidationStateTracker::PostCallRecordCreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003494 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3495 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003496 if (VK_SUCCESS != result) return;
3497
3498 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003499}
3500
locke-lunargd556cc32019-09-17 01:21:23 -06003501void ValidationStateTracker::RecordCmdBeginRenderPassState(VkCommandBuffer commandBuffer,
3502 const VkRenderPassBeginInfo *pRenderPassBegin,
3503 const VkSubpassContents contents) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003504 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003505 cb_state->BeginRenderPass(pRenderPassBegin, contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003506}
3507
3508void ValidationStateTracker::PreCallRecordCmdBeginRenderPass(VkCommandBuffer commandBuffer,
3509 const VkRenderPassBeginInfo *pRenderPassBegin,
3510 VkSubpassContents contents) {
3511 RecordCmdBeginRenderPassState(commandBuffer, pRenderPassBegin, contents);
3512}
3513
3514void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
3515 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003516 const VkSubpassBeginInfo *pSubpassBeginInfo) {
locke-lunargd556cc32019-09-17 01:21:23 -06003517 RecordCmdBeginRenderPassState(commandBuffer, pRenderPassBegin, pSubpassBeginInfo->contents);
3518}
3519
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003520void ValidationStateTracker::PostCallRecordCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3521 uint32_t counterBufferCount,
3522 const VkBuffer *pCounterBuffers,
3523 const VkDeviceSize *pCounterBufferOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003524 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003525
3526 cb_state->transform_feedback_active = true;
3527}
3528
3529void ValidationStateTracker::PostCallRecordCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3530 uint32_t counterBufferCount, const VkBuffer *pCounterBuffers,
3531 const VkDeviceSize *pCounterBufferOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003532 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003533
3534 cb_state->transform_feedback_active = false;
3535}
3536
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003537void ValidationStateTracker::PostCallRecordCmdBeginConditionalRenderingEXT(
3538 VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin) {
Jeremy Gebbenc8b51a92021-08-16 15:19:00 -06003539 auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003540
3541 cb_state->conditional_rendering_active = true;
3542}
3543
3544void ValidationStateTracker::PostCallRecordCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer) {
Jeremy Gebbenc8b51a92021-08-16 15:19:00 -06003545 auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003546
3547 cb_state->conditional_rendering_active = false;
3548
3549}
3550
Tony-LunarG977448c2019-12-02 14:52:02 -07003551void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
3552 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003553 const VkSubpassBeginInfo *pSubpassBeginInfo) {
Tony-LunarG977448c2019-12-02 14:52:02 -07003554 RecordCmdBeginRenderPassState(commandBuffer, pRenderPassBegin, pSubpassBeginInfo->contents);
3555}
3556
locke-lunargd556cc32019-09-17 01:21:23 -06003557void ValidationStateTracker::RecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003558 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003559 cb_state->NextSubpass(contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003560}
3561
3562void ValidationStateTracker::PostCallRecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
3563 RecordCmdNextSubpass(commandBuffer, contents);
3564}
3565
3566void ValidationStateTracker::PostCallRecordCmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003567 const VkSubpassBeginInfo *pSubpassBeginInfo,
3568 const VkSubpassEndInfo *pSubpassEndInfo) {
locke-lunargd556cc32019-09-17 01:21:23 -06003569 RecordCmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
3570}
3571
Tony-LunarG977448c2019-12-02 14:52:02 -07003572void ValidationStateTracker::PostCallRecordCmdNextSubpass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003573 const VkSubpassBeginInfo *pSubpassBeginInfo,
3574 const VkSubpassEndInfo *pSubpassEndInfo) {
Tony-LunarG977448c2019-12-02 14:52:02 -07003575 RecordCmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
3576}
3577
locke-lunargd556cc32019-09-17 01:21:23 -06003578void ValidationStateTracker::RecordCmdEndRenderPassState(VkCommandBuffer commandBuffer) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003579 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003580 cb_state->EndRenderPass();
locke-lunargd556cc32019-09-17 01:21:23 -06003581}
3582
3583void ValidationStateTracker::PostCallRecordCmdEndRenderPass(VkCommandBuffer commandBuffer) {
3584 RecordCmdEndRenderPassState(commandBuffer);
3585}
3586
3587void ValidationStateTracker::PostCallRecordCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003588 const VkSubpassEndInfo *pSubpassEndInfo) {
locke-lunargd556cc32019-09-17 01:21:23 -06003589 RecordCmdEndRenderPassState(commandBuffer);
3590}
3591
Tony-LunarG977448c2019-12-02 14:52:02 -07003592void ValidationStateTracker::PostCallRecordCmdEndRenderPass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003593 const VkSubpassEndInfo *pSubpassEndInfo) {
Tony-LunarG977448c2019-12-02 14:52:02 -07003594 RecordCmdEndRenderPassState(commandBuffer);
3595}
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003596
locke-lunargd556cc32019-09-17 01:21:23 -06003597void ValidationStateTracker::PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
3598 const VkCommandBuffer *pCommandBuffers) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003599 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003600
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003601 cb_state->ExecuteCommands(commandBuffersCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06003602}
3603
3604void ValidationStateTracker::PostCallRecordMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size,
3605 VkFlags flags, void **ppData, VkResult result) {
3606 if (VK_SUCCESS != result) return;
3607 RecordMappedMemory(mem, offset, size, ppData);
3608}
3609
3610void ValidationStateTracker::PreCallRecordUnmapMemory(VkDevice device, VkDeviceMemory mem) {
3611 auto mem_info = GetDevMemState(mem);
3612 if (mem_info) {
3613 mem_info->mapped_range = MemRange();
3614 mem_info->p_driver_data = nullptr;
3615 }
3616}
3617
3618void ValidationStateTracker::UpdateBindImageMemoryState(const VkBindImageMemoryInfo &bindInfo) {
Jeremy Gebben8ee02af2021-07-16 10:15:55 -06003619 auto image_state = GetShared<IMAGE_STATE>(bindInfo.image);
locke-lunargd556cc32019-09-17 01:21:23 -06003620 if (image_state) {
locke-lunargae26eac2020-04-16 15:29:05 -06003621 // An Android sepcial image cannot get VkSubresourceLayout until the image binds a memory.
3622 // See: VUID-vkGetImageSubresourceLayout-image-01895
3623 image_state->fragment_encoder =
3624 std::unique_ptr<const subresource_adapter::ImageRangeEncoder>(new subresource_adapter::ImageRangeEncoder(*image_state));
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003625 const auto swapchain_info = LvlFindInChain<VkBindImageMemorySwapchainInfoKHR>(bindInfo.pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003626 if (swapchain_info) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003627 auto swapchain = GetShared<SWAPCHAIN_NODE>(swapchain_info->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003628 if (swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003629 SWAPCHAIN_IMAGE &swapchain_image = swapchain->images[swapchain_info->imageIndex];
John Zulaufd13b38e2021-03-05 08:17:38 -07003630
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003631 if (!swapchain_image.fake_base_address) {
3632 auto size = image_state->fragment_encoder->TotalSize();
3633 swapchain_image.fake_base_address = fake_memory.Alloc(size);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06003634 }
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003635 // All images bound to this swapchain and index are aliases
3636 image_state->SetSwapchain(swapchain, swapchain_info->imageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003637 }
3638 } else {
3639 // Track bound memory range information
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003640 auto mem_info = GetDevMemShared(bindInfo.memory);
locke-lunargd556cc32019-09-17 01:21:23 -06003641 if (mem_info) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003642 image_state->SetMemBinding(mem_info, bindInfo.memoryOffset);
locke-lunargd556cc32019-09-17 01:21:23 -06003643 }
locke-lunargd556cc32019-09-17 01:21:23 -06003644 }
locke-lunargd556cc32019-09-17 01:21:23 -06003645 }
3646}
3647
3648void ValidationStateTracker::PostCallRecordBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
3649 VkDeviceSize memoryOffset, VkResult result) {
3650 if (VK_SUCCESS != result) return;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003651 auto bind_info = LvlInitStruct<VkBindImageMemoryInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003652 bind_info.image = image;
3653 bind_info.memory = mem;
3654 bind_info.memoryOffset = memoryOffset;
3655 UpdateBindImageMemoryState(bind_info);
locke-lunargd556cc32019-09-17 01:21:23 -06003656}
3657
3658void ValidationStateTracker::PostCallRecordBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003659 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003660 if (VK_SUCCESS != result) return;
3661 for (uint32_t i = 0; i < bindInfoCount; i++) {
3662 UpdateBindImageMemoryState(pBindInfos[i]);
3663 }
3664}
3665
3666void ValidationStateTracker::PostCallRecordBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003667 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003668 if (VK_SUCCESS != result) return;
3669 for (uint32_t i = 0; i < bindInfoCount; i++) {
3670 UpdateBindImageMemoryState(pBindInfos[i]);
3671 }
3672}
3673
3674void ValidationStateTracker::PreCallRecordSetEvent(VkDevice device, VkEvent event) {
3675 auto event_state = GetEventState(event);
3676 if (event_state) {
3677 event_state->stageMask = VK_PIPELINE_STAGE_HOST_BIT;
3678 }
locke-lunargd556cc32019-09-17 01:21:23 -06003679}
3680
3681void ValidationStateTracker::PostCallRecordImportSemaphoreFdKHR(VkDevice device,
3682 const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo,
3683 VkResult result) {
3684 if (VK_SUCCESS != result) return;
3685 RecordImportSemaphoreState(pImportSemaphoreFdInfo->semaphore, pImportSemaphoreFdInfo->handleType,
3686 pImportSemaphoreFdInfo->flags);
3687}
3688
3689void ValidationStateTracker::RecordGetExternalSemaphoreState(VkSemaphore semaphore,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003690 VkExternalSemaphoreHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003691 SEMAPHORE_STATE *semaphore_state = GetSemaphoreState(semaphore);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003692 if (semaphore_state && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003693 // Cannot track semaphore state once it is exported, except for Sync FD handle types which have copy transference
3694 semaphore_state->scope = kSyncScopeExternalPermanent;
3695 }
3696}
3697
3698#ifdef VK_USE_PLATFORM_WIN32_KHR
3699void ValidationStateTracker::PostCallRecordImportSemaphoreWin32HandleKHR(
3700 VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR *pImportSemaphoreWin32HandleInfo, VkResult result) {
3701 if (VK_SUCCESS != result) return;
3702 RecordImportSemaphoreState(pImportSemaphoreWin32HandleInfo->semaphore, pImportSemaphoreWin32HandleInfo->handleType,
3703 pImportSemaphoreWin32HandleInfo->flags);
3704}
3705
3706void ValidationStateTracker::PostCallRecordGetSemaphoreWin32HandleKHR(VkDevice device,
3707 const VkSemaphoreGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3708 HANDLE *pHandle, VkResult result) {
3709 if (VK_SUCCESS != result) return;
3710 RecordGetExternalSemaphoreState(pGetWin32HandleInfo->semaphore, pGetWin32HandleInfo->handleType);
3711}
3712
3713void ValidationStateTracker::PostCallRecordImportFenceWin32HandleKHR(
3714 VkDevice device, const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo, VkResult result) {
3715 if (VK_SUCCESS != result) return;
3716 RecordImportFenceState(pImportFenceWin32HandleInfo->fence, pImportFenceWin32HandleInfo->handleType,
3717 pImportFenceWin32HandleInfo->flags);
3718}
3719
3720void ValidationStateTracker::PostCallRecordGetFenceWin32HandleKHR(VkDevice device,
3721 const VkFenceGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3722 HANDLE *pHandle, VkResult result) {
3723 if (VK_SUCCESS != result) return;
3724 RecordGetExternalFenceState(pGetWin32HandleInfo->fence, pGetWin32HandleInfo->handleType);
3725}
3726#endif
3727
3728void ValidationStateTracker::PostCallRecordGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *pGetFdInfo, int *pFd,
3729 VkResult result) {
3730 if (VK_SUCCESS != result) return;
3731 RecordGetExternalSemaphoreState(pGetFdInfo->semaphore, pGetFdInfo->handleType);
3732}
3733
Mike Schuchardt2df08912020-12-15 16:28:09 -08003734void ValidationStateTracker::RecordImportFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type,
3735 VkFenceImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06003736 FENCE_STATE *fence_node = GetFenceState(fence);
3737 if (fence_node && fence_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003738 if ((handle_type == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_FENCE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06003739 fence_node->scope == kSyncScopeInternal) {
3740 fence_node->scope = kSyncScopeExternalTemporary;
3741 } else {
3742 fence_node->scope = kSyncScopeExternalPermanent;
3743 }
3744 }
3745}
3746
3747void ValidationStateTracker::PostCallRecordImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo,
3748 VkResult result) {
3749 if (VK_SUCCESS != result) return;
3750 RecordImportFenceState(pImportFenceFdInfo->fence, pImportFenceFdInfo->handleType, pImportFenceFdInfo->flags);
3751}
3752
Mike Schuchardt2df08912020-12-15 16:28:09 -08003753void ValidationStateTracker::RecordGetExternalFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003754 FENCE_STATE *fence_state = GetFenceState(fence);
3755 if (fence_state) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003756 if (handle_type != VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003757 // Export with reference transference becomes external
3758 fence_state->scope = kSyncScopeExternalPermanent;
3759 } else if (fence_state->scope == kSyncScopeInternal) {
3760 // Export with copy transference has a side effect of resetting the fence
3761 fence_state->state = FENCE_UNSIGNALED;
3762 }
3763 }
3764}
3765
3766void ValidationStateTracker::PostCallRecordGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *pGetFdInfo, int *pFd,
3767 VkResult result) {
3768 if (VK_SUCCESS != result) return;
3769 RecordGetExternalFenceState(pGetFdInfo->fence, pGetFdInfo->handleType);
3770}
3771
3772void ValidationStateTracker::PostCallRecordCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
3773 const VkAllocationCallbacks *pAllocator, VkEvent *pEvent, VkResult result) {
3774 if (VK_SUCCESS != result) return;
John Zulaufd5115702021-01-18 12:34:33 -07003775 const auto event = *pEvent;
Jeremy Gebbencbf22862021-03-03 12:01:22 -07003776 eventMap.emplace(event, std::make_shared<EVENT_STATE>(event, pCreateInfo->flags));
locke-lunargd556cc32019-09-17 01:21:23 -06003777}
3778
3779void ValidationStateTracker::RecordCreateSwapchainState(VkResult result, const VkSwapchainCreateInfoKHR *pCreateInfo,
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003780 VkSwapchainKHR *pSwapchain, std::shared_ptr<SURFACE_STATE> &&surface_state,
locke-lunargd556cc32019-09-17 01:21:23 -06003781 SWAPCHAIN_NODE *old_swapchain_state) {
3782 if (VK_SUCCESS == result) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003783 if (surface_state->swapchain) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003784 surface_state->RemoveParent(surface_state->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003785 }
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003786 auto swapchain = CreateSwapchainState(pCreateInfo, *pSwapchain);
3787 surface_state->AddParent(swapchain.get());
3788 surface_state->swapchain = swapchain.get();
3789 swapchain->surface = std::move(surface_state);
3790 swapchainMap[*pSwapchain] = std::move(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003791 } else {
3792 surface_state->swapchain = nullptr;
3793 }
3794 // Spec requires that even if CreateSwapchainKHR fails, oldSwapchain is retired
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003795 // Retired swapchains remain associated with the surface until they are destroyed.
locke-lunargd556cc32019-09-17 01:21:23 -06003796 if (old_swapchain_state) {
3797 old_swapchain_state->retired = true;
3798 }
3799 return;
3800}
3801
3802void ValidationStateTracker::PostCallRecordCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
3803 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain,
3804 VkResult result) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003805 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfo->surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003806 auto old_swapchain_state = GetSwapchainState(pCreateInfo->oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003807 RecordCreateSwapchainState(result, pCreateInfo, pSwapchain, std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003808}
3809
3810void ValidationStateTracker::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
3811 const VkAllocationCallbacks *pAllocator) {
3812 if (!swapchain) return;
3813 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003814 if (!swapchain_data) return;
John Zulauffaa7a522021-03-05 12:22:45 -07003815
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003816 swapchain_data->Destroy();
3817 swapchainMap.erase(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003818}
3819
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003820void ValidationStateTracker::PostCallRecordCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
3821 const VkDisplayModeCreateInfoKHR *pCreateInfo,
3822 const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode,
3823 VkResult result) {
3824 if (VK_SUCCESS != result) return;
3825 if (!pMode) return;
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06003826 display_mode_map[*pMode] = std::make_shared<DISPLAY_MODE_STATE>(*pMode, physicalDevice);
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003827}
3828
locke-lunargd556cc32019-09-17 01:21:23 -06003829void ValidationStateTracker::PostCallRecordQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo, VkResult result) {
3830 // Semaphore waits occur before error generation, if the call reached the ICD. (Confirm?)
3831 for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003832 auto semaphore_state = GetSemaphoreState(pPresentInfo->pWaitSemaphores[i]);
3833 if (semaphore_state) {
3834 semaphore_state->signaler.first = VK_NULL_HANDLE;
3835 semaphore_state->signaled = false;
locke-lunargd556cc32019-09-17 01:21:23 -06003836 }
3837 }
3838
Tony-LunarG6f887e52021-07-27 11:23:14 -06003839 const auto *present_id_info = LvlFindInChain<VkPresentIdKHR>(pPresentInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003840 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
3841 // Note: this is imperfect, in that we can get confused about what did or didn't succeed-- but if the app does that, it's
3842 // confused itself just as much.
3843 auto local_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result;
3844 if (local_result != VK_SUCCESS && local_result != VK_SUBOPTIMAL_KHR) continue; // this present didn't actually happen.
3845 // Mark the image as having been released to the WSI
3846 auto swapchain_data = GetSwapchainState(pPresentInfo->pSwapchains[i]);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003847 if (swapchain_data) {
3848 swapchain_data->PresentImage(pPresentInfo->pImageIndices[i]);
Tony-LunarG6f887e52021-07-27 11:23:14 -06003849 if (present_id_info) {
3850 if (i < present_id_info->swapchainCount && present_id_info->pPresentIds[i] > swapchain_data->max_present_id) {
3851 swapchain_data->max_present_id = present_id_info->pPresentIds[i];
3852 }
3853 }
locke-lunargd556cc32019-09-17 01:21:23 -06003854 }
3855 }
3856 // Note: even though presentation is directed to a queue, there is no direct ordering between QP and subsequent work, so QP (and
3857 // its semaphore waits) /never/ participate in any completion proof.
3858}
3859
3860void ValidationStateTracker::PostCallRecordCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
3861 const VkSwapchainCreateInfoKHR *pCreateInfos,
3862 const VkAllocationCallbacks *pAllocator,
3863 VkSwapchainKHR *pSwapchains, VkResult result) {
3864 if (pCreateInfos) {
3865 for (uint32_t i = 0; i < swapchainCount; i++) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003866 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfos[i].surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003867 auto old_swapchain_state = GetSwapchainState(pCreateInfos[i].oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003868 RecordCreateSwapchainState(result, &pCreateInfos[i], &pSwapchains[i], std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003869 }
3870 }
3871}
3872
3873void ValidationStateTracker::RecordAcquireNextImageState(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3874 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003875 auto fence_state = GetFenceState(fence);
3876 if (fence_state && fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003877 // Treat as inflight since it is valid to wait on this fence, even in cases where it is technically a temporary
3878 // import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003879 fence_state->state = FENCE_INFLIGHT;
3880 fence_state->signaler.first = VK_NULL_HANDLE; // ANI isn't on a queue, so this can't participate in a completion proof.
locke-lunargd556cc32019-09-17 01:21:23 -06003881 }
3882
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003883 auto semaphore_state = GetSemaphoreState(semaphore);
3884 if (semaphore_state && semaphore_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003885 // Treat as signaled since it is valid to wait on this semaphore, even in cases where it is technically a
3886 // temporary import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003887 semaphore_state->signaled = true;
3888 semaphore_state->signaler.first = VK_NULL_HANDLE;
locke-lunargd556cc32019-09-17 01:21:23 -06003889 }
3890
3891 // Mark the image as acquired.
3892 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003893 if (swapchain_data) {
3894 swapchain_data->AcquireImage(*pImageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003895 }
3896}
3897
3898void ValidationStateTracker::PostCallRecordAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3899 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex,
3900 VkResult result) {
3901 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3902 RecordAcquireNextImageState(device, swapchain, timeout, semaphore, fence, pImageIndex);
3903}
3904
3905void ValidationStateTracker::PostCallRecordAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
3906 uint32_t *pImageIndex, VkResult result) {
3907 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3908 RecordAcquireNextImageState(device, pAcquireInfo->swapchain, pAcquireInfo->timeout, pAcquireInfo->semaphore,
3909 pAcquireInfo->fence, pImageIndex);
3910}
3911
3912void ValidationStateTracker::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
3913 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
3914 if ((NULL != pPhysicalDevices) && ((result == VK_SUCCESS || result == VK_INCOMPLETE))) {
3915 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
3916 auto &phys_device_state = physical_device_map[pPhysicalDevices[i]];
3917 phys_device_state.phys_device = pPhysicalDevices[i];
3918 // Init actual features for each physical device
3919 DispatchGetPhysicalDeviceFeatures(pPhysicalDevices[i], &phys_device_state.features2.features);
3920 }
3921 }
3922}
3923
3924// Common function to update state for GetPhysicalDeviceQueueFamilyProperties & 2KHR version
3925static void StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003926 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003927 pd_state->queue_family_known_count = std::max(pd_state->queue_family_known_count, count);
3928
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003929 if (pQueueFamilyProperties) { // Save queue family properties
locke-lunargd556cc32019-09-17 01:21:23 -06003930 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
3931 for (uint32_t i = 0; i < count; ++i) {
3932 pd_state->queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
3933 }
3934 }
3935}
3936
3937void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
3938 uint32_t *pQueueFamilyPropertyCount,
3939 VkQueueFamilyProperties *pQueueFamilyProperties) {
3940 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3941 assert(physical_device_state);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003942 VkQueueFamilyProperties2 *pqfp = nullptr;
3943 std::vector<VkQueueFamilyProperties2> qfp;
locke-lunargd556cc32019-09-17 01:21:23 -06003944 qfp.resize(*pQueueFamilyPropertyCount);
3945 if (pQueueFamilyProperties) {
3946 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003947 qfp[i] = LvlInitStruct<VkQueueFamilyProperties2>();
locke-lunargd556cc32019-09-17 01:21:23 -06003948 qfp[i].queueFamilyProperties = pQueueFamilyProperties[i];
3949 }
3950 pqfp = qfp.data();
3951 }
3952 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount, pqfp);
3953}
3954
3955void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003956 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003957 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3958 assert(physical_device_state);
3959 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3960 pQueueFamilyProperties);
3961}
3962
3963void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003964 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003965 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3966 assert(physical_device_state);
3967 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3968 pQueueFamilyProperties);
3969}
3970void ValidationStateTracker::PreCallRecordDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
3971 const VkAllocationCallbacks *pAllocator) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003972 if (!surface) return;
3973 auto surface_state = GetSurfaceState(surface);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003974 surface_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06003975 surface_map.erase(surface);
3976}
3977
3978void ValidationStateTracker::RecordVulkanSurface(VkSurfaceKHR *pSurface) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003979 surface_map[*pSurface] = std::make_shared<SURFACE_STATE>(*pSurface);
locke-lunargd556cc32019-09-17 01:21:23 -06003980}
3981
3982void ValidationStateTracker::PostCallRecordCreateDisplayPlaneSurfaceKHR(VkInstance instance,
3983 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
3984 const VkAllocationCallbacks *pAllocator,
3985 VkSurfaceKHR *pSurface, VkResult result) {
3986 if (VK_SUCCESS != result) return;
3987 RecordVulkanSurface(pSurface);
3988}
3989
3990#ifdef VK_USE_PLATFORM_ANDROID_KHR
3991void ValidationStateTracker::PostCallRecordCreateAndroidSurfaceKHR(VkInstance instance,
3992 const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
3993 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3994 VkResult result) {
3995 if (VK_SUCCESS != result) return;
3996 RecordVulkanSurface(pSurface);
3997}
3998#endif // VK_USE_PLATFORM_ANDROID_KHR
3999
4000#ifdef VK_USE_PLATFORM_IOS_MVK
4001void ValidationStateTracker::PostCallRecordCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
4002 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4003 VkResult result) {
4004 if (VK_SUCCESS != result) return;
4005 RecordVulkanSurface(pSurface);
4006}
4007#endif // VK_USE_PLATFORM_IOS_MVK
4008
4009#ifdef VK_USE_PLATFORM_MACOS_MVK
4010void ValidationStateTracker::PostCallRecordCreateMacOSSurfaceMVK(VkInstance instance,
4011 const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
4012 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4013 VkResult result) {
4014 if (VK_SUCCESS != result) return;
4015 RecordVulkanSurface(pSurface);
4016}
4017#endif // VK_USE_PLATFORM_MACOS_MVK
4018
Jeremy Kniagerf33a67c2019-12-09 09:44:39 -07004019#ifdef VK_USE_PLATFORM_METAL_EXT
4020void ValidationStateTracker::PostCallRecordCreateMetalSurfaceEXT(VkInstance instance,
4021 const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
4022 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4023 VkResult result) {
4024 if (VK_SUCCESS != result) return;
4025 RecordVulkanSurface(pSurface);
4026}
4027#endif // VK_USE_PLATFORM_METAL_EXT
4028
locke-lunargd556cc32019-09-17 01:21:23 -06004029#ifdef VK_USE_PLATFORM_WAYLAND_KHR
4030void ValidationStateTracker::PostCallRecordCreateWaylandSurfaceKHR(VkInstance instance,
4031 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
4032 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4033 VkResult result) {
4034 if (VK_SUCCESS != result) return;
4035 RecordVulkanSurface(pSurface);
4036}
4037#endif // VK_USE_PLATFORM_WAYLAND_KHR
4038
4039#ifdef VK_USE_PLATFORM_WIN32_KHR
4040void ValidationStateTracker::PostCallRecordCreateWin32SurfaceKHR(VkInstance instance,
4041 const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
4042 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4043 VkResult result) {
4044 if (VK_SUCCESS != result) return;
4045 RecordVulkanSurface(pSurface);
4046}
4047#endif // VK_USE_PLATFORM_WIN32_KHR
4048
4049#ifdef VK_USE_PLATFORM_XCB_KHR
4050void ValidationStateTracker::PostCallRecordCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
4051 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4052 VkResult result) {
4053 if (VK_SUCCESS != result) return;
4054 RecordVulkanSurface(pSurface);
4055}
4056#endif // VK_USE_PLATFORM_XCB_KHR
4057
4058#ifdef VK_USE_PLATFORM_XLIB_KHR
4059void ValidationStateTracker::PostCallRecordCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
4060 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4061 VkResult result) {
4062 if (VK_SUCCESS != result) return;
4063 RecordVulkanSurface(pSurface);
4064}
4065#endif // VK_USE_PLATFORM_XLIB_KHR
4066
Niklas Haas8b84af12020-04-19 22:20:11 +02004067void ValidationStateTracker::PostCallRecordCreateHeadlessSurfaceEXT(VkInstance instance,
4068 const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
4069 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4070 VkResult result) {
4071 if (VK_SUCCESS != result) return;
4072 RecordVulkanSurface(pSurface);
4073}
4074
Cort23cf2282019-09-20 18:58:18 +02004075void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02004076 VkPhysicalDeviceFeatures *pFeatures) {
4077 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Yilong Li358152a2020-07-08 02:16:45 -07004078 // Reset the features2 safe struct before setting up the features field.
4079 physical_device_state->features2 = safe_VkPhysicalDeviceFeatures2();
Cortffba2642019-09-20 22:09:41 +02004080 physical_device_state->features2.features = *pFeatures;
Cort23cf2282019-09-20 18:58:18 +02004081}
4082
4083void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02004084 VkPhysicalDeviceFeatures2 *pFeatures) {
4085 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02004086 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02004087}
4088
4089void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02004090 VkPhysicalDeviceFeatures2 *pFeatures) {
4091 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02004092 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02004093}
4094
locke-lunargd556cc32019-09-17 01:21:23 -06004095void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
4096 VkSurfaceKHR surface,
4097 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities,
4098 VkResult result) {
4099 if (VK_SUCCESS != result) return;
4100 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004101 physical_device_state->surfaceCapabilities = *pSurfaceCapabilities;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004102
4103 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
4104 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004105}
4106
4107void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(
4108 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
4109 VkSurfaceCapabilities2KHR *pSurfaceCapabilities, VkResult result) {
4110 if (VK_SUCCESS != result) return;
4111 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004112 physical_device_state->surfaceCapabilities = pSurfaceCapabilities->surfaceCapabilities;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004113
4114 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
4115 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004116}
4117
4118void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,
4119 VkSurfaceKHR surface,
4120 VkSurfaceCapabilities2EXT *pSurfaceCapabilities,
4121 VkResult result) {
4122 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004123 physical_device_state->surfaceCapabilities.minImageCount = pSurfaceCapabilities->minImageCount;
4124 physical_device_state->surfaceCapabilities.maxImageCount = pSurfaceCapabilities->maxImageCount;
4125 physical_device_state->surfaceCapabilities.currentExtent = pSurfaceCapabilities->currentExtent;
4126 physical_device_state->surfaceCapabilities.minImageExtent = pSurfaceCapabilities->minImageExtent;
4127 physical_device_state->surfaceCapabilities.maxImageExtent = pSurfaceCapabilities->maxImageExtent;
4128 physical_device_state->surfaceCapabilities.maxImageArrayLayers = pSurfaceCapabilities->maxImageArrayLayers;
4129 physical_device_state->surfaceCapabilities.supportedTransforms = pSurfaceCapabilities->supportedTransforms;
4130 physical_device_state->surfaceCapabilities.currentTransform = pSurfaceCapabilities->currentTransform;
4131 physical_device_state->surfaceCapabilities.supportedCompositeAlpha = pSurfaceCapabilities->supportedCompositeAlpha;
4132 physical_device_state->surfaceCapabilities.supportedUsageFlags = pSurfaceCapabilities->supportedUsageFlags;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004133
4134 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
4135 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004136}
4137
4138void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
4139 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
4140 VkBool32 *pSupported, VkResult result) {
4141 if (VK_SUCCESS != result) return;
4142 auto surface_state = GetSurfaceState(surface);
4143 surface_state->gpu_queue_support[{physicalDevice, queueFamilyIndex}] = (*pSupported == VK_TRUE);
4144}
4145
4146void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
4147 VkSurfaceKHR surface,
4148 uint32_t *pPresentModeCount,
4149 VkPresentModeKHR *pPresentModes,
4150 VkResult result) {
4151 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4152
4153 // TODO: This isn't quite right -- available modes may differ by surface AND physical device.
4154 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004155
4156 if (*pPresentModeCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004157 if (*pPresentModeCount > physical_device_state->present_modes.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06004158 physical_device_state->present_modes.resize(*pPresentModeCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004159 }
locke-lunargd556cc32019-09-17 01:21:23 -06004160 }
4161 if (pPresentModes) {
locke-lunargd556cc32019-09-17 01:21:23 -06004162 for (uint32_t i = 0; i < *pPresentModeCount; i++) {
4163 physical_device_state->present_modes[i] = pPresentModes[i];
4164 }
4165 }
4166}
4167
4168void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
4169 uint32_t *pSurfaceFormatCount,
4170 VkSurfaceFormatKHR *pSurfaceFormats,
4171 VkResult result) {
4172 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4173
4174 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004175
4176 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004177 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06004178 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004179 }
locke-lunargd556cc32019-09-17 01:21:23 -06004180 }
4181 if (pSurfaceFormats) {
locke-lunargd556cc32019-09-17 01:21:23 -06004182 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
4183 physical_device_state->surface_formats[i] = pSurfaceFormats[i];
4184 }
4185 }
4186}
4187
4188void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
4189 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
4190 uint32_t *pSurfaceFormatCount,
4191 VkSurfaceFormat2KHR *pSurfaceFormats,
4192 VkResult result) {
4193 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4194
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004195 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004196 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004197 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
4198 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
4199 }
locke-lunargd556cc32019-09-17 01:21:23 -06004200 }
4201 if (pSurfaceFormats) {
locke-lunargd556cc32019-09-17 01:21:23 -06004202 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004203 physical_device_state->surface_formats[i] = pSurfaceFormats[i].surfaceFormat;
locke-lunargd556cc32019-09-17 01:21:23 -06004204 }
4205 }
4206}
4207
4208void ValidationStateTracker::PreCallRecordCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4209 const VkDebugUtilsLabelEXT *pLabelInfo) {
4210 BeginCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4211}
4212
4213void ValidationStateTracker::PostCallRecordCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
4214 EndCmdDebugUtilsLabel(report_data, commandBuffer);
4215}
4216
4217void ValidationStateTracker::PreCallRecordCmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4218 const VkDebugUtilsLabelEXT *pLabelInfo) {
4219 InsertCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4220
4221 // Squirrel away an easily accessible copy.
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004222 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004223 cb_state->debug_label = LoggingLabel(pLabelInfo);
4224}
4225
4226void ValidationStateTracker::RecordEnumeratePhysicalDeviceGroupsState(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004227 uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06004228 if (NULL != pPhysicalDeviceGroupProperties) {
4229 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
4230 for (uint32_t j = 0; j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount; j++) {
4231 VkPhysicalDevice cur_phys_dev = pPhysicalDeviceGroupProperties[i].physicalDevices[j];
4232 auto &phys_device_state = physical_device_map[cur_phys_dev];
4233 phys_device_state.phys_device = cur_phys_dev;
4234 // Init actual features for each physical device
4235 DispatchGetPhysicalDeviceFeatures(cur_phys_dev, &phys_device_state.features2.features);
4236 }
4237 }
4238 }
4239}
4240
4241void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroups(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004242 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004243 VkResult result) {
4244 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4245 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4246}
4247
4248void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroupsKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004249 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004250 VkResult result) {
4251 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4252 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4253}
4254
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004255void ValidationStateTracker::RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(VkPhysicalDevice physicalDevice,
4256 uint32_t queueFamilyIndex,
4257 uint32_t *pCounterCount,
4258 VkPerformanceCounterKHR *pCounters) {
4259 if (NULL == pCounters) return;
4260
4261 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4262 assert(physical_device_state);
4263
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004264 std::unique_ptr<QUEUE_FAMILY_PERF_COUNTERS> queue_family_counters(new QUEUE_FAMILY_PERF_COUNTERS());
4265 queue_family_counters->counters.resize(*pCounterCount);
4266 for (uint32_t i = 0; i < *pCounterCount; i++) queue_family_counters->counters[i] = pCounters[i];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004267
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004268 physical_device_state->perf_counters[queueFamilyIndex] = std::move(queue_family_counters);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004269}
4270
4271void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
4272 VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t *pCounterCount, VkPerformanceCounterKHR *pCounters,
4273 VkPerformanceCounterDescriptionKHR *pCounterDescriptions, VkResult result) {
4274 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4275 RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(physicalDevice, queueFamilyIndex, pCounterCount, pCounters);
4276}
4277
4278void ValidationStateTracker::PostCallRecordAcquireProfilingLockKHR(VkDevice device, const VkAcquireProfilingLockInfoKHR *pInfo,
4279 VkResult result) {
4280 if (result == VK_SUCCESS) performance_lock_acquired = true;
4281}
4282
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004283void ValidationStateTracker::PostCallRecordReleaseProfilingLockKHR(VkDevice device) {
4284 performance_lock_acquired = false;
4285 for (auto &cmd_buffer : commandBufferMap) {
4286 cmd_buffer.second->performance_lock_released = true;
4287 }
4288}
4289
locke-lunargd556cc32019-09-17 01:21:23 -06004290void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplate(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004291 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004292 const VkAllocationCallbacks *pAllocator) {
4293 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004294 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4295 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004296 desc_template_map.erase(descriptorUpdateTemplate);
4297}
4298
4299void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplateKHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004300 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004301 const VkAllocationCallbacks *pAllocator) {
4302 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004303 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4304 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004305 desc_template_map.erase(descriptorUpdateTemplate);
4306}
4307
Mike Schuchardt2df08912020-12-15 16:28:09 -08004308void ValidationStateTracker::RecordCreateDescriptorUpdateTemplateState(const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4309 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
locke-lunargd556cc32019-09-17 01:21:23 -06004310 safe_VkDescriptorUpdateTemplateCreateInfo local_create_info(pCreateInfo);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004311 auto template_state = std::make_shared<TEMPLATE_STATE>(*pDescriptorUpdateTemplate, &local_create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004312 desc_template_map[*pDescriptorUpdateTemplate] = std::move(template_state);
4313}
4314
Mike Schuchardt2df08912020-12-15 16:28:09 -08004315void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplate(VkDevice device,
4316 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4317 const VkAllocationCallbacks *pAllocator,
4318 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate,
4319 VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004320 if (VK_SUCCESS != result) return;
4321 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4322}
4323
4324void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplateKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004325 VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
4326 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004327 if (VK_SUCCESS != result) return;
4328 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4329}
4330
4331void ValidationStateTracker::RecordUpdateDescriptorSetWithTemplateState(VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004332 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004333 const void *pData) {
4334 auto const template_map_entry = desc_template_map.find(descriptorUpdateTemplate);
4335 if ((template_map_entry == desc_template_map.end()) || (template_map_entry->second.get() == nullptr)) {
4336 assert(0);
4337 } else {
4338 const TEMPLATE_STATE *template_state = template_map_entry->second.get();
4339 // TODO: Record template push descriptor updates
4340 if (template_state->create_info.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET) {
4341 PerformUpdateDescriptorSetsWithTemplateKHR(descriptorSet, template_state, pData);
4342 }
4343 }
4344}
4345
4346void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
4347 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4348 const void *pData) {
4349 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4350}
4351
4352void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004353 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004354 const void *pData) {
4355 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4356}
4357
Mike Schuchardt2df08912020-12-15 16:28:09 -08004358void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
4359 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4360 VkPipelineLayout layout, uint32_t set,
4361 const void *pData) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004362 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004363
4364 const auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4365 if (template_state) {
4366 auto layout_data = GetPipelineLayout(layout);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06004367 auto dsl = layout_data ? layout_data->GetDsl(set) : nullptr;
locke-lunargd556cc32019-09-17 01:21:23 -06004368 const auto &template_ci = template_state->create_info;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004369 // Decode the template into a set of write updates
4370 cvdescriptorset::DecodedTemplateUpdate decoded_template(this, VK_NULL_HANDLE, template_state, pData,
4371 dsl->GetDescriptorSetLayout());
4372 cb_state->PushDescriptorSetState(template_ci.pipelineBindPoint, layout_data, set,
4373 static_cast<uint32_t>(decoded_template.desc_writes.size()),
4374 decoded_template.desc_writes.data());
locke-lunargd556cc32019-09-17 01:21:23 -06004375 }
4376}
4377
4378void ValidationStateTracker::RecordGetPhysicalDeviceDisplayPlanePropertiesState(VkPhysicalDevice physicalDevice,
4379 uint32_t *pPropertyCount, void *pProperties) {
4380 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4381 if (*pPropertyCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004382 physical_device_state->display_plane_property_count = *pPropertyCount;
4383 }
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004384 if (*pPropertyCount || pProperties) {
4385 physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004386 }
4387}
4388
4389void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
4390 uint32_t *pPropertyCount,
4391 VkDisplayPlanePropertiesKHR *pProperties,
4392 VkResult result) {
4393 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4394 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4395}
4396
4397void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
4398 uint32_t *pPropertyCount,
4399 VkDisplayPlaneProperties2KHR *pProperties,
4400 VkResult result) {
4401 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4402 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4403}
4404
4405void ValidationStateTracker::PostCallRecordCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4406 uint32_t query, VkQueryControlFlags flags, uint32_t index) {
4407 QueryObject query_obj = {queryPool, query, index};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004408 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004409 cb_state->BeginQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004410}
4411
4412void ValidationStateTracker::PostCallRecordCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4413 uint32_t query, uint32_t index) {
4414 QueryObject query_obj = {queryPool, query, index};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004415 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004416 cb_state->EndQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004417}
4418
4419void ValidationStateTracker::RecordCreateSamplerYcbcrConversionState(const VkSamplerYcbcrConversionCreateInfo *create_info,
4420 VkSamplerYcbcrConversion ycbcr_conversion) {
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004421 VkFormatFeatureFlags format_features = 0;
4422
4423 if (create_info->format != VK_FORMAT_UNDEFINED) {
4424 format_features = GetPotentialFormatFeatures(create_info->format);
4425 } else if (device_extensions.vk_android_external_memory_android_hardware_buffer) {
4426 // If format is VK_FORMAT_UNDEFINED, format_features will be set by external AHB features
4427 format_features = GetExternalFormatFeaturesANDROID(create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004428 }
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004429
4430 samplerYcbcrConversionMap[ycbcr_conversion] =
4431 std::make_shared<SAMPLER_YCBCR_CONVERSION_STATE>(ycbcr_conversion, create_info, format_features);
locke-lunargd556cc32019-09-17 01:21:23 -06004432}
4433
4434void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversion(VkDevice device,
4435 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4436 const VkAllocationCallbacks *pAllocator,
4437 VkSamplerYcbcrConversion *pYcbcrConversion,
4438 VkResult result) {
4439 if (VK_SUCCESS != result) return;
4440 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4441}
4442
4443void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversionKHR(VkDevice device,
4444 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4445 const VkAllocationCallbacks *pAllocator,
4446 VkSamplerYcbcrConversion *pYcbcrConversion,
4447 VkResult result) {
4448 if (VK_SUCCESS != result) return;
4449 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4450}
4451
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004452void ValidationStateTracker::RecordDestroySamplerYcbcrConversionState(VkSamplerYcbcrConversion ycbcr_conversion) {
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004453 auto ycbcr_state = GetSamplerYcbcrConversionState(ycbcr_conversion);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004454 ycbcr_state->Destroy();
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004455 samplerYcbcrConversionMap.erase(ycbcr_conversion);
4456}
4457
locke-lunargd556cc32019-09-17 01:21:23 -06004458void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
4459 const VkAllocationCallbacks *pAllocator) {
4460 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004461 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004462}
4463
4464void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversionKHR(VkDevice device,
4465 VkSamplerYcbcrConversion ycbcrConversion,
4466 const VkAllocationCallbacks *pAllocator) {
4467 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004468 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004469}
4470
Tony-LunarG977448c2019-12-02 14:52:02 -07004471void ValidationStateTracker::RecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4472 uint32_t queryCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004473 // Do nothing if the feature is not enabled.
Piers Daniell41b8c5d2020-01-10 15:42:00 -07004474 if (!enabled_features.core12.hostQueryReset) return;
locke-lunargd556cc32019-09-17 01:21:23 -06004475
4476 // Do nothing if the query pool has been destroyed.
4477 auto query_pool_state = GetQueryPoolState(queryPool);
4478 if (!query_pool_state) return;
4479
4480 // Reset the state of existing entries.
4481 QueryObject query_obj{queryPool, 0};
4482 const uint32_t max_query_count = std::min(queryCount, query_pool_state->createInfo.queryCount - firstQuery);
4483 for (uint32_t i = 0; i < max_query_count; ++i) {
4484 query_obj.query = firstQuery + i;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004485 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004486 if (query_pool_state->createInfo.queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004487 for (uint32_t pass_index = 0; pass_index < query_pool_state->n_performance_passes; pass_index++) {
4488 query_obj.perf_pass = pass_index;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004489 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004490 }
4491 }
locke-lunargd556cc32019-09-17 01:21:23 -06004492 }
4493}
4494
Tony-LunarG977448c2019-12-02 14:52:02 -07004495void ValidationStateTracker::PostCallRecordResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4496 uint32_t queryCount) {
4497 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4498}
4499
4500void ValidationStateTracker::PostCallRecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4501 uint32_t queryCount) {
4502 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4503}
4504
locke-lunargd556cc32019-09-17 01:21:23 -06004505void ValidationStateTracker::PerformUpdateDescriptorSetsWithTemplateKHR(VkDescriptorSet descriptorSet,
4506 const TEMPLATE_STATE *template_state, const void *pData) {
4507 // Translate the templated update into a normal update for validation...
4508 cvdescriptorset::DecodedTemplateUpdate decoded_update(this, descriptorSet, template_state, pData);
4509 cvdescriptorset::PerformUpdateDescriptorSets(this, static_cast<uint32_t>(decoded_update.desc_writes.size()),
4510 decoded_update.desc_writes.data(), 0, NULL);
4511}
4512
4513// Update the common AllocateDescriptorSetsData
4514void ValidationStateTracker::UpdateAllocateDescriptorSetsData(const VkDescriptorSetAllocateInfo *p_alloc_info,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05004515 cvdescriptorset::AllocateDescriptorSetsData *ds_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004516 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05004517 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06004518 if (layout) {
4519 ds_data->layout_nodes[i] = layout;
4520 // Count total descriptors required per type
4521 for (uint32_t j = 0; j < layout->GetBindingCount(); ++j) {
4522 const auto &binding_layout = layout->GetDescriptorSetLayoutBindingPtrFromIndex(j);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004523 uint32_t type_index = static_cast<uint32_t>(binding_layout->descriptorType);
4524 ds_data->required_descriptors_by_type[type_index] += binding_layout->descriptorCount;
locke-lunargd556cc32019-09-17 01:21:23 -06004525 }
4526 }
4527 // Any unknown layouts will be flagged as errors during ValidateAllocateDescriptorSets() call
4528 }
4529}
4530
4531// Decrement allocated sets from the pool and insert new sets into set_map
4532void ValidationStateTracker::PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
4533 const VkDescriptorSet *descriptor_sets,
4534 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) {
4535 auto pool_state = descriptorPoolMap[p_alloc_info->descriptorPool].get();
4536 // Account for sets and individual descriptors allocated from pool
4537 pool_state->availableSets -= p_alloc_info->descriptorSetCount;
4538 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
4539 pool_state->availableDescriptorTypeCount[it->first] -= ds_data->required_descriptors_by_type.at(it->first);
4540 }
4541
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07004542 const auto *variable_count_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(p_alloc_info->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06004543 bool variable_count_valid = variable_count_info && variable_count_info->descriptorSetCount == p_alloc_info->descriptorSetCount;
4544
4545 // Create tracking object for each descriptor set; insert into global map and the pool's set.
4546 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
4547 uint32_t variable_count = variable_count_valid ? variable_count_info->pDescriptorCounts[i] : 0;
4548
Jeff Bolz41a1ced2019-10-11 11:40:49 -05004549 auto new_ds = std::make_shared<cvdescriptorset::DescriptorSet>(descriptor_sets[i], pool_state, ds_data->layout_nodes[i],
John Zulaufd2c3dae2019-12-12 11:02:17 -07004550 variable_count, this);
locke-lunargd556cc32019-09-17 01:21:23 -06004551 pool_state->sets.insert(new_ds.get());
locke-lunargd556cc32019-09-17 01:21:23 -06004552 setMap[descriptor_sets[i]] = std::move(new_ds);
4553 }
4554}
4555
locke-lunargd556cc32019-09-17 01:21:23 -06004556void ValidationStateTracker::PostCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
4557 uint32_t firstVertex, uint32_t firstInstance) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004558 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004559 cb_state->UpdateStateCmdDrawType(CMD_DRAW, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDraw()");
locke-lunargd556cc32019-09-17 01:21:23 -06004560}
4561
Tony-LunarG745150c2021-07-02 15:07:31 -06004562void ValidationStateTracker::PostCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4563 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
4564 uint32_t firstInstance, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004565 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004566 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004567}
4568
locke-lunargd556cc32019-09-17 01:21:23 -06004569void ValidationStateTracker::PostCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
4570 uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
4571 uint32_t firstInstance) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004572 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004573 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXED, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexed()");
locke-lunargd556cc32019-09-17 01:21:23 -06004574}
4575
Tony-LunarG745150c2021-07-02 15:07:31 -06004576void ValidationStateTracker::PostCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4577 const VkMultiDrawIndexedInfoEXT *pIndexInfo,
4578 uint32_t instanceCount, uint32_t firstInstance, uint32_t stride,
4579 const int32_t *pVertexOffset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004580 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004581 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIINDEXEDEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiIndexedEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004582}
4583
locke-lunargd556cc32019-09-17 01:21:23 -06004584void ValidationStateTracker::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4585 uint32_t count, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004586 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004587 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004588 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004589 if (!disabled[command_buffer_state]) {
4590 cb_state->AddChild(buffer_state);
4591 }
locke-lunargd556cc32019-09-17 01:21:23 -06004592}
4593
4594void ValidationStateTracker::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4595 VkDeviceSize offset, uint32_t count, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004596 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004597 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004598 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexedIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004599 if (!disabled[command_buffer_state]) {
4600 cb_state->AddChild(buffer_state);
4601 }
locke-lunargd556cc32019-09-17 01:21:23 -06004602}
4603
4604void ValidationStateTracker::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004605 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004606 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCH, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatch()");
locke-lunargd556cc32019-09-17 01:21:23 -06004607}
4608
4609void ValidationStateTracker::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4610 VkDeviceSize offset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004611 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004612 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCHINDIRECT, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatchIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004613 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004614 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004615 cb_state->AddChild(buffer_state);
4616 }
locke-lunargd556cc32019-09-17 01:21:23 -06004617}
4618
Tony-LunarG977448c2019-12-02 14:52:02 -07004619void ValidationStateTracker::RecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4620 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
locke-lunarg540b2252020-08-03 13:23:36 -06004621 uint32_t stride, const char *function) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004622 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004623 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004624 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004625 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4626 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004627 cb_state->AddChild(buffer_state);
4628 cb_state->AddChild(count_buffer_state);
4629 }
Tony-LunarG977448c2019-12-02 14:52:02 -07004630}
4631
locke-lunargd556cc32019-09-17 01:21:23 -06004632void ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4633 VkDeviceSize offset, VkBuffer countBuffer,
4634 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4635 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004636 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4637 "vkCmdDrawIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004638}
4639
4640void ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4641 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
4642 uint32_t maxDrawCount, uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004643 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4644 "vkCmdDrawIndirectCount()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004645}
4646
4647void ValidationStateTracker::RecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4648 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
locke-lunarg540b2252020-08-03 13:23:36 -06004649 uint32_t maxDrawCount, uint32_t stride, const char *function) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004650 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004651 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004652 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004653 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4654 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004655 cb_state->AddChild(buffer_state);
4656 cb_state->AddChild(count_buffer_state);
4657 }
locke-lunargd556cc32019-09-17 01:21:23 -06004658}
4659
4660void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4661 VkDeviceSize offset, VkBuffer countBuffer,
4662 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4663 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004664 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4665 "vkCmdDrawIndexedIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004666}
4667
4668void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
4669 VkDeviceSize offset, VkBuffer countBuffer,
4670 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4671 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004672 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4673 "vkCmdDrawIndexedIndirectCount()");
locke-lunargd556cc32019-09-17 01:21:23 -06004674}
4675
4676void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount,
4677 uint32_t firstTask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004678 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004679 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSNV, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMeshTasksNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004680}
4681
4682void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4683 VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004684 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004685 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4686 "vkCmdDrawMeshTasksIndirectNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004687 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004688 if (!disabled[command_buffer_state] && buffer_state) {
4689 cb_state->AddChild(buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -06004690 }
4691}
4692
4693void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4694 VkDeviceSize offset, VkBuffer countBuffer,
4695 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4696 uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004697 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004698 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTCOUNTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4699 "vkCmdDrawMeshTasksIndirectCountNV()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004700 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004701 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4702 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004703 if (buffer_state) {
4704 cb_state->AddChild(buffer_state);
4705 }
4706 if (count_buffer_state) {
4707 cb_state->AddChild(count_buffer_state);
4708 }
locke-lunargd556cc32019-09-17 01:21:23 -06004709 }
4710}
4711
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004712void ValidationStateTracker::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
4713 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
4714 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
4715 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
4716 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
4717 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
4718 uint32_t width, uint32_t height, uint32_t depth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004719 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004720 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSNV, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, "vkCmdTraceRaysNV()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004721 cb_state->hasTraceRaysCmd = true;
4722}
4723
4724
4725void ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
4726 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4727 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4728 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4729 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
4730 uint32_t height, uint32_t depth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004731 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004732 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, "vkCmdTraceRaysKHR()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004733 cb_state->hasTraceRaysCmd = true;
4734}
4735
4736void ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
4737 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4738 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4739 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4740 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
4741 VkDeviceAddress indirectDeviceAddress) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004742 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004743 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSINDIRECTKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004744 "vkCmdTraceRaysIndirectKHR()");
4745 cb_state->hasTraceRaysCmd = true;
4746}
4747
locke-lunargd556cc32019-09-17 01:21:23 -06004748void ValidationStateTracker::PostCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
4749 const VkAllocationCallbacks *pAllocator,
4750 VkShaderModule *pShaderModule, VkResult result,
4751 void *csm_state_data) {
4752 if (VK_SUCCESS != result) return;
4753 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
4754
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06004755 spv_target_env spirv_environment = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
locke-lunargd556cc32019-09-17 01:21:23 -06004756 bool is_spirv = (pCreateInfo->pCode[0] == spv::MagicNumber);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004757 auto new_shader_module = is_spirv ? std::make_shared<SHADER_MODULE_STATE>(pCreateInfo, *pShaderModule, spirv_environment,
4758 csm_state->unique_shader_id)
4759 : std::make_shared<SHADER_MODULE_STATE>();
sfricke-samsung962cad92021-04-13 00:46:29 -07004760 new_shader_module->SetPushConstantUsedInShader();
locke-lunargd556cc32019-09-17 01:21:23 -06004761 shaderModuleMap[*pShaderModule] = std::move(new_shader_module);
4762}
4763
4764void ValidationStateTracker::RecordPipelineShaderStage(VkPipelineShaderStageCreateInfo const *pStage, PIPELINE_STATE *pipeline,
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06004765 PipelineStageState *stage_state) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004766 // Validation shouldn't rely on anything in stage state being valid if the spirv isn't
locke-lunargde3f0fa2020-09-10 11:55:31 -06004767 stage_state->entry_point_name = pStage->pName;
4768 stage_state->shader_state = GetShared<SHADER_MODULE_STATE>(pStage->module);
4769 auto module = stage_state->shader_state.get();
locke-lunargd556cc32019-09-17 01:21:23 -06004770 if (!module->has_valid_spirv) return;
4771
4772 // Validation shouldn't rely on anything in stage state being valid if the entrypoint isn't present
sfricke-samsung962cad92021-04-13 00:46:29 -07004773 auto entrypoint = module->FindEntrypoint(pStage->pName, pStage->stage);
locke-lunargd556cc32019-09-17 01:21:23 -06004774 if (entrypoint == module->end()) return;
4775
locke-lunarg654e3692020-06-04 17:19:15 -06004776 stage_state->stage_flag = pStage->stage;
4777
locke-lunargd556cc32019-09-17 01:21:23 -06004778 // Mark accessible ids
sfricke-samsung962cad92021-04-13 00:46:29 -07004779 stage_state->accessible_ids = module->MarkAccessibleIds(entrypoint);
4780 module->ProcessExecutionModes(entrypoint, pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06004781
sfricke-samsung962cad92021-04-13 00:46:29 -07004782 stage_state->descriptor_uses = module->CollectInterfaceByDescriptorSlot(
4783 stage_state->accessible_ids, &stage_state->has_writable_descriptor, &stage_state->has_atomic_descriptor);
locke-lunargd556cc32019-09-17 01:21:23 -06004784 // Capture descriptor uses for the pipeline
locke-lunarg36045992020-08-20 16:54:37 -06004785 for (const auto &use : stage_state->descriptor_uses) {
locke-lunargd556cc32019-09-17 01:21:23 -06004786 // While validating shaders capture which slots are used by the pipeline
John Zulauf649edd52019-10-02 14:39:41 -06004787 const uint32_t slot = use.first.first;
locke-lunarg351c9d82020-10-23 14:43:21 -06004788 pipeline->active_slots[slot][use.first.second].is_writable |= use.second.is_writable;
locke-lunarg36045992020-08-20 16:54:37 -06004789 auto &reqs = pipeline->active_slots[slot][use.first.second].reqs;
sfricke-samsung962cad92021-04-13 00:46:29 -07004790 reqs = descriptor_req(reqs | module->DescriptorTypeToReqs(use.second.type_id));
locke-lunarg25b6c352020-08-06 17:44:18 -06004791 if (use.second.is_atomic_operation) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION);
locke-lunarg12d20992020-09-21 12:46:49 -06004792 if (use.second.is_sampler_implicitLod_dref_proj) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ);
locke-lunargae2a43c2020-09-22 17:21:57 -06004793 if (use.second.is_sampler_bias_offset) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET);
locke-lunarg12d20992020-09-21 12:46:49 -06004794
John Zulauf649edd52019-10-02 14:39:41 -06004795 pipeline->max_active_slot = std::max(pipeline->max_active_slot, slot);
locke-lunarg36045992020-08-20 16:54:37 -06004796 if (use.second.samplers_used_by_image.size()) {
locke-lunarg654a9052020-10-13 16:28:42 -06004797 auto &samplers_used_by_image = pipeline->active_slots[slot][use.first.second].samplers_used_by_image;
4798 if (use.second.samplers_used_by_image.size() > samplers_used_by_image.size()) {
4799 samplers_used_by_image.resize(use.second.samplers_used_by_image.size());
4800 }
locke-lunarg654a9052020-10-13 16:28:42 -06004801 uint32_t image_index = 0;
4802 for (const auto &samplers : use.second.samplers_used_by_image) {
4803 for (const auto &sampler : samplers) {
locke-lunargb8be8222020-10-20 00:34:37 -06004804 samplers_used_by_image[image_index].emplace(sampler, nullptr);
locke-lunarg654a9052020-10-13 16:28:42 -06004805 }
4806 ++image_index;
4807 }
locke-lunarg36045992020-08-20 16:54:37 -06004808 }
locke-lunargd556cc32019-09-17 01:21:23 -06004809 }
locke-lunarg78486832020-09-09 19:39:42 -06004810
locke-lunarg96dc9632020-06-10 17:22:18 -06004811 if (pStage->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
sfricke-samsung962cad92021-04-13 00:46:29 -07004812 pipeline->fragmentShader_writable_output_location_list = module->CollectWritableOutputLocationinFS(*pStage);
locke-lunarg96dc9632020-06-10 17:22:18 -06004813 }
locke-lunargd556cc32019-09-17 01:21:23 -06004814}
4815
John Zulauf22b0fbe2019-10-15 06:26:16 -06004816void ValidationStateTracker::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
4817 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages,
4818 VkResult result) {
4819 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004820 auto swapchain_state = GetShared<SWAPCHAIN_NODE>(swapchain);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004821
4822 if (*pSwapchainImageCount > swapchain_state->images.size()) swapchain_state->images.resize(*pSwapchainImageCount);
4823
4824 if (pSwapchainImages) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004825 for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
John Zulauf29d00532021-03-04 13:28:54 -07004826 SWAPCHAIN_IMAGE &swapchain_image = swapchain_state->images[i];
John Zulauffaa7a522021-03-05 12:22:45 -07004827 if (swapchain_image.image_state) continue; // Already retrieved this.
John Zulauf22b0fbe2019-10-15 06:26:16 -06004828
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004829 auto format_features =
4830 GetImageFormatFeatures(physical_device, device, pSwapchainImages[i], swapchain_state->image_create_info.format,
4831 swapchain_state->image_create_info.tiling);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004832
Jeremy Gebbenbcba6d32021-07-16 11:41:41 -06004833 auto image_state = std::make_shared<IMAGE_STATE>(device, pSwapchainImages[i], swapchain_state->image_create_info.ptr(),
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004834 swapchain, i, format_features);
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004835 if (!swapchain_image.fake_base_address) {
4836 auto size = image_state->fragment_encoder->TotalSize();
4837 swapchain_image.fake_base_address = fake_memory.Alloc(size);
John Zulauf29d00532021-03-04 13:28:54 -07004838 }
4839
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004840 image_state->SetSwapchain(swapchain_state, i);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004841 swapchain_image.image_state = image_state.get();
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004842 imageMap[pSwapchainImages[i]] = std::move(image_state);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004843 }
4844 }
4845
4846 if (*pSwapchainImageCount) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004847 swapchain_state->get_swapchain_image_count = *pSwapchainImageCount;
4848 }
4849}
sourav parmar35e7a002020-06-09 17:58:44 -07004850
sourav parmar35e7a002020-06-09 17:58:44 -07004851void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer,
4852 const VkCopyAccelerationStructureInfoKHR *pInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004853 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmar35e7a002020-06-09 17:58:44 -07004854 if (cb_state) {
sourav parmarcd5fb182020-07-17 12:58:44 -07004855 ACCELERATION_STRUCTURE_STATE_KHR *src_as_state = GetAccelerationStructureStateKHR(pInfo->src);
4856 ACCELERATION_STRUCTURE_STATE_KHR *dst_as_state = GetAccelerationStructureStateKHR(pInfo->dst);
sourav parmar35e7a002020-06-09 17:58:44 -07004857 if (dst_as_state != nullptr && src_as_state != nullptr) {
4858 dst_as_state->built = true;
4859 dst_as_state->build_info_khr = src_as_state->build_info_khr;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004860 if (!disabled[command_buffer_state]) {
4861 cb_state->AddChild(dst_as_state);
4862 cb_state->AddChild(src_as_state);
4863 }
sourav parmar35e7a002020-06-09 17:58:44 -07004864 }
4865 }
4866}
Piers Daniell39842ee2020-07-10 16:42:33 -06004867
4868void ValidationStateTracker::PreCallRecordCmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004869 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004870 cb_state->status |= CBSTATUS_CULL_MODE_SET;
4871 cb_state->static_status &= ~CBSTATUS_CULL_MODE_SET;
4872}
4873
4874void ValidationStateTracker::PreCallRecordCmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004875 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004876 cb_state->status |= CBSTATUS_FRONT_FACE_SET;
4877 cb_state->static_status &= ~CBSTATUS_FRONT_FACE_SET;
4878}
4879
4880void ValidationStateTracker::PreCallRecordCmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
4881 VkPrimitiveTopology primitiveTopology) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004882 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004883 cb_state->primitiveTopology = primitiveTopology;
4884 cb_state->status |= CBSTATUS_PRIMITIVE_TOPOLOGY_SET;
4885 cb_state->static_status &= ~CBSTATUS_PRIMITIVE_TOPOLOGY_SET;
4886}
4887
4888void ValidationStateTracker::PreCallRecordCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer, uint32_t viewportCount,
4889 const VkViewport *pViewports) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004890 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004891 uint32_t bits = (1u << viewportCount) - 1u;
4892 cb_state->viewportWithCountMask |= bits;
4893 cb_state->trashedViewportMask &= ~bits;
Tobias Hector6663c9b2020-11-05 10:18:02 +00004894 cb_state->viewportWithCountCount = viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004895 cb_state->trashedViewportCount = false;
Piers Daniell39842ee2020-07-10 16:42:33 -06004896 cb_state->status |= CBSTATUS_VIEWPORT_WITH_COUNT_SET;
4897 cb_state->static_status &= ~CBSTATUS_VIEWPORT_WITH_COUNT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004898
4899 cb_state->dynamicViewports.resize(std::max(size_t(viewportCount), cb_state->dynamicViewports.size()));
4900 for (size_t i = 0; i < viewportCount; ++i) {
4901 cb_state->dynamicViewports[i] = pViewports[i];
4902 }
Piers Daniell39842ee2020-07-10 16:42:33 -06004903}
4904
4905void ValidationStateTracker::PreCallRecordCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount,
4906 const VkRect2D *pScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004907 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004908 uint32_t bits = (1u << scissorCount) - 1u;
4909 cb_state->scissorWithCountMask |= bits;
4910 cb_state->trashedScissorMask &= ~bits;
4911 cb_state->scissorWithCountCount = scissorCount;
4912 cb_state->trashedScissorCount = false;
Piers Daniell39842ee2020-07-10 16:42:33 -06004913 cb_state->status |= CBSTATUS_SCISSOR_WITH_COUNT_SET;
4914 cb_state->static_status &= ~CBSTATUS_SCISSOR_WITH_COUNT_SET;
4915}
4916
4917void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
4918 uint32_t bindingCount, const VkBuffer *pBuffers,
4919 const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes,
4920 const VkDeviceSize *pStrides) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004921 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004922 if (pStrides) {
4923 cb_state->status |= CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET;
4924 cb_state->static_status &= ~CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET;
4925 }
4926
4927 uint32_t end = firstBinding + bindingCount;
4928 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
4929 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
4930 }
4931
4932 for (uint32_t i = 0; i < bindingCount; ++i) {
4933 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07004934 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
Piers Daniell39842ee2020-07-10 16:42:33 -06004935 vertex_buffer_binding.offset = pOffsets[i];
4936 vertex_buffer_binding.size = (pSizes) ? pSizes[i] : VK_WHOLE_SIZE;
4937 vertex_buffer_binding.stride = (pStrides) ? pStrides[i] : 0;
4938 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004939 if (!disabled[command_buffer_state] && pBuffers[i]) {
4940 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Piers Daniell39842ee2020-07-10 16:42:33 -06004941 }
4942 }
4943}
4944
4945void ValidationStateTracker::PreCallRecordCmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004946 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004947 cb_state->status |= CBSTATUS_DEPTH_TEST_ENABLE_SET;
4948 cb_state->static_status &= ~CBSTATUS_DEPTH_TEST_ENABLE_SET;
4949}
4950
4951void ValidationStateTracker::PreCallRecordCmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004952 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004953 cb_state->status |= CBSTATUS_DEPTH_WRITE_ENABLE_SET;
4954 cb_state->static_status &= ~CBSTATUS_DEPTH_WRITE_ENABLE_SET;
4955}
4956
4957void ValidationStateTracker::PreCallRecordCmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004958 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004959 cb_state->status |= CBSTATUS_DEPTH_COMPARE_OP_SET;
4960 cb_state->static_status &= ~CBSTATUS_DEPTH_COMPARE_OP_SET;
4961}
4962
4963void ValidationStateTracker::PreCallRecordCmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,
4964 VkBool32 depthBoundsTestEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004965 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004966 cb_state->status |= CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET;
4967 cb_state->static_status &= ~CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET;
4968}
4969void ValidationStateTracker::PreCallRecordCmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004970 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004971 cb_state->status |= CBSTATUS_STENCIL_TEST_ENABLE_SET;
4972 cb_state->static_status &= ~CBSTATUS_STENCIL_TEST_ENABLE_SET;
4973}
4974
4975void ValidationStateTracker::PreCallRecordCmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
4976 VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
4977 VkCompareOp compareOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004978 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell39842ee2020-07-10 16:42:33 -06004979 cb_state->status |= CBSTATUS_STENCIL_OP_SET;
4980 cb_state->static_status &= ~CBSTATUS_STENCIL_OP_SET;
4981}
locke-lunarg4189aa22020-10-21 00:23:48 -06004982
4983void ValidationStateTracker::PreCallRecordCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle,
4984 uint32_t discardRectangleCount,
4985 const VkRect2D *pDiscardRectangles) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004986 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunarg4189aa22020-10-21 00:23:48 -06004987 cb_state->status |= CBSTATUS_DISCARD_RECTANGLE_SET;
4988 cb_state->static_status &= ~CBSTATUS_DISCARD_RECTANGLE_SET;
4989}
4990
4991void ValidationStateTracker::PreCallRecordCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
4992 const VkSampleLocationsInfoEXT *pSampleLocationsInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004993 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunarg4189aa22020-10-21 00:23:48 -06004994 cb_state->status |= CBSTATUS_SAMPLE_LOCATIONS_SET;
4995 cb_state->static_status &= ~CBSTATUS_SAMPLE_LOCATIONS_SET;
4996}
4997
4998void ValidationStateTracker::PreCallRecordCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer,
4999 VkCoarseSampleOrderTypeNV sampleOrderType,
5000 uint32_t customSampleOrderCount,
5001 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005002 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunarg4189aa22020-10-21 00:23:48 -06005003 cb_state->status |= CBSTATUS_COARSE_SAMPLE_ORDER_SET;
5004 cb_state->static_status &= ~CBSTATUS_COARSE_SAMPLE_ORDER_SET;
5005}
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07005006
5007void ValidationStateTracker::PreCallRecordCmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, uint32_t patchControlPoints) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005008 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07005009 cb_state->status |= CBSTATUS_PATCH_CONTROL_POINTS_SET;
5010 cb_state->static_status &= ~CBSTATUS_PATCH_CONTROL_POINTS_SET;
5011}
5012
5013void ValidationStateTracker::PreCallRecordCmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005014 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07005015 cb_state->status |= CBSTATUS_LOGIC_OP_SET;
5016 cb_state->static_status &= ~CBSTATUS_LOGIC_OP_SET;
5017}
5018
5019void ValidationStateTracker::PreCallRecordCmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
5020 VkBool32 rasterizerDiscardEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005021 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07005022 cb_state->status |= CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET;
5023 cb_state->static_status &= ~CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET;
5024}
5025
5026void ValidationStateTracker::PreCallRecordCmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005027 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07005028 cb_state->status |= CBSTATUS_DEPTH_BIAS_ENABLE_SET;
5029 cb_state->static_status &= ~CBSTATUS_DEPTH_BIAS_ENABLE_SET;
5030}
5031
5032void ValidationStateTracker::PreCallRecordCmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,
5033 VkBool32 primitiveRestartEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005034 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07005035 cb_state->status |= CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET;
5036 cb_state->static_status &= ~CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07005037}
Piers Daniell924cd832021-05-18 13:48:47 -06005038
5039void ValidationStateTracker::PreCallRecordCmdSetVertexInputEXT(
5040 VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount,
5041 const VkVertexInputBindingDescription2EXT *pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount,
5042 const VkVertexInputAttributeDescription2EXT *pVertexAttributeDescriptions) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005043 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Piers Daniell924cd832021-05-18 13:48:47 -06005044 cb_state->status |= CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET | CBSTATUS_VERTEX_INPUT_SET;
5045 cb_state->static_status &= ~(CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET | CBSTATUS_VERTEX_INPUT_SET);
5046}
Nathaniel Cesario42ac6ca2021-06-15 17:23:05 -06005047
5048void ValidationStateTracker::RecordGetBufferDeviceAddress(const VkBufferDeviceAddressInfo *pInfo, VkDeviceAddress address) {
5049 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
5050 if (buffer_state) {
5051 // address is used for GPU-AV and ray tracing buffer validation
5052 buffer_state->deviceAddress = address;
5053 buffer_address_map_.emplace(address, buffer_state);
5054 }
5055}
5056
5057void ValidationStateTracker::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
5058 VkDeviceAddress address) {
5059 RecordGetBufferDeviceAddress(pInfo, address);
5060}
5061
5062void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
5063 VkDeviceAddress address) {
5064 RecordGetBufferDeviceAddress(pInfo, address);
5065}
5066
5067void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
5068 VkDeviceAddress address) {
5069 RecordGetBufferDeviceAddress(pInfo, address);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06005070}
5071
5072std::shared_ptr<SWAPCHAIN_NODE> ValidationStateTracker::CreateSwapchainState(const VkSwapchainCreateInfoKHR *create_info,
5073 VkSwapchainKHR swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06005074 return std::make_shared<SWAPCHAIN_NODE>(this, create_info, swapchain);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06005075}
Jeremy Gebben3d22d582021-08-11 15:37:58 -06005076
5077std::shared_ptr<CMD_BUFFER_STATE> ValidationStateTracker::CreateCmdBufferState(VkCommandBuffer cb,
5078 const VkCommandBufferAllocateInfo *create_info,
5079 std::shared_ptr<COMMAND_POOL_STATE> &pool) {
5080 return std::make_shared<CMD_BUFFER_STATE>(this, cb, create_info, pool);
5081}