blob: 783857c9a16fb5c24161fca407e545e057b93b8e [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
Jeremy Gebben11af9792021-08-20 10:20:09 -060042extern template PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *, const VkRayTracingPipelineCreateInfoKHR *,
43 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&);
44extern template PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *, const VkRayTracingPipelineCreateInfoNV *,
45 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&);
46
Mark Lobodzinskib4ab6ac2020-04-02 13:12:06 -060047void ValidationStateTracker::InitDeviceValidationObject(bool add_obj, ValidationObject *inst_obj, ValidationObject *dev_obj) {
48 if (add_obj) {
49 instance_state = reinterpret_cast<ValidationStateTracker *>(GetValidationObject(inst_obj->object_dispatch, container_type));
50 // Call base class
51 ValidationObject::InitDeviceValidationObject(add_obj, inst_obj, dev_obj);
52 }
53}
54
John Zulauf2bc1fde2020-04-24 15:09:51 -060055// NOTE: Beware the lifespan of the rp_begin when holding the return. If the rp_begin isn't a "safe" copy, "IMAGELESS"
56// attachments won't persist past the API entry point exit.
Jeremy Gebben88f58142021-06-01 10:07:52 -060057static std::pair<uint32_t, const VkImageView *> GetFramebufferAttachments(const VkRenderPassBeginInfo &rp_begin,
58 const FRAMEBUFFER_STATE &fb_state) {
John Zulauf2bc1fde2020-04-24 15:09:51 -060059 const VkImageView *attachments = fb_state.createInfo.pAttachments;
60 uint32_t count = fb_state.createInfo.attachmentCount;
61 if (fb_state.createInfo.flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -070062 const auto *framebuffer_attachments = LvlFindInChain<VkRenderPassAttachmentBeginInfo>(rp_begin.pNext);
John Zulauf2bc1fde2020-04-24 15:09:51 -060063 if (framebuffer_attachments) {
64 attachments = framebuffer_attachments->pAttachments;
65 count = framebuffer_attachments->attachmentCount;
66 }
67 }
68 return std::make_pair(count, attachments);
69}
70
John Zulauf64ffe552021-02-06 10:25:07 -070071template <typename ImageViewPointer, typename Get>
72std::vector<ImageViewPointer> GetAttachmentViewsImpl(const VkRenderPassBeginInfo &rp_begin, const FRAMEBUFFER_STATE &fb_state,
73 const Get &get_fn) {
74 std::vector<ImageViewPointer> views;
John Zulauf2bc1fde2020-04-24 15:09:51 -060075
76 const auto count_attachment = GetFramebufferAttachments(rp_begin, fb_state);
77 const auto attachment_count = count_attachment.first;
78 const auto *attachments = count_attachment.second;
79 views.resize(attachment_count, nullptr);
80 for (uint32_t i = 0; i < attachment_count; i++) {
81 if (attachments[i] != VK_NULL_HANDLE) {
John Zulauf64ffe552021-02-06 10:25:07 -070082 views[i] = get_fn(attachments[i]);
John Zulauf2bc1fde2020-04-24 15:09:51 -060083 }
84 }
85 return views;
86}
87
John Zulauf64ffe552021-02-06 10:25:07 -070088std::vector<std::shared_ptr<const IMAGE_VIEW_STATE>> ValidationStateTracker::GetSharedAttachmentViews(
89 const VkRenderPassBeginInfo &rp_begin, const FRAMEBUFFER_STATE &fb_state) const {
90 auto get_fn = [this](VkImageView handle) { return this->GetShared<IMAGE_VIEW_STATE>(handle); };
91 return GetAttachmentViewsImpl<std::shared_ptr<const IMAGE_VIEW_STATE>>(rp_begin, fb_state, get_fn);
92}
93
locke-lunargd556cc32019-09-17 01:21:23 -060094#ifdef VK_USE_PLATFORM_ANDROID_KHR
95// Android-specific validation that uses types defined only with VK_USE_PLATFORM_ANDROID_KHR
96// This could also move into a seperate core_validation_android.cpp file... ?
97
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -060098template <typename CreateInfo>
99VkFormatFeatureFlags ValidationStateTracker::GetExternalFormatFeaturesANDROID(const CreateInfo *create_info) const {
100 VkFormatFeatureFlags format_features = 0;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700101 const VkExternalFormatANDROID *ext_fmt_android = LvlFindInChain<VkExternalFormatANDROID>(create_info->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600102 if (ext_fmt_android && (0 != ext_fmt_android->externalFormat)) {
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700103 // VUID 01894 will catch if not found in map
104 auto it = ahb_ext_formats_map.find(ext_fmt_android->externalFormat);
105 if (it != ahb_ext_formats_map.end()) {
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600106 format_features = it->second;
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700107 }
locke-lunargd556cc32019-09-17 01:21:23 -0600108 }
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600109 return format_features;
locke-lunargd556cc32019-09-17 01:21:23 -0600110}
111
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700112void ValidationStateTracker::PostCallRecordGetAndroidHardwareBufferPropertiesANDROID(
113 VkDevice device, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties, VkResult result) {
114 if (VK_SUCCESS != result) return;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700115 auto ahb_format_props = LvlFindInChain<VkAndroidHardwareBufferFormatPropertiesANDROID>(pProperties->pNext);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700116 if (ahb_format_props) {
Jeremy Gebbenfc6f8152021-03-18 16:58:55 -0600117 ahb_ext_formats_map.emplace(ahb_format_props->externalFormat, ahb_format_props->formatFeatures);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700118 }
119}
120
locke-lunargd556cc32019-09-17 01:21:23 -0600121#else
122
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600123template <typename CreateInfo>
124VkFormatFeatureFlags ValidationStateTracker::GetExternalFormatFeaturesANDROID(const CreateInfo *create_info) const {
125 return 0;
126}
locke-lunargd556cc32019-09-17 01:21:23 -0600127
128#endif // VK_USE_PLATFORM_ANDROID_KHR
129
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600130VkFormatFeatureFlags GetImageFormatFeatures(VkPhysicalDevice physical_device, VkDevice device, VkImage image, VkFormat format,
131 VkImageTiling tiling) {
132 VkFormatFeatureFlags format_features = 0;
Petr Kraus44f1c482020-04-25 20:09:25 +0200133 // Add feature support according to Image Format Features (vkspec.html#resources-image-format-features)
134 // if format is AHB external format then the features are already set
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600135 if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
136 VkImageDrmFormatModifierPropertiesEXT drm_format_properties = {VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
137 nullptr};
138 DispatchGetImageDrmFormatModifierPropertiesEXT(device, image, &drm_format_properties);
Petr Kraus44f1c482020-04-25 20:09:25 +0200139
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600140 VkFormatProperties2 format_properties_2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, nullptr};
141 VkDrmFormatModifierPropertiesListEXT drm_properties_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
142 nullptr};
143 format_properties_2.pNext = (void *)&drm_properties_list;
144 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
145 std::vector<VkDrmFormatModifierPropertiesEXT> drm_properties;
146 drm_properties.resize(drm_properties_list.drmFormatModifierCount);
147 drm_properties_list.pDrmFormatModifierProperties = &drm_properties[0];
148 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
Petr Kraus44f1c482020-04-25 20:09:25 +0200149
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600150 for (uint32_t i = 0; i < drm_properties_list.drmFormatModifierCount; i++) {
151 if (drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifier == drm_format_properties.drmFormatModifier) {
152 format_features = drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
153 break;
Petr Kraus44f1c482020-04-25 20:09:25 +0200154 }
Petr Kraus44f1c482020-04-25 20:09:25 +0200155 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600156 } else {
157 VkFormatProperties format_properties;
158 DispatchGetPhysicalDeviceFormatProperties(physical_device, format, &format_properties);
159 format_features =
160 (tiling == VK_IMAGE_TILING_LINEAR) ? format_properties.linearTilingFeatures : format_properties.optimalTilingFeatures;
Petr Kraus44f1c482020-04-25 20:09:25 +0200161 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600162 return format_features;
Petr Kraus44f1c482020-04-25 20:09:25 +0200163}
164
locke-lunargd556cc32019-09-17 01:21:23 -0600165void ValidationStateTracker::PostCallRecordCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
166 const VkAllocationCallbacks *pAllocator, VkImage *pImage, VkResult result) {
167 if (VK_SUCCESS != result) return;
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600168 VkFormatFeatureFlags format_features = 0;
locke-lunargd556cc32019-09-17 01:21:23 -0600169 if (device_extensions.vk_android_external_memory_android_hardware_buffer) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600170 format_features = GetExternalFormatFeaturesANDROID(pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -0600171 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600172 if (format_features == 0) {
173 format_features = GetImageFormatFeatures(physical_device, device, *pImage, pCreateInfo->format, pCreateInfo->tiling);
locke-lunargd556cc32019-09-17 01:21:23 -0600174 }
175
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600176 auto is_node = std::make_shared<IMAGE_STATE>(device, *pImage, pCreateInfo, format_features);
locke-lunargd556cc32019-09-17 01:21:23 -0600177 // Record the memory requirements in case they won't be queried
sfricke-samsung013f1ef2020-05-14 22:56:20 -0700178 // External AHB memory can't be queried until after memory is bound
Jeremy Gebben6fbf8242021-06-21 09:14:46 -0600179 if (is_node->IsExternalAHB() == false) {
sfricke-samsung71bc6572020-04-29 15:49:43 -0700180 if (is_node->disjoint == false) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -0600181 DispatchGetImageMemoryRequirements(device, *pImage, &is_node->requirements[0]);
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700182 } else {
183 uint32_t plane_count = FormatPlaneCount(pCreateInfo->format);
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600184 static const std::array<VkImageAspectFlagBits, 3> aspects{VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT,
185 VK_IMAGE_ASPECT_PLANE_2_BIT};
186 assert(plane_count <= aspects.size());
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700187 VkImagePlaneMemoryRequirementsInfo image_plane_req = {VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, nullptr};
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600188 VkImageMemoryRequirementsInfo2 mem_req_info2 = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, &image_plane_req,
189 *pImage};
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700190
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600191 for (uint32_t i = 0; i < plane_count; i++) {
192 VkMemoryRequirements2 mem_reqs2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, nullptr};
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700193
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600194 image_plane_req.planeAspect = aspects[i];
Jeremy Gebbenb9b07b62021-08-16 11:38:47 -0600195 switch (device_extensions.vk_khr_get_memory_requirements2) {
196 case kEnabledByApiLevel:
197 DispatchGetImageMemoryRequirements2(device, &mem_req_info2, &mem_reqs2);
198 break;
199 case kEnabledByCreateinfo:
200 DispatchGetImageMemoryRequirements2KHR(device, &mem_req_info2, &mem_reqs2);
201 break;
202 default:
203 // The VK_KHR_sampler_ycbcr_conversion extension requires VK_KHR_get_memory_requirements2,
204 // so validation of this vkCreateImage call should have already failed.
205 assert(false);
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600206 }
207 is_node->requirements[i] = mem_reqs2.memoryRequirements;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700208 }
209 }
locke-lunargd556cc32019-09-17 01:21:23 -0600210 }
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700211
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600212 imageMap[*pImage] = std::move(is_node);
locke-lunargd556cc32019-09-17 01:21:23 -0600213}
214
215void ValidationStateTracker::PreCallRecordDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
216 if (!image) return;
217 IMAGE_STATE *image_state = GetImageState(image);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600218 if (!image_state) return;
219
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600220 image_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600221 imageMap.erase(image);
222}
223
224void ValidationStateTracker::PreCallRecordCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
225 VkImageLayout imageLayout, const VkClearColorValue *pColor,
226 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600227
228 if (disabled[command_buffer_state]) return;
229
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600230 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600231 if (cb_node) {
232 cb_node->RecordTransferCmd(CMD_CLEARCOLORIMAGE, GetImageState(image));
locke-lunargd556cc32019-09-17 01:21:23 -0600233 }
234}
235
236void ValidationStateTracker::PreCallRecordCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
237 VkImageLayout imageLayout,
238 const VkClearDepthStencilValue *pDepthStencil,
239 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600240 if (disabled[command_buffer_state]) return;
241
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600242 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600243 if (cb_node) {
244 cb_node->RecordTransferCmd(CMD_CLEARDEPTHSTENCILIMAGE, GetImageState(image));
locke-lunargd556cc32019-09-17 01:21:23 -0600245 }
246}
247
248void ValidationStateTracker::PreCallRecordCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
249 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
250 uint32_t regionCount, const VkImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600251 if (disabled[command_buffer_state]) return;
252
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600253 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600254 cb_node->RecordTransferCmd(CMD_COPYIMAGE, GetImageState(srcImage), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600255}
256
Jeff Leger178b1e52020-10-05 12:22:23 -0400257void ValidationStateTracker::PreCallRecordCmdCopyImage2KHR(VkCommandBuffer commandBuffer,
258 const VkCopyImageInfo2KHR *pCopyImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600259 if (disabled[command_buffer_state]) return;
260
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600261 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600262 cb_node->RecordTransferCmd(CMD_COPYIMAGE2KHR, GetImageState(pCopyImageInfo->srcImage), GetImageState(pCopyImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400263}
264
locke-lunargd556cc32019-09-17 01:21:23 -0600265void ValidationStateTracker::PreCallRecordCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
266 VkImageLayout srcImageLayout, VkImage dstImage,
267 VkImageLayout dstImageLayout, uint32_t regionCount,
268 const VkImageResolve *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600269 if (disabled[command_buffer_state]) return;
270
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600271 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600272 cb_node->RecordTransferCmd(CMD_RESOLVEIMAGE, GetImageState(srcImage), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600273}
274
Jeff Leger178b1e52020-10-05 12:22:23 -0400275void ValidationStateTracker::PreCallRecordCmdResolveImage2KHR(VkCommandBuffer commandBuffer,
276 const VkResolveImageInfo2KHR *pResolveImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600277 if (disabled[command_buffer_state]) return;
278
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600279 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600280 cb_node->RecordTransferCmd(CMD_RESOLVEIMAGE2KHR, GetImageState(pResolveImageInfo->srcImage),
281 GetImageState(pResolveImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400282}
283
locke-lunargd556cc32019-09-17 01:21:23 -0600284void ValidationStateTracker::PreCallRecordCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
285 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
286 uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600287 if (disabled[command_buffer_state]) return;
288
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600289 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600290 cb_node->RecordTransferCmd(CMD_BLITIMAGE, GetImageState(srcImage), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600291}
292
Jeff Leger178b1e52020-10-05 12:22:23 -0400293void ValidationStateTracker::PreCallRecordCmdBlitImage2KHR(VkCommandBuffer commandBuffer,
294 const VkBlitImageInfo2KHR *pBlitImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600295 if (disabled[command_buffer_state]) return;
296
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600297 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600298 cb_node->RecordTransferCmd(CMD_BLITIMAGE2KHR, GetImageState(pBlitImageInfo->srcImage), GetImageState(pBlitImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400299}
300
locke-lunargd556cc32019-09-17 01:21:23 -0600301void ValidationStateTracker::PostCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
302 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer,
303 VkResult result) {
304 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600305
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500306 auto buffer_state = std::make_shared<BUFFER_STATE>(*pBuffer, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -0600307
James Rumble2f6e7bb2021-07-13 15:21:20 +0100308 if (pCreateInfo) {
309 const auto *opaque_capture_address = LvlFindInChain<VkBufferOpaqueCaptureAddressCreateInfo>(pCreateInfo->pNext);
310 if (opaque_capture_address) {
311 // address is used for GPU-AV and ray tracing buffer validation
312 buffer_state->deviceAddress = opaque_capture_address->opaqueCaptureAddress;
313 buffer_address_map_.emplace(opaque_capture_address->opaqueCaptureAddress, buffer_state.get());
314 }
315 }
316
locke-lunargd556cc32019-09-17 01:21:23 -0600317 // Get a set of requirements in the case the app does not
sfricke-samsungad90e722020-07-08 20:54:24 -0700318 DispatchGetBufferMemoryRequirements(device, *pBuffer, &buffer_state->requirements);
locke-lunargd556cc32019-09-17 01:21:23 -0600319
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700320 bufferMap.emplace(*pBuffer, std::move(buffer_state));
locke-lunargd556cc32019-09-17 01:21:23 -0600321}
322
323void ValidationStateTracker::PostCallRecordCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
324 const VkAllocationCallbacks *pAllocator, VkBufferView *pView,
325 VkResult result) {
326 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600327
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500328 auto buffer_state = GetBufferShared(pCreateInfo->buffer);
locke-lunarg25b6c352020-08-06 17:44:18 -0600329
330 VkFormatProperties format_properties;
331 DispatchGetPhysicalDeviceFormatProperties(physical_device, pCreateInfo->format, &format_properties);
locke-lunarg25b6c352020-08-06 17:44:18 -0600332
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600333 bufferViewMap[*pView] =
334 std::make_shared<BUFFER_VIEW_STATE>(buffer_state, *pView, pCreateInfo, format_properties.bufferFeatures);
locke-lunargd556cc32019-09-17 01:21:23 -0600335}
336
337void ValidationStateTracker::PostCallRecordCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
338 const VkAllocationCallbacks *pAllocator, VkImageView *pView,
339 VkResult result) {
340 if (result != VK_SUCCESS) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500341 auto image_state = GetImageShared(pCreateInfo->image);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700342
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600343 VkFormatFeatureFlags format_features = 0;
344 if (image_state->HasAHBFormat() == true) {
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700345 // The ImageView uses same Image's format feature since they share same AHB
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600346 format_features = image_state->format_features;
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700347 } else {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600348 format_features = GetImageFormatFeatures(physical_device, device, image_state->image(), pCreateInfo->format,
349 image_state->createInfo.tiling);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700350 }
351
locke-lunarg9939d4b2020-10-26 20:11:08 -0600352 // 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 -0600353 auto filter_cubic_props = LvlInitStruct<VkFilterCubicImageViewImageFormatPropertiesEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600354 if (IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700355 auto imageview_format_info = LvlInitStruct<VkPhysicalDeviceImageViewImageFormatInfoEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600356 imageview_format_info.imageViewType = pCreateInfo->viewType;
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700357 auto image_format_info = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>(&imageview_format_info);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600358 image_format_info.type = image_state->createInfo.imageType;
359 image_format_info.format = image_state->createInfo.format;
360 image_format_info.tiling = image_state->createInfo.tiling;
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600361 auto usage_create_info = LvlFindInChain<VkImageViewUsageCreateInfo>(pCreateInfo->pNext);
362 image_format_info.usage = usage_create_info ? usage_create_info->usage : image_state->createInfo.usage;
locke-lunarg9939d4b2020-10-26 20:11:08 -0600363 image_format_info.flags = image_state->createInfo.flags;
364
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600365 auto image_format_properties = LvlInitStruct<VkImageFormatProperties2>(&filter_cubic_props);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600366
367 DispatchGetPhysicalDeviceImageFormatProperties2(physical_device, &image_format_info, &image_format_properties);
368 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600369
370 imageViewMap[*pView] =
371 std::make_shared<IMAGE_VIEW_STATE>(image_state, *pView, pCreateInfo, format_features, filter_cubic_props);
locke-lunargd556cc32019-09-17 01:21:23 -0600372}
373
374void ValidationStateTracker::PreCallRecordCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
375 uint32_t regionCount, const VkBufferCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600376 if (disabled[command_buffer_state]) return;
377
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600378 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600379 cb_node->RecordTransferCmd(CMD_COPYBUFFER, GetBufferState(srcBuffer), GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -0600380}
381
Jeff Leger178b1e52020-10-05 12:22:23 -0400382void ValidationStateTracker::PreCallRecordCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600383 const VkCopyBufferInfo2KHR *pCopyBufferInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600384 if (disabled[command_buffer_state]) return;
385
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600386 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600387 cb_node->RecordTransferCmd(CMD_COPYBUFFER2KHR, GetBufferState(pCopyBufferInfo->srcBuffer),
388 GetBufferState(pCopyBufferInfo->dstBuffer));
Jeff Leger178b1e52020-10-05 12:22:23 -0400389}
390
locke-lunargd556cc32019-09-17 01:21:23 -0600391void ValidationStateTracker::PreCallRecordDestroyImageView(VkDevice device, VkImageView imageView,
392 const VkAllocationCallbacks *pAllocator) {
393 IMAGE_VIEW_STATE *image_view_state = GetImageViewState(imageView);
394 if (!image_view_state) return;
locke-lunargd556cc32019-09-17 01:21:23 -0600395
396 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600397 image_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600398 imageViewMap.erase(imageView);
399}
400
401void ValidationStateTracker::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
402 if (!buffer) return;
403 auto buffer_state = GetBufferState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600404
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600405 buffer_state->Destroy();
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600406 bufferMap.erase(buffer_state->buffer());
locke-lunargd556cc32019-09-17 01:21:23 -0600407}
408
409void ValidationStateTracker::PreCallRecordDestroyBufferView(VkDevice device, VkBufferView bufferView,
410 const VkAllocationCallbacks *pAllocator) {
411 if (!bufferView) return;
412 auto buffer_view_state = GetBufferViewState(bufferView);
locke-lunargd556cc32019-09-17 01:21:23 -0600413
414 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600415 buffer_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600416 bufferViewMap.erase(bufferView);
417}
418
419void ValidationStateTracker::PreCallRecordCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
420 VkDeviceSize size, uint32_t data) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600421 if (disabled[command_buffer_state]) return;
422
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600423 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600424 cb_node->RecordTransferCmd(CMD_FILLBUFFER, GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -0600425}
426
427void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
428 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
429 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600430 if (disabled[command_buffer_state]) return;
431
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600432 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600433
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600434 cb_node->RecordTransferCmd(CMD_COPYIMAGETOBUFFER, GetImageState(srcImage), GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -0600435}
436
Jeff Leger178b1e52020-10-05 12:22:23 -0400437void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
438 const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600439 if (disabled[command_buffer_state]) return;
440
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600441 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600442 cb_node->RecordTransferCmd(CMD_COPYIMAGETOBUFFER2KHR, GetImageState(pCopyImageToBufferInfo->srcImage),
443 GetBufferState(pCopyImageToBufferInfo->dstBuffer));
Jeff Leger178b1e52020-10-05 12:22:23 -0400444}
445
locke-lunargd556cc32019-09-17 01:21:23 -0600446void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
447 VkImageLayout dstImageLayout, uint32_t regionCount,
448 const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600449 if (disabled[command_buffer_state]) return;
450
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600451 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600452 cb_node->RecordTransferCmd(CMD_COPYBUFFERTOIMAGE, GetBufferState(srcBuffer), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600453}
454
Jeff Leger178b1e52020-10-05 12:22:23 -0400455void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
456 const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600457
458 if (disabled[command_buffer_state]) return;
459
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600460 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600461 cb_node->RecordTransferCmd(CMD_COPYBUFFERTOIMAGE2KHR, GetBufferState(pCopyBufferToImageInfo->srcBuffer),
462 GetImageState(pCopyBufferToImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400463}
464
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600465QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) {
466 auto it = queueMap.find(queue);
467 if (it == queueMap.end()) {
468 return nullptr;
469 }
470 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600471}
472
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600473const QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) const {
474 auto it = queueMap.find(queue);
475 if (it == queueMap.cend()) {
476 return nullptr;
477 }
478 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600479}
480
locke-lunargd556cc32019-09-17 01:21:23 -0600481const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) const {
482 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
483 auto it = phys_dev_map->find(phys);
484 if (it == phys_dev_map->end()) {
485 return nullptr;
486 }
487 return &it->second;
488}
489
490PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) {
491 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
492 auto it = phys_dev_map->find(phys);
493 if (it == phys_dev_map->end()) {
494 return nullptr;
495 }
496 return &it->second;
497}
498
499PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() { return physical_device_state; }
500const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() const { return physical_device_state; }
501
502// Return ptr to memory binding for given handle of specified type
503template <typename State, typename Result>
504static Result GetObjectMemBindingImpl(State state, const VulkanTypedHandle &typed_handle) {
505 switch (typed_handle.type) {
506 case kVulkanObjectTypeImage:
507 return state->GetImageState(typed_handle.Cast<VkImage>());
508 case kVulkanObjectTypeBuffer:
509 return state->GetBufferState(typed_handle.Cast<VkBuffer>());
510 case kVulkanObjectTypeAccelerationStructureNV:
sourav parmarcd5fb182020-07-17 12:58:44 -0700511 return state->GetAccelerationStructureStateNV(typed_handle.Cast<VkAccelerationStructureNV>());
locke-lunargd556cc32019-09-17 01:21:23 -0600512 default:
513 break;
514 }
515 return nullptr;
516}
517
518const BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) const {
519 return GetObjectMemBindingImpl<const ValidationStateTracker *, const BINDABLE *>(this, typed_handle);
520}
521
522BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) {
523 return GetObjectMemBindingImpl<ValidationStateTracker *, BINDABLE *>(this, typed_handle);
524}
525
locke-lunargd556cc32019-09-17 01:21:23 -0600526// Remove set from setMap and delete the set
527void ValidationStateTracker::FreeDescriptorSet(cvdescriptorset::DescriptorSet *descriptor_set) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500528 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600529 descriptor_set->Destroy();
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500530
locke-lunargd556cc32019-09-17 01:21:23 -0600531 setMap.erase(descriptor_set->GetSet());
532}
533
534// Free all DS Pools including their Sets & related sub-structs
535// NOTE : Calls to this function should be wrapped in mutex
536void ValidationStateTracker::DeleteDescriptorSetPools() {
537 for (auto ii = descriptorPoolMap.begin(); ii != descriptorPoolMap.end();) {
538 // Remove this pools' sets from setMap and delete them
John Zulauf79f06582021-02-27 18:38:39 -0700539 for (auto *ds : ii->second->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -0600540 FreeDescriptorSet(ds);
541 }
542 ii->second->sets.clear();
543 ii = descriptorPoolMap.erase(ii);
544 }
545}
546
547// For given object struct return a ptr of BASE_NODE type for its wrapping struct
548BASE_NODE *ValidationStateTracker::GetStateStructPtrFromObject(const VulkanTypedHandle &object_struct) {
Jeff Bolzadbfa852019-10-04 13:53:30 -0500549 if (object_struct.node) {
550#ifdef _DEBUG
551 // assert that lookup would find the same object
552 VulkanTypedHandle other = object_struct;
553 other.node = nullptr;
554 assert(object_struct.node == GetStateStructPtrFromObject(other));
555#endif
556 return object_struct.node;
557 }
locke-lunargd556cc32019-09-17 01:21:23 -0600558 BASE_NODE *base_ptr = nullptr;
559 switch (object_struct.type) {
560 case kVulkanObjectTypeDescriptorSet: {
561 base_ptr = GetSetNode(object_struct.Cast<VkDescriptorSet>());
562 break;
563 }
564 case kVulkanObjectTypeSampler: {
565 base_ptr = GetSamplerState(object_struct.Cast<VkSampler>());
566 break;
567 }
568 case kVulkanObjectTypeQueryPool: {
569 base_ptr = GetQueryPoolState(object_struct.Cast<VkQueryPool>());
570 break;
571 }
572 case kVulkanObjectTypePipeline: {
573 base_ptr = GetPipelineState(object_struct.Cast<VkPipeline>());
574 break;
575 }
576 case kVulkanObjectTypeBuffer: {
577 base_ptr = GetBufferState(object_struct.Cast<VkBuffer>());
578 break;
579 }
580 case kVulkanObjectTypeBufferView: {
581 base_ptr = GetBufferViewState(object_struct.Cast<VkBufferView>());
582 break;
583 }
584 case kVulkanObjectTypeImage: {
585 base_ptr = GetImageState(object_struct.Cast<VkImage>());
586 break;
587 }
588 case kVulkanObjectTypeImageView: {
589 base_ptr = GetImageViewState(object_struct.Cast<VkImageView>());
590 break;
591 }
592 case kVulkanObjectTypeEvent: {
593 base_ptr = GetEventState(object_struct.Cast<VkEvent>());
594 break;
595 }
596 case kVulkanObjectTypeDescriptorPool: {
597 base_ptr = GetDescriptorPoolState(object_struct.Cast<VkDescriptorPool>());
598 break;
599 }
600 case kVulkanObjectTypeCommandPool: {
601 base_ptr = GetCommandPoolState(object_struct.Cast<VkCommandPool>());
602 break;
603 }
604 case kVulkanObjectTypeFramebuffer: {
605 base_ptr = GetFramebufferState(object_struct.Cast<VkFramebuffer>());
606 break;
607 }
608 case kVulkanObjectTypeRenderPass: {
609 base_ptr = GetRenderPassState(object_struct.Cast<VkRenderPass>());
610 break;
611 }
612 case kVulkanObjectTypeDeviceMemory: {
613 base_ptr = GetDevMemState(object_struct.Cast<VkDeviceMemory>());
614 break;
615 }
616 case kVulkanObjectTypeAccelerationStructureNV: {
sourav parmarcd5fb182020-07-17 12:58:44 -0700617 base_ptr = GetAccelerationStructureStateNV(object_struct.Cast<VkAccelerationStructureNV>());
618 break;
619 }
620 case kVulkanObjectTypeAccelerationStructureKHR: {
621 base_ptr = GetAccelerationStructureStateKHR(object_struct.Cast<VkAccelerationStructureKHR>());
locke-lunargd556cc32019-09-17 01:21:23 -0600622 break;
623 }
Jeff Bolzadbfa852019-10-04 13:53:30 -0500624 case kVulkanObjectTypeUnknown:
625 // This can happen if an element of the object_bindings vector has been
626 // zeroed out, after an object is destroyed.
627 break;
locke-lunargd556cc32019-09-17 01:21:23 -0600628 default:
629 // TODO : Any other objects to be handled here?
630 assert(0);
631 break;
632 }
633 return base_ptr;
634}
635
sfricke-samsungbf1a2ed2020-06-14 23:31:00 -0700636// Gets union of all features defined by Potential Format Features
637// 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 -0700638VkFormatFeatureFlags ValidationStateTracker::GetPotentialFormatFeatures(VkFormat format) const {
639 VkFormatFeatureFlags format_features = 0;
640
641 if (format != VK_FORMAT_UNDEFINED) {
642 VkFormatProperties format_properties;
643 DispatchGetPhysicalDeviceFormatProperties(physical_device, format, &format_properties);
644 format_features |= format_properties.linearTilingFeatures;
645 format_features |= format_properties.optimalTilingFeatures;
646 if (device_extensions.vk_ext_image_drm_format_modifier) {
647 // VK_KHR_get_physical_device_properties2 is required in this case
648 VkFormatProperties2 format_properties_2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
649 VkDrmFormatModifierPropertiesListEXT drm_properties_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
650 nullptr};
651 format_properties_2.pNext = (void *)&drm_properties_list;
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100652
653 // First call is to get the number of modifiers compatible with the queried format
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700654 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100655
656 std::vector<VkDrmFormatModifierPropertiesEXT> drm_properties;
657 drm_properties.resize(drm_properties_list.drmFormatModifierCount);
658 drm_properties_list.pDrmFormatModifierProperties = drm_properties.data();
659
660 // Second call, now with an allocated array in pDrmFormatModifierProperties, is to get the modifiers
661 // compatible with the queried format
662 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
663
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700664 for (uint32_t i = 0; i < drm_properties_list.drmFormatModifierCount; i++) {
665 format_features |= drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
666 }
667 }
668 }
669
670 return format_features;
671}
672
locke-lunargd556cc32019-09-17 01:21:23 -0600673void ValidationStateTracker::PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
674 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
675 VkResult result) {
676 if (VK_SUCCESS != result) return;
677
Locke Linf3873542021-04-26 11:25:10 -0600678 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
679 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
680 ValidationStateTracker *state_tracker = static_cast<ValidationStateTracker *>(validation_data);
681
locke-lunargd556cc32019-09-17 01:21:23 -0600682 const VkPhysicalDeviceFeatures *enabled_features_found = pCreateInfo->pEnabledFeatures;
683 if (nullptr == enabled_features_found) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700684 const auto *features2 = LvlFindInChain<VkPhysicalDeviceFeatures2>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600685 if (features2) {
686 enabled_features_found = &(features2->features);
Locke Linf3873542021-04-26 11:25:10 -0600687
688 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(features2->pNext);
689 if (provoking_vertex_features) {
690 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
691 }
locke-lunargd556cc32019-09-17 01:21:23 -0600692 }
693 }
694
locke-lunargd556cc32019-09-17 01:21:23 -0600695 if (nullptr == enabled_features_found) {
696 state_tracker->enabled_features.core = {};
697 } else {
698 state_tracker->enabled_features.core = *enabled_features_found;
699 }
700
701 // Make sure that queue_family_properties are obtained for this device's physical_device, even if the app has not
702 // previously set them through an explicit API call.
703 uint32_t count;
704 auto pd_state = GetPhysicalDeviceState(gpu);
705 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
706 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
707 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, &pd_state->queue_family_properties[0]);
708 // Save local link to this device's physical device state
709 state_tracker->physical_device_state = pd_state;
710
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700711 const auto *vulkan_12_features = LvlFindInChain<VkPhysicalDeviceVulkan12Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700712 if (vulkan_12_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700713 state_tracker->enabled_features.core12 = *vulkan_12_features;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700714 } else {
sfricke-samsung27c70722020-05-02 08:42:39 -0700715 // Set Extension Feature Aliases to false as there is no struct to check
716 state_tracker->enabled_features.core12.drawIndirectCount = VK_FALSE;
717 state_tracker->enabled_features.core12.samplerMirrorClampToEdge = VK_FALSE;
718 state_tracker->enabled_features.core12.descriptorIndexing = VK_FALSE;
719 state_tracker->enabled_features.core12.samplerFilterMinmax = VK_FALSE;
720 state_tracker->enabled_features.core12.shaderOutputLayer = VK_FALSE;
721 state_tracker->enabled_features.core12.shaderOutputViewportIndex = VK_FALSE;
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800722 state_tracker->enabled_features.core12.subgroupBroadcastDynamicId = VK_FALSE;
sfricke-samsung27c70722020-05-02 08:42:39 -0700723
724 // These structs are only allowed in pNext chain if there is no VkPhysicalDeviceVulkan12Features
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700725
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700726 const auto *eight_bit_storage_features = LvlFindInChain<VkPhysicalDevice8BitStorageFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700727 if (eight_bit_storage_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700728 state_tracker->enabled_features.core12.storageBuffer8BitAccess = eight_bit_storage_features->storageBuffer8BitAccess;
729 state_tracker->enabled_features.core12.uniformAndStorageBuffer8BitAccess =
730 eight_bit_storage_features->uniformAndStorageBuffer8BitAccess;
731 state_tracker->enabled_features.core12.storagePushConstant8 = eight_bit_storage_features->storagePushConstant8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700732 }
733
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700734 const auto *float16_int8_features = LvlFindInChain<VkPhysicalDeviceShaderFloat16Int8Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700735 if (float16_int8_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700736 state_tracker->enabled_features.core12.shaderFloat16 = float16_int8_features->shaderFloat16;
737 state_tracker->enabled_features.core12.shaderInt8 = float16_int8_features->shaderInt8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700738 }
739
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700740 const auto *descriptor_indexing_features = LvlFindInChain<VkPhysicalDeviceDescriptorIndexingFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700741 if (descriptor_indexing_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700742 state_tracker->enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing =
743 descriptor_indexing_features->shaderInputAttachmentArrayDynamicIndexing;
744 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing =
745 descriptor_indexing_features->shaderUniformTexelBufferArrayDynamicIndexing;
746 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing =
747 descriptor_indexing_features->shaderStorageTexelBufferArrayDynamicIndexing;
748 state_tracker->enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing =
749 descriptor_indexing_features->shaderUniformBufferArrayNonUniformIndexing;
750 state_tracker->enabled_features.core12.shaderSampledImageArrayNonUniformIndexing =
751 descriptor_indexing_features->shaderSampledImageArrayNonUniformIndexing;
752 state_tracker->enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing =
753 descriptor_indexing_features->shaderStorageBufferArrayNonUniformIndexing;
754 state_tracker->enabled_features.core12.shaderStorageImageArrayNonUniformIndexing =
755 descriptor_indexing_features->shaderStorageImageArrayNonUniformIndexing;
756 state_tracker->enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing =
757 descriptor_indexing_features->shaderInputAttachmentArrayNonUniformIndexing;
758 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing =
759 descriptor_indexing_features->shaderUniformTexelBufferArrayNonUniformIndexing;
760 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing =
761 descriptor_indexing_features->shaderStorageTexelBufferArrayNonUniformIndexing;
762 state_tracker->enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind =
763 descriptor_indexing_features->descriptorBindingUniformBufferUpdateAfterBind;
764 state_tracker->enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind =
765 descriptor_indexing_features->descriptorBindingSampledImageUpdateAfterBind;
766 state_tracker->enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind =
767 descriptor_indexing_features->descriptorBindingStorageImageUpdateAfterBind;
768 state_tracker->enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind =
769 descriptor_indexing_features->descriptorBindingStorageBufferUpdateAfterBind;
770 state_tracker->enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind =
771 descriptor_indexing_features->descriptorBindingUniformTexelBufferUpdateAfterBind;
772 state_tracker->enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind =
773 descriptor_indexing_features->descriptorBindingStorageTexelBufferUpdateAfterBind;
774 state_tracker->enabled_features.core12.descriptorBindingUpdateUnusedWhilePending =
775 descriptor_indexing_features->descriptorBindingUpdateUnusedWhilePending;
776 state_tracker->enabled_features.core12.descriptorBindingPartiallyBound =
777 descriptor_indexing_features->descriptorBindingPartiallyBound;
778 state_tracker->enabled_features.core12.descriptorBindingVariableDescriptorCount =
779 descriptor_indexing_features->descriptorBindingVariableDescriptorCount;
780 state_tracker->enabled_features.core12.runtimeDescriptorArray = descriptor_indexing_features->runtimeDescriptorArray;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700781 }
782
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700783 const auto *scalar_block_layout_features = LvlFindInChain<VkPhysicalDeviceScalarBlockLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700784 if (scalar_block_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700785 state_tracker->enabled_features.core12.scalarBlockLayout = scalar_block_layout_features->scalarBlockLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700786 }
787
788 const auto *imageless_framebuffer_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700789 LvlFindInChain<VkPhysicalDeviceImagelessFramebufferFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700790 if (imageless_framebuffer_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700791 state_tracker->enabled_features.core12.imagelessFramebuffer = imageless_framebuffer_features->imagelessFramebuffer;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700792 }
793
794 const auto *uniform_buffer_standard_layout_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700795 LvlFindInChain<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700796 if (uniform_buffer_standard_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700797 state_tracker->enabled_features.core12.uniformBufferStandardLayout =
798 uniform_buffer_standard_layout_features->uniformBufferStandardLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700799 }
800
801 const auto *subgroup_extended_types_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700802 LvlFindInChain<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700803 if (subgroup_extended_types_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700804 state_tracker->enabled_features.core12.shaderSubgroupExtendedTypes =
805 subgroup_extended_types_features->shaderSubgroupExtendedTypes;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700806 }
807
808 const auto *separate_depth_stencil_layouts_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700809 LvlFindInChain<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700810 if (separate_depth_stencil_layouts_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700811 state_tracker->enabled_features.core12.separateDepthStencilLayouts =
812 separate_depth_stencil_layouts_features->separateDepthStencilLayouts;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700813 }
814
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700815 const auto *host_query_reset_features = LvlFindInChain<VkPhysicalDeviceHostQueryResetFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700816 if (host_query_reset_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700817 state_tracker->enabled_features.core12.hostQueryReset = host_query_reset_features->hostQueryReset;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700818 }
819
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700820 const auto *timeline_semaphore_features = LvlFindInChain<VkPhysicalDeviceTimelineSemaphoreFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700821 if (timeline_semaphore_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700822 state_tracker->enabled_features.core12.timelineSemaphore = timeline_semaphore_features->timelineSemaphore;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700823 }
824
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700825 const auto *buffer_device_address = LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700826 if (buffer_device_address) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700827 state_tracker->enabled_features.core12.bufferDeviceAddress = buffer_device_address->bufferDeviceAddress;
828 state_tracker->enabled_features.core12.bufferDeviceAddressCaptureReplay =
829 buffer_device_address->bufferDeviceAddressCaptureReplay;
830 state_tracker->enabled_features.core12.bufferDeviceAddressMultiDevice =
831 buffer_device_address->bufferDeviceAddressMultiDevice;
832 }
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800833
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700834 const auto *atomic_int64_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicInt64Features>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800835 if (atomic_int64_features) {
836 state_tracker->enabled_features.core12.shaderBufferInt64Atomics = atomic_int64_features->shaderBufferInt64Atomics;
837 state_tracker->enabled_features.core12.shaderSharedInt64Atomics = atomic_int64_features->shaderSharedInt64Atomics;
838 }
839
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700840 const auto *memory_model_features = LvlFindInChain<VkPhysicalDeviceVulkanMemoryModelFeatures>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800841 if (memory_model_features) {
842 state_tracker->enabled_features.core12.vulkanMemoryModel = memory_model_features->vulkanMemoryModel;
843 state_tracker->enabled_features.core12.vulkanMemoryModelDeviceScope =
844 memory_model_features->vulkanMemoryModelDeviceScope;
845 state_tracker->enabled_features.core12.vulkanMemoryModelAvailabilityVisibilityChains =
846 memory_model_features->vulkanMemoryModelAvailabilityVisibilityChains;
847 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700848 }
849
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700850 const auto *vulkan_11_features = LvlFindInChain<VkPhysicalDeviceVulkan11Features>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700851 if (vulkan_11_features) {
852 state_tracker->enabled_features.core11 = *vulkan_11_features;
853 } else {
sfricke-samsung828e59d2021-08-22 23:20:49 -0700854 // These structs are only allowed in pNext chain if there is no vkPhysicalDeviceVulkan11Features
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700855
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700856 const auto *sixteen_bit_storage_features = LvlFindInChain<VkPhysicalDevice16BitStorageFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700857 if (sixteen_bit_storage_features) {
858 state_tracker->enabled_features.core11.storageBuffer16BitAccess =
859 sixteen_bit_storage_features->storageBuffer16BitAccess;
860 state_tracker->enabled_features.core11.uniformAndStorageBuffer16BitAccess =
861 sixteen_bit_storage_features->uniformAndStorageBuffer16BitAccess;
862 state_tracker->enabled_features.core11.storagePushConstant16 = sixteen_bit_storage_features->storagePushConstant16;
863 state_tracker->enabled_features.core11.storageInputOutput16 = sixteen_bit_storage_features->storageInputOutput16;
864 }
865
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700866 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700867 if (multiview_features) {
868 state_tracker->enabled_features.core11.multiview = multiview_features->multiview;
869 state_tracker->enabled_features.core11.multiviewGeometryShader = multiview_features->multiviewGeometryShader;
870 state_tracker->enabled_features.core11.multiviewTessellationShader = multiview_features->multiviewTessellationShader;
871 }
872
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700873 const auto *variable_pointers_features = LvlFindInChain<VkPhysicalDeviceVariablePointersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700874 if (variable_pointers_features) {
875 state_tracker->enabled_features.core11.variablePointersStorageBuffer =
876 variable_pointers_features->variablePointersStorageBuffer;
877 state_tracker->enabled_features.core11.variablePointers = variable_pointers_features->variablePointers;
878 }
879
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700880 const auto *protected_memory_features = LvlFindInChain<VkPhysicalDeviceProtectedMemoryFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700881 if (protected_memory_features) {
882 state_tracker->enabled_features.core11.protectedMemory = protected_memory_features->protectedMemory;
883 }
884
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700885 const auto *ycbcr_conversion_features = LvlFindInChain<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700886 if (ycbcr_conversion_features) {
887 state_tracker->enabled_features.core11.samplerYcbcrConversion = ycbcr_conversion_features->samplerYcbcrConversion;
888 }
889
890 const auto *shader_draw_parameters_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700891 LvlFindInChain<VkPhysicalDeviceShaderDrawParametersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700892 if (shader_draw_parameters_features) {
893 state_tracker->enabled_features.core11.shaderDrawParameters = shader_draw_parameters_features->shaderDrawParameters;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700894 }
895 }
896
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700897 const auto *device_group_ci = LvlFindInChain<VkDeviceGroupDeviceCreateInfo>(pCreateInfo->pNext);
Tony-LunarGca4891a2020-08-10 15:46:46 -0600898 if (device_group_ci) {
899 state_tracker->physical_device_count = device_group_ci->physicalDeviceCount;
900 state_tracker->device_group_create_info = *device_group_ci;
901 } else {
902 state_tracker->physical_device_count = 1;
903 }
locke-lunargd556cc32019-09-17 01:21:23 -0600904
sfricke-samsung828e59d2021-08-22 23:20:49 -0700905 // Features from other extensions passesd in create info
906 {
907 const auto *exclusive_scissor_features = LvlFindInChain<VkPhysicalDeviceExclusiveScissorFeaturesNV>(pCreateInfo->pNext);
908 if (exclusive_scissor_features) {
909 state_tracker->enabled_features.exclusive_scissor_features = *exclusive_scissor_features;
910 }
locke-lunargd556cc32019-09-17 01:21:23 -0600911
sfricke-samsung828e59d2021-08-22 23:20:49 -0700912 const auto *shading_rate_image_features = LvlFindInChain<VkPhysicalDeviceShadingRateImageFeaturesNV>(pCreateInfo->pNext);
913 if (shading_rate_image_features) {
914 state_tracker->enabled_features.shading_rate_image_features = *shading_rate_image_features;
915 }
locke-lunargd556cc32019-09-17 01:21:23 -0600916
sfricke-samsung828e59d2021-08-22 23:20:49 -0700917 const auto *mesh_shader_features = LvlFindInChain<VkPhysicalDeviceMeshShaderFeaturesNV>(pCreateInfo->pNext);
918 if (mesh_shader_features) {
919 state_tracker->enabled_features.mesh_shader_features = *mesh_shader_features;
920 }
locke-lunargd556cc32019-09-17 01:21:23 -0600921
sfricke-samsung828e59d2021-08-22 23:20:49 -0700922 const auto *inline_uniform_block_features =
923 LvlFindInChain<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(pCreateInfo->pNext);
924 if (inline_uniform_block_features) {
925 state_tracker->enabled_features.inline_uniform_block_features = *inline_uniform_block_features;
926 }
locke-lunargd556cc32019-09-17 01:21:23 -0600927
sfricke-samsung828e59d2021-08-22 23:20:49 -0700928 const auto *transform_feedback_features = LvlFindInChain<VkPhysicalDeviceTransformFeedbackFeaturesEXT>(pCreateInfo->pNext);
929 if (transform_feedback_features) {
930 state_tracker->enabled_features.transform_feedback_features = *transform_feedback_features;
931 }
locke-lunargd556cc32019-09-17 01:21:23 -0600932
sfricke-samsung828e59d2021-08-22 23:20:49 -0700933 const auto *vtx_attrib_div_features = LvlFindInChain<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(pCreateInfo->pNext);
934 if (vtx_attrib_div_features) {
935 state_tracker->enabled_features.vtx_attrib_divisor_features = *vtx_attrib_div_features;
936 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700937
sfricke-samsung828e59d2021-08-22 23:20:49 -0700938 const auto *buffer_device_address_ext_features =
939 LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>(pCreateInfo->pNext);
940 if (buffer_device_address_ext_features) {
941 state_tracker->enabled_features.buffer_device_address_ext_features = *buffer_device_address_ext_features;
942 }
locke-lunargd556cc32019-09-17 01:21:23 -0600943
sfricke-samsung828e59d2021-08-22 23:20:49 -0700944 const auto *cooperative_matrix_features = LvlFindInChain<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(pCreateInfo->pNext);
945 if (cooperative_matrix_features) {
946 state_tracker->enabled_features.cooperative_matrix_features = *cooperative_matrix_features;
947 }
locke-lunargd556cc32019-09-17 01:21:23 -0600948
sfricke-samsung828e59d2021-08-22 23:20:49 -0700949 const auto *compute_shader_derivatives_features =
950 LvlFindInChain<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>(pCreateInfo->pNext);
951 if (compute_shader_derivatives_features) {
952 state_tracker->enabled_features.compute_shader_derivatives_features = *compute_shader_derivatives_features;
953 }
locke-lunargd556cc32019-09-17 01:21:23 -0600954
sfricke-samsung828e59d2021-08-22 23:20:49 -0700955 const auto *fragment_shader_barycentric_features =
956 LvlFindInChain<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>(pCreateInfo->pNext);
957 if (fragment_shader_barycentric_features) {
958 state_tracker->enabled_features.fragment_shader_barycentric_features = *fragment_shader_barycentric_features;
959 }
locke-lunargd556cc32019-09-17 01:21:23 -0600960
sfricke-samsung828e59d2021-08-22 23:20:49 -0700961 const auto *shader_image_footprint_features =
962 LvlFindInChain<VkPhysicalDeviceShaderImageFootprintFeaturesNV>(pCreateInfo->pNext);
963 if (shader_image_footprint_features) {
964 state_tracker->enabled_features.shader_image_footprint_features = *shader_image_footprint_features;
965 }
locke-lunargd556cc32019-09-17 01:21:23 -0600966
sfricke-samsung828e59d2021-08-22 23:20:49 -0700967 const auto *fragment_shader_interlock_features =
968 LvlFindInChain<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>(pCreateInfo->pNext);
969 if (fragment_shader_interlock_features) {
970 state_tracker->enabled_features.fragment_shader_interlock_features = *fragment_shader_interlock_features;
971 }
locke-lunargd556cc32019-09-17 01:21:23 -0600972
sfricke-samsung828e59d2021-08-22 23:20:49 -0700973 const auto *demote_to_helper_invocation_features =
974 LvlFindInChain<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>(pCreateInfo->pNext);
975 if (demote_to_helper_invocation_features) {
976 state_tracker->enabled_features.demote_to_helper_invocation_features = *demote_to_helper_invocation_features;
977 }
locke-lunargd556cc32019-09-17 01:21:23 -0600978
sfricke-samsung828e59d2021-08-22 23:20:49 -0700979 const auto *texel_buffer_alignment_features =
980 LvlFindInChain<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>(pCreateInfo->pNext);
981 if (texel_buffer_alignment_features) {
982 state_tracker->enabled_features.texel_buffer_alignment_features = *texel_buffer_alignment_features;
983 }
locke-lunargd556cc32019-09-17 01:21:23 -0600984
sfricke-samsung828e59d2021-08-22 23:20:49 -0700985 const auto *pipeline_exe_props_features =
986 LvlFindInChain<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>(pCreateInfo->pNext);
987 if (pipeline_exe_props_features) {
988 state_tracker->enabled_features.pipeline_exe_props_features = *pipeline_exe_props_features;
989 }
locke-lunargd556cc32019-09-17 01:21:23 -0600990
sfricke-samsung828e59d2021-08-22 23:20:49 -0700991 const auto *dedicated_allocation_image_aliasing_features =
992 LvlFindInChain<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>(pCreateInfo->pNext);
993 if (dedicated_allocation_image_aliasing_features) {
994 state_tracker->enabled_features.dedicated_allocation_image_aliasing_features =
995 *dedicated_allocation_image_aliasing_features;
996 }
Jeff Bolz82f854d2019-09-17 14:56:47 -0500997
sfricke-samsung828e59d2021-08-22 23:20:49 -0700998 const auto *performance_query_features = LvlFindInChain<VkPhysicalDevicePerformanceQueryFeaturesKHR>(pCreateInfo->pNext);
999 if (performance_query_features) {
1000 state_tracker->enabled_features.performance_query_features = *performance_query_features;
1001 }
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001002
sfricke-samsung828e59d2021-08-22 23:20:49 -07001003 const auto *device_coherent_memory_features = LvlFindInChain<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(pCreateInfo->pNext);
1004 if (device_coherent_memory_features) {
1005 state_tracker->enabled_features.device_coherent_memory_features = *device_coherent_memory_features;
1006 }
Tobias Hector782bcde2019-11-28 16:19:42 +00001007
sfricke-samsung828e59d2021-08-22 23:20:49 -07001008 const auto *ycbcr_image_array_features = LvlFindInChain<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>(pCreateInfo->pNext);
1009 if (ycbcr_image_array_features) {
1010 state_tracker->enabled_features.ycbcr_image_array_features = *ycbcr_image_array_features;
1011 }
sfricke-samsungcead0802020-01-30 22:20:10 -08001012
sfricke-samsung828e59d2021-08-22 23:20:49 -07001013 const auto *ray_query_features = LvlFindInChain<VkPhysicalDeviceRayQueryFeaturesKHR>(pCreateInfo->pNext);
1014 if (ray_query_features) {
1015 state_tracker->enabled_features.ray_query_features = *ray_query_features;
1016 }
sourav parmarcd5fb182020-07-17 12:58:44 -07001017
sfricke-samsung828e59d2021-08-22 23:20:49 -07001018 const auto *ray_tracing_pipeline_features =
1019 LvlFindInChain<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>(pCreateInfo->pNext);
1020 if (ray_tracing_pipeline_features) {
1021 state_tracker->enabled_features.ray_tracing_pipeline_features = *ray_tracing_pipeline_features;
1022 }
sourav parmarcd5fb182020-07-17 12:58:44 -07001023
sfricke-samsung828e59d2021-08-22 23:20:49 -07001024 const auto *ray_tracing_acceleration_structure_features =
1025 LvlFindInChain<VkPhysicalDeviceAccelerationStructureFeaturesKHR>(pCreateInfo->pNext);
1026 if (ray_tracing_acceleration_structure_features) {
1027 state_tracker->enabled_features.ray_tracing_acceleration_structure_features =
1028 *ray_tracing_acceleration_structure_features;
1029 }
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001030
sfricke-samsung828e59d2021-08-22 23:20:49 -07001031 const auto *robustness2_features = LvlFindInChain<VkPhysicalDeviceRobustness2FeaturesEXT>(pCreateInfo->pNext);
1032 if (robustness2_features) {
1033 state_tracker->enabled_features.robustness2_features = *robustness2_features;
1034 }
Jeff Bolz165818a2020-05-08 11:19:03 -05001035
sfricke-samsung828e59d2021-08-22 23:20:49 -07001036 const auto *fragment_density_map_features =
1037 LvlFindInChain<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(pCreateInfo->pNext);
1038 if (fragment_density_map_features) {
1039 state_tracker->enabled_features.fragment_density_map_features = *fragment_density_map_features;
1040 }
janharaldfredriksen-arm3b793772020-05-12 18:55:53 +02001041
sfricke-samsung828e59d2021-08-22 23:20:49 -07001042 const auto *fragment_density_map_features2 =
1043 LvlFindInChain<VkPhysicalDeviceFragmentDensityMap2FeaturesEXT>(pCreateInfo->pNext);
1044 if (fragment_density_map_features2) {
1045 state_tracker->enabled_features.fragment_density_map2_features = *fragment_density_map_features2;
1046 }
janharaldfredriksen-arm36e17572020-07-07 13:59:28 +02001047
sfricke-samsung828e59d2021-08-22 23:20:49 -07001048 const auto *astc_decode_features = LvlFindInChain<VkPhysicalDeviceASTCDecodeFeaturesEXT>(pCreateInfo->pNext);
1049 if (astc_decode_features) {
1050 state_tracker->enabled_features.astc_decode_features = *astc_decode_features;
1051 }
sfricke-samsung0c4a06f2020-06-27 01:24:32 -07001052
sfricke-samsung828e59d2021-08-22 23:20:49 -07001053 const auto *custom_border_color_features = LvlFindInChain<VkPhysicalDeviceCustomBorderColorFeaturesEXT>(pCreateInfo->pNext);
1054 if (custom_border_color_features) {
1055 state_tracker->enabled_features.custom_border_color_features = *custom_border_color_features;
1056 }
Tony-LunarG7337b312020-04-15 16:40:25 -06001057
sfricke-samsung828e59d2021-08-22 23:20:49 -07001058 const auto *pipeline_creation_cache_control_features =
1059 LvlFindInChain<VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT>(pCreateInfo->pNext);
1060 if (pipeline_creation_cache_control_features) {
1061 state_tracker->enabled_features.pipeline_creation_cache_control_features = *pipeline_creation_cache_control_features;
1062 }
sfricke-samsungfd661d62020-05-16 00:57:27 -07001063
sfricke-samsung828e59d2021-08-22 23:20:49 -07001064 const auto *fragment_shading_rate_features =
1065 LvlFindInChain<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>(pCreateInfo->pNext);
1066 if (fragment_shading_rate_features) {
1067 state_tracker->enabled_features.fragment_shading_rate_features = *fragment_shading_rate_features;
1068 }
Tobias Hector6663c9b2020-11-05 10:18:02 +00001069
sfricke-samsung828e59d2021-08-22 23:20:49 -07001070 const auto *extended_dynamic_state_features =
1071 LvlFindInChain<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>(pCreateInfo->pNext);
1072 if (extended_dynamic_state_features) {
1073 state_tracker->enabled_features.extended_dynamic_state_features = *extended_dynamic_state_features;
1074 }
Piers Daniell39842ee2020-07-10 16:42:33 -06001075
sfricke-samsung828e59d2021-08-22 23:20:49 -07001076 const auto *extended_dynamic_state2_features =
1077 LvlFindInChain<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>(pCreateInfo->pNext);
1078 if (extended_dynamic_state2_features) {
1079 state_tracker->enabled_features.extended_dynamic_state2_features = *extended_dynamic_state2_features;
1080 }
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07001081
sfricke-samsung828e59d2021-08-22 23:20:49 -07001082 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
1083 if (multiview_features) {
1084 state_tracker->enabled_features.multiview_features = *multiview_features;
1085 }
locke-lunarg3fa463a2020-10-23 16:39:04 -06001086
sfricke-samsung828e59d2021-08-22 23:20:49 -07001087 const auto *portability_features = LvlFindInChain<VkPhysicalDevicePortabilitySubsetFeaturesKHR>(pCreateInfo->pNext);
1088 if (portability_features) {
1089 state_tracker->enabled_features.portability_subset_features = *portability_features;
1090 }
Nathaniel Cesariob3f2d702020-11-09 09:20:49 -07001091
sfricke-samsung828e59d2021-08-22 23:20:49 -07001092 const auto *shader_integer_functions2_features =
1093 LvlFindInChain<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>(pCreateInfo->pNext);
1094 if (shader_integer_functions2_features) {
1095 state_tracker->enabled_features.shader_integer_functions2_features = *shader_integer_functions2_features;
1096 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001097
sfricke-samsung828e59d2021-08-22 23:20:49 -07001098 const auto *shader_sm_builtins_features = LvlFindInChain<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>(pCreateInfo->pNext);
1099 if (shader_sm_builtins_features) {
1100 state_tracker->enabled_features.shader_sm_builtins_features = *shader_sm_builtins_features;
1101 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001102
sfricke-samsung828e59d2021-08-22 23:20:49 -07001103 const auto *shader_atomic_float_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>(pCreateInfo->pNext);
1104 if (shader_atomic_float_features) {
1105 state_tracker->enabled_features.shader_atomic_float_features = *shader_atomic_float_features;
1106 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001107
sfricke-samsung828e59d2021-08-22 23:20:49 -07001108 const auto *shader_image_atomic_int64_features =
1109 LvlFindInChain<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>(pCreateInfo->pNext);
1110 if (shader_image_atomic_int64_features) {
1111 state_tracker->enabled_features.shader_image_atomic_int64_features = *shader_image_atomic_int64_features;
1112 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001113
sfricke-samsung828e59d2021-08-22 23:20:49 -07001114 const auto *shader_clock_features = LvlFindInChain<VkPhysicalDeviceShaderClockFeaturesKHR>(pCreateInfo->pNext);
1115 if (shader_clock_features) {
1116 state_tracker->enabled_features.shader_clock_features = *shader_clock_features;
1117 }
sfricke-samsung486a51e2021-01-02 00:10:15 -08001118
sfricke-samsung828e59d2021-08-22 23:20:49 -07001119 const auto *conditional_rendering_features =
1120 LvlFindInChain<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(pCreateInfo->pNext);
1121 if (conditional_rendering_features) {
1122 state_tracker->enabled_features.conditional_rendering_features = *conditional_rendering_features;
1123 }
Jeremy Gebben5f585ae2021-02-02 09:03:06 -07001124
sfricke-samsung828e59d2021-08-22 23:20:49 -07001125 const auto *workgroup_memory_explicit_layout_features =
1126 LvlFindInChain<VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>(pCreateInfo->pNext);
1127 if (workgroup_memory_explicit_layout_features) {
1128 state_tracker->enabled_features.workgroup_memory_explicit_layout_features = *workgroup_memory_explicit_layout_features;
1129 }
Shannon McPhersondb287d42021-02-02 15:27:32 -07001130
sfricke-samsung828e59d2021-08-22 23:20:49 -07001131 const auto *synchronization2_features = LvlFindInChain<VkPhysicalDeviceSynchronization2FeaturesKHR>(pCreateInfo->pNext);
1132 if (synchronization2_features) {
1133 state_tracker->enabled_features.synchronization2_features = *synchronization2_features;
1134 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001135
sfricke-samsung828e59d2021-08-22 23:20:49 -07001136 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(pCreateInfo->pNext);
1137 if (provoking_vertex_features) {
1138 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
1139 }
Locke Linf3873542021-04-26 11:25:10 -06001140
sfricke-samsung828e59d2021-08-22 23:20:49 -07001141 const auto *vertex_input_dynamic_state_features =
1142 LvlFindInChain<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>(pCreateInfo->pNext);
1143 if (vertex_input_dynamic_state_features) {
1144 state_tracker->enabled_features.vertex_input_dynamic_state_features = *vertex_input_dynamic_state_features;
1145 }
Piers Daniellcb6d8032021-04-19 18:51:26 -06001146
sfricke-samsung828e59d2021-08-22 23:20:49 -07001147 const auto *inherited_viewport_scissor_features =
1148 LvlFindInChain<VkPhysicalDeviceInheritedViewportScissorFeaturesNV>(pCreateInfo->pNext);
1149 if (inherited_viewport_scissor_features) {
1150 state_tracker->enabled_features.inherited_viewport_scissor_features = *inherited_viewport_scissor_features;
1151 }
David Zhao Akeley44139b12021-04-26 16:16:13 -07001152
sfricke-samsung828e59d2021-08-22 23:20:49 -07001153 const auto *multi_draw_features = LvlFindInChain<VkPhysicalDeviceMultiDrawFeaturesEXT>(pCreateInfo->pNext);
1154 if (multi_draw_features) {
1155 state_tracker->enabled_features.multi_draw_features = *multi_draw_features;
1156 }
Tony-LunarG4490de42021-06-21 15:49:19 -06001157
sfricke-samsung828e59d2021-08-22 23:20:49 -07001158 const auto *color_write_features = LvlFindInChain<VkPhysicalDeviceColorWriteEnableFeaturesEXT>(pCreateInfo->pNext);
1159 if (color_write_features) {
1160 state_tracker->enabled_features.color_write_features = *color_write_features;
1161 }
ziga-lunarg29ba2b92021-07-20 21:51:45 +02001162
sfricke-samsung828e59d2021-08-22 23:20:49 -07001163 const auto *shader_atomic_float2_features =
1164 LvlFindInChain<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>(pCreateInfo->pNext);
1165 if (shader_atomic_float2_features) {
1166 state_tracker->enabled_features.shader_atomic_float2_features = *shader_atomic_float2_features;
1167 }
Mike Schuchardtb3870ea2021-07-20 18:56:51 -07001168
sfricke-samsung828e59d2021-08-22 23:20:49 -07001169 const auto *present_id_features = LvlFindInChain<VkPhysicalDevicePresentIdFeaturesKHR>(pCreateInfo->pNext);
1170 if (present_id_features) {
1171 state_tracker->enabled_features.present_id_features = *present_id_features;
1172 }
Tony-LunarG6f887e52021-07-27 11:23:14 -06001173
sfricke-samsung828e59d2021-08-22 23:20:49 -07001174 const auto *present_wait_features = LvlFindInChain<VkPhysicalDevicePresentWaitFeaturesKHR>(pCreateInfo->pNext);
1175 if (present_wait_features) {
1176 state_tracker->enabled_features.present_wait_features = *present_wait_features;
1177 }
Mike Schuchardt9f65d3f2021-08-25 15:11:39 -07001178
1179 const auto *ray_tracing_motion_blur_features =
1180 LvlFindInChain<VkPhysicalDeviceRayTracingMotionBlurFeaturesNV>(pCreateInfo->pNext);
1181 if (ray_tracing_motion_blur_features) {
1182 state_tracker->enabled_features.ray_tracing_motion_blur_features = *ray_tracing_motion_blur_features;
1183 }
Mike Schuchardtb4d90452021-08-30 09:24:51 -07001184
1185 const auto *shader_integer_dot_product_features =
1186 LvlFindInChain<VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR>(pCreateInfo->pNext);
1187 if (shader_integer_dot_product_features) {
1188 state_tracker->enabled_features.shader_integer_dot_product_features = *shader_integer_dot_product_features;
1189 }
Tony-LunarG0b0d8be2021-08-30 13:50:38 -06001190
1191 const auto *primitive_topology_list_restart_features =
1192 LvlFindInChain<VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>(pCreateInfo->pNext);
1193 if (primitive_topology_list_restart_features) {
1194 state_tracker->enabled_features.primitive_topology_list_restart_features = *primitive_topology_list_restart_features;
1195 }
Tony-LunarG6f887e52021-07-27 11:23:14 -06001196 }
1197
locke-lunargd556cc32019-09-17 01:21:23 -06001198 // Store physical device properties and physical device mem limits into CoreChecks structs
1199 DispatchGetPhysicalDeviceMemoryProperties(gpu, &state_tracker->phys_dev_mem_props);
1200 DispatchGetPhysicalDeviceProperties(gpu, &state_tracker->phys_dev_props);
1201
1202 const auto &dev_ext = state_tracker->device_extensions;
1203 auto *phys_dev_props = &state_tracker->phys_dev_ext_props;
1204
sfricke-samsung828e59d2021-08-22 23:20:49 -07001205 // Vulkan 1.2 can get properties from single struct, otherwise need to add to it per extension
1206 if (state_tracker->device_extensions.vk_feature_version_1_2) {
1207 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1208 &state_tracker->phys_dev_props_core11);
1209 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1210 &state_tracker->phys_dev_props_core12);
1211 } else {
1212 // VkPhysicalDeviceVulkan11Properties
1213 //
1214 // Can ingnore VkPhysicalDeviceIDProperties as it has no validation purpose
1215
1216 if (dev_ext.vk_khr_multiview) {
1217 auto multiview_props = LvlInitStruct<VkPhysicalDeviceMultiviewProperties>();
1218 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_multiview, &multiview_props);
1219 state_tracker->phys_dev_props_core11.maxMultiviewViewCount = multiview_props.maxMultiviewViewCount;
1220 state_tracker->phys_dev_props_core11.maxMultiviewInstanceIndex = multiview_props.maxMultiviewInstanceIndex;
1221 }
1222
1223 if (dev_ext.vk_khr_maintenance3) {
1224 auto maintenance3_props = LvlInitStruct<VkPhysicalDeviceMaintenance3Properties>();
1225 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_maintenance3, &maintenance3_props);
1226 state_tracker->phys_dev_props_core11.maxPerSetDescriptors = maintenance3_props.maxPerSetDescriptors;
1227 state_tracker->phys_dev_props_core11.maxMemoryAllocationSize = maintenance3_props.maxMemoryAllocationSize;
1228 }
1229
1230 // Some 1.1 properties were added to core without previous extensions
1231 if (state_tracker->api_version >= VK_API_VERSION_1_1) {
1232 auto subgroup_prop = LvlInitStruct<VkPhysicalDeviceSubgroupProperties>();
1233 auto protected_memory_prop = LvlInitStruct<VkPhysicalDeviceProtectedMemoryProperties>(&subgroup_prop);
1234 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&protected_memory_prop);
1235 instance_dispatch_table.GetPhysicalDeviceProperties2(gpu, &prop2);
1236
1237 state_tracker->phys_dev_props_core11.subgroupSize = subgroup_prop.subgroupSize;
1238 state_tracker->phys_dev_props_core11.subgroupSupportedStages = subgroup_prop.supportedStages;
1239 state_tracker->phys_dev_props_core11.subgroupSupportedOperations = subgroup_prop.supportedOperations;
1240 state_tracker->phys_dev_props_core11.subgroupQuadOperationsInAllStages = subgroup_prop.quadOperationsInAllStages;
1241
1242 state_tracker->phys_dev_props_core11.protectedNoFault = protected_memory_prop.protectedNoFault;
1243 }
1244
1245 // VkPhysicalDeviceVulkan12Properties
1246 //
1247 // Can ingnore VkPhysicalDeviceDriverProperties as it has no validation purpose
1248
1249 if (dev_ext.vk_ext_descriptor_indexing) {
1250 auto descriptor_indexing_prop = LvlInitStruct<VkPhysicalDeviceDescriptorIndexingProperties>();
1251 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_descriptor_indexing, &descriptor_indexing_prop);
1252 state_tracker->phys_dev_props_core12.maxUpdateAfterBindDescriptorsInAllPools =
1253 descriptor_indexing_prop.maxUpdateAfterBindDescriptorsInAllPools;
1254 state_tracker->phys_dev_props_core12.shaderUniformBufferArrayNonUniformIndexingNative =
1255 descriptor_indexing_prop.shaderUniformBufferArrayNonUniformIndexingNative;
1256 state_tracker->phys_dev_props_core12.shaderSampledImageArrayNonUniformIndexingNative =
1257 descriptor_indexing_prop.shaderSampledImageArrayNonUniformIndexingNative;
1258 state_tracker->phys_dev_props_core12.shaderStorageBufferArrayNonUniformIndexingNative =
1259 descriptor_indexing_prop.shaderStorageBufferArrayNonUniformIndexingNative;
1260 state_tracker->phys_dev_props_core12.shaderStorageImageArrayNonUniformIndexingNative =
1261 descriptor_indexing_prop.shaderStorageImageArrayNonUniformIndexingNative;
1262 state_tracker->phys_dev_props_core12.shaderInputAttachmentArrayNonUniformIndexingNative =
1263 descriptor_indexing_prop.shaderInputAttachmentArrayNonUniformIndexingNative;
1264 state_tracker->phys_dev_props_core12.robustBufferAccessUpdateAfterBind =
1265 descriptor_indexing_prop.robustBufferAccessUpdateAfterBind;
1266 state_tracker->phys_dev_props_core12.quadDivergentImplicitLod = descriptor_indexing_prop.quadDivergentImplicitLod;
1267 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSamplers =
1268 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSamplers;
1269 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindUniformBuffers =
1270 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindUniformBuffers;
1271 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageBuffers =
1272 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageBuffers;
1273 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSampledImages =
1274 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSampledImages;
1275 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageImages =
1276 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageImages;
1277 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindInputAttachments =
1278 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindInputAttachments;
1279 state_tracker->phys_dev_props_core12.maxPerStageUpdateAfterBindResources =
1280 descriptor_indexing_prop.maxPerStageUpdateAfterBindResources;
1281 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSamplers =
1282 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSamplers;
1283 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffers =
1284 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffers;
1285 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
1286 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
1287 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffers =
1288 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffers;
1289 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
1290 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
1291 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSampledImages =
1292 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSampledImages;
1293 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageImages =
1294 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageImages;
1295 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindInputAttachments =
1296 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindInputAttachments;
1297 }
1298
1299 if (dev_ext.vk_khr_depth_stencil_resolve) {
1300 auto depth_stencil_resolve_props = LvlInitStruct<VkPhysicalDeviceDepthStencilResolveProperties>();
1301 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_depth_stencil_resolve, &depth_stencil_resolve_props);
1302 state_tracker->phys_dev_props_core12.supportedDepthResolveModes =
1303 depth_stencil_resolve_props.supportedDepthResolveModes;
1304 state_tracker->phys_dev_props_core12.supportedStencilResolveModes =
1305 depth_stencil_resolve_props.supportedStencilResolveModes;
1306 state_tracker->phys_dev_props_core12.independentResolveNone = depth_stencil_resolve_props.independentResolveNone;
1307 state_tracker->phys_dev_props_core12.independentResolve = depth_stencil_resolve_props.independentResolve;
1308 }
1309
1310 if (dev_ext.vk_khr_timeline_semaphore) {
1311 auto timeline_semaphore_props = LvlInitStruct<VkPhysicalDeviceTimelineSemaphoreProperties>();
1312 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_timeline_semaphore, &timeline_semaphore_props);
1313 state_tracker->phys_dev_props_core12.maxTimelineSemaphoreValueDifference =
1314 timeline_semaphore_props.maxTimelineSemaphoreValueDifference;
1315 }
1316
1317 if (dev_ext.vk_ext_sampler_filter_minmax) {
1318 auto sampler_filter_minmax_props = LvlInitStruct<VkPhysicalDeviceSamplerFilterMinmaxProperties>();
1319 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_sampler_filter_minmax, &sampler_filter_minmax_props);
1320 state_tracker->phys_dev_props_core12.filterMinmaxSingleComponentFormats =
1321 sampler_filter_minmax_props.filterMinmaxSingleComponentFormats;
1322 state_tracker->phys_dev_props_core12.filterMinmaxImageComponentMapping =
1323 sampler_filter_minmax_props.filterMinmaxImageComponentMapping;
1324 }
1325
1326 if (dev_ext.vk_khr_shader_float_controls) {
1327 auto float_controls_props = LvlInitStruct<VkPhysicalDeviceFloatControlsProperties>();
1328 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_shader_float_controls, &float_controls_props);
1329 state_tracker->phys_dev_props_core12.denormBehaviorIndependence = float_controls_props.denormBehaviorIndependence;
1330 state_tracker->phys_dev_props_core12.roundingModeIndependence = float_controls_props.roundingModeIndependence;
1331 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat16 =
1332 float_controls_props.shaderSignedZeroInfNanPreserveFloat16;
1333 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat32 =
1334 float_controls_props.shaderSignedZeroInfNanPreserveFloat32;
1335 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat64 =
1336 float_controls_props.shaderSignedZeroInfNanPreserveFloat64;
1337 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat16 = float_controls_props.shaderDenormPreserveFloat16;
1338 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat32 = float_controls_props.shaderDenormPreserveFloat32;
1339 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat64 = float_controls_props.shaderDenormPreserveFloat64;
1340 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat16 =
1341 float_controls_props.shaderDenormFlushToZeroFloat16;
1342 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat32 =
1343 float_controls_props.shaderDenormFlushToZeroFloat32;
1344 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat64 =
1345 float_controls_props.shaderDenormFlushToZeroFloat64;
1346 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat16 = float_controls_props.shaderRoundingModeRTEFloat16;
1347 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat32 = float_controls_props.shaderRoundingModeRTEFloat32;
1348 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat64 = float_controls_props.shaderRoundingModeRTEFloat64;
1349 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat16 = float_controls_props.shaderRoundingModeRTZFloat16;
1350 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat32 = float_controls_props.shaderRoundingModeRTZFloat32;
1351 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat64 = float_controls_props.shaderRoundingModeRTZFloat64;
1352 }
locke-lunargd556cc32019-09-17 01:21:23 -06001353 }
1354
sfricke-samsung828e59d2021-08-22 23:20:49 -07001355 // Extensions with properties to extract to DeviceExtensionProperties
1356 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_push_descriptor, &phys_dev_props->push_descriptor_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001357 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_shading_rate_image, &phys_dev_props->shading_rate_image_props);
1358 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_mesh_shader, &phys_dev_props->mesh_shader_props);
1359 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_inline_uniform_block, &phys_dev_props->inline_uniform_block_props);
1360 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_vertex_attribute_divisor, &phys_dev_props->vtx_attrib_divisor_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001361 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_transform_feedback, &phys_dev_props->transform_feedback_props);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001362 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_ray_tracing, &phys_dev_props->ray_tracing_propsNV);
sourav parmarcd5fb182020-07-17 12:58:44 -07001363 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_ray_tracing_pipeline, &phys_dev_props->ray_tracing_propsKHR);
1364 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_acceleration_structure, &phys_dev_props->acc_structure_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001365 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_texel_buffer_alignment, &phys_dev_props->texel_buffer_alignment_props);
1366 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map, &phys_dev_props->fragment_density_map_props);
Mike Schuchardtc57de4a2021-07-20 17:26:32 -07001367 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map2, &phys_dev_props->fragment_density_map2_props);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001368 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_performance_query, &phys_dev_props->performance_query_props);
sfricke-samsung8f658d42020-05-03 20:12:24 -07001369 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_sample_locations, &phys_dev_props->sample_locations_props);
Tony-LunarG7337b312020-04-15 16:40:25 -06001370 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_custom_border_color, &phys_dev_props->custom_border_color_props);
locke-lunarg3fa463a2020-10-23 16:39:04 -06001371 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_multiview, &phys_dev_props->multiview_props);
Nathaniel Cesario3291c912020-11-17 16:54:41 -07001372 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_portability_subset, &phys_dev_props->portability_props);
sfricke-samsung828e59d2021-08-22 23:20:49 -07001373 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_fragment_shading_rate, &phys_dev_props->fragment_shading_rate_props);
Locke Lin016d8482021-05-27 12:11:31 -06001374 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_provoking_vertex, &phys_dev_props->provoking_vertex_props);
Tony-LunarG4490de42021-06-21 15:49:19 -06001375 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_multi_draw, &phys_dev_props->multi_draw_props);
ziga-lunarg128904a2021-07-30 13:49:01 +02001376 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_discard_rectangles, &phys_dev_props->discard_rectangle_props);
ziga-lunarg86492812021-08-05 23:58:16 +02001377 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_blend_operation_advanced, &phys_dev_props->blend_operation_advanced_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001378
locke-lunargd556cc32019-09-17 01:21:23 -06001379 if (state_tracker->device_extensions.vk_nv_cooperative_matrix) {
1380 // Get the needed cooperative_matrix properties
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001381 auto cooperative_matrix_props = LvlInitStruct<VkPhysicalDeviceCooperativeMatrixPropertiesNV>();
1382 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&cooperative_matrix_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001383 instance_dispatch_table.GetPhysicalDeviceProperties2KHR(gpu, &prop2);
1384 state_tracker->phys_dev_ext_props.cooperative_matrix_props = cooperative_matrix_props;
1385
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001386 uint32_t num_cooperative_matrix_properties = 0;
1387 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties, NULL);
1388 state_tracker->cooperative_matrix_properties.resize(num_cooperative_matrix_properties,
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001389 LvlInitStruct<VkCooperativeMatrixPropertiesNV>());
locke-lunargd556cc32019-09-17 01:21:23 -06001390
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001391 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties,
locke-lunargd556cc32019-09-17 01:21:23 -06001392 state_tracker->cooperative_matrix_properties.data());
1393 }
Tobias Hector6663c9b2020-11-05 10:18:02 +00001394
locke-lunargd556cc32019-09-17 01:21:23 -06001395 // Store queue family data
1396 if (pCreateInfo->pQueueCreateInfos != nullptr) {
1397 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
sfricke-samsung590ae1e2020-04-25 01:18:05 -07001398 const VkDeviceQueueCreateInfo &queue_create_info = pCreateInfo->pQueueCreateInfos[i];
sfricke-samsungb585ec12021-05-06 03:10:13 -07001399 state_tracker->queue_family_index_set.insert(queue_create_info.queueFamilyIndex);
1400 state_tracker->device_queue_info_list.push_back(
1401 {i, queue_create_info.queueFamilyIndex, queue_create_info.flags, queue_create_info.queueCount});
locke-lunargd556cc32019-09-17 01:21:23 -06001402 }
1403 }
1404}
1405
1406void ValidationStateTracker::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
1407 if (!device) return;
1408
locke-lunargd556cc32019-09-17 01:21:23 -06001409 // Reset all command buffers before destroying them, to unlink object_bindings.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001410 for (auto &command_buffer : commandBufferMap) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001411 command_buffer.second->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06001412 }
Jeff Bolzadbfa852019-10-04 13:53:30 -05001413 pipelineMap.clear();
1414 renderPassMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001415 commandBufferMap.clear();
1416
1417 // This will also delete all sets in the pool & remove them from setMap
1418 DeleteDescriptorSetPools();
1419 // All sets should be removed
1420 assert(setMap.empty());
1421 descriptorSetLayoutMap.clear();
Jeremy Gebben5a542f52021-07-21 15:25:52 -06001422 // Because swapchains are associated with Surfaces, which are at instance level,
1423 // they need to be explicitly destroyed here to avoid continued references to
1424 // the device we're destroying.
1425 for (auto &entry : swapchainMap) {
1426 entry.second->Destroy();
1427 }
1428 swapchainMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001429 imageViewMap.clear();
1430 imageMap.clear();
1431 bufferViewMap.clear();
1432 bufferMap.clear();
1433 // Queues persist until device is destroyed
1434 queueMap.clear();
1435}
1436
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001437void ValidationStateTracker::RetireWorkOnQueue(QUEUE_STATE *pQueue, uint64_t seq) {
Jeremy Gebbencbf22862021-03-03 12:01:22 -07001438 layer_data::unordered_map<VkQueue, uint64_t> other_queue_seqs;
1439 layer_data::unordered_map<VkSemaphore, uint64_t> timeline_semaphore_counters;
locke-lunargd556cc32019-09-17 01:21:23 -06001440
1441 // Roll this queue forward, one submission at a time.
1442 while (pQueue->seq < seq) {
1443 auto &submission = pQueue->submissions.front();
1444
1445 for (auto &wait : submission.waitSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001446 auto semaphore_state = GetSemaphoreState(wait.semaphore);
1447 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001448 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001449 }
Mike Schuchardt2df08912020-12-15 16:28:09 -08001450 if (wait.type == VK_SEMAPHORE_TYPE_TIMELINE) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001451 auto &last_counter = timeline_semaphore_counters[wait.semaphore];
1452 last_counter = std::max(last_counter, wait.payload);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001453 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001454 auto &last_seq = other_queue_seqs[wait.queue];
1455 last_seq = std::max(last_seq, wait.seq);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001456 }
locke-lunargd556cc32019-09-17 01:21:23 -06001457 }
1458
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001459 for (auto &signal : submission.signalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001460 auto semaphore_state = GetSemaphoreState(signal.semaphore);
1461 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001462 semaphore_state->EndUse();
Mike Schuchardt2df08912020-12-15 16:28:09 -08001463 if (semaphore_state->type == VK_SEMAPHORE_TYPE_TIMELINE && semaphore_state->payload < signal.payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001464 semaphore_state->payload = signal.payload;
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001465 }
locke-lunargd556cc32019-09-17 01:21:23 -06001466 }
1467 }
1468
1469 for (auto &semaphore : submission.externalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001470 auto semaphore_state = GetSemaphoreState(semaphore);
1471 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001472 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001473 }
1474 }
1475
1476 for (auto cb : submission.cbs) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06001477 auto cb_node = Get<CMD_BUFFER_STATE>(cb);
locke-lunargd556cc32019-09-17 01:21:23 -06001478 if (!cb_node) {
1479 continue;
1480 }
1481 // First perform decrement on general case bound objects
locke-lunargd556cc32019-09-17 01:21:23 -06001482 for (auto event : cb_node->writeEventsBeforeWait) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001483 auto event_node = eventMap.find(event);
1484 if (event_node != eventMap.end()) {
John Zulauf48057322020-12-02 11:59:31 -07001485 event_node->second->write_in_use--;
locke-lunargd556cc32019-09-17 01:21:23 -06001486 }
1487 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001488 QueryMap local_query_to_state_map;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001489 VkQueryPool first_pool = VK_NULL_HANDLE;
Jeff Bolz310775c2019-10-09 00:46:33 -05001490 for (auto &function : cb_node->queryUpdates) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001491 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
Jeff Bolz310775c2019-10-09 00:46:33 -05001492 }
1493
John Zulauf79f06582021-02-27 18:38:39 -07001494 for (const auto &query_state_pair : local_query_to_state_map) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001495 if (query_state_pair.second == QUERYSTATE_ENDED) {
1496 queryToStateMap[query_state_pair.first] = QUERYSTATE_AVAILABLE;
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001497 }
locke-lunargd556cc32019-09-17 01:21:23 -06001498 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001499 if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
1500 cb_node->EndUse();
1501 }
locke-lunargd556cc32019-09-17 01:21:23 -06001502 }
1503
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001504 auto fence_state = GetFenceState(submission.fence);
1505 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1506 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001507 }
1508
1509 pQueue->submissions.pop_front();
1510 pQueue->seq++;
1511 }
1512
1513 // Roll other queues forward to the highest seq we saw a wait for
John Zulauf79f06582021-02-27 18:38:39 -07001514 for (const auto &qs : other_queue_seqs) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001515 RetireWorkOnQueue(GetQueueState(qs.first), qs.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001516 }
John Zulauf79f06582021-02-27 18:38:39 -07001517 for (const auto &sc : timeline_semaphore_counters) {
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001518 RetireTimelineSemaphore(sc.first, sc.second);
1519 }
locke-lunargd556cc32019-09-17 01:21:23 -06001520}
1521
1522// Submit a fence to a queue, delimiting previous fences and previous untracked
1523// work by it.
1524static void SubmitFence(QUEUE_STATE *pQueue, FENCE_STATE *pFence, uint64_t submitCount) {
1525 pFence->state = FENCE_INFLIGHT;
1526 pFence->signaler.first = pQueue->queue;
1527 pFence->signaler.second = pQueue->seq + pQueue->submissions.size() + submitCount;
1528}
1529
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001530uint64_t ValidationStateTracker::RecordSubmitFence(QUEUE_STATE *queue_state, VkFence fence, uint32_t submit_count) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001531 auto fence_state = GetFenceState(fence);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001532 uint64_t early_retire_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001533 if (fence_state) {
1534 if (fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06001535 // Mark fence in use
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001536 SubmitFence(queue_state, fence_state, std::max(1u, submit_count));
1537 if (!submit_count) {
locke-lunargd556cc32019-09-17 01:21:23 -06001538 // If no submissions, but just dropping a fence on the end of the queue,
1539 // record an empty submission with just the fence, so we can determine
1540 // its completion.
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001541 CB_SUBMISSION submission;
1542 submission.fence = fence;
1543 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001544 }
1545 } else {
1546 // 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 -07001547 early_retire_seq = queue_state->seq + queue_state->submissions.size();
locke-lunargd556cc32019-09-17 01:21:23 -06001548 }
1549 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001550 return early_retire_seq;
1551}
1552
1553void ValidationStateTracker::RecordSubmitCommandBuffer(CB_SUBMISSION &submission, VkCommandBuffer command_buffer) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06001554 auto cb_node = Get<CMD_BUFFER_STATE>(command_buffer);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001555 if (cb_node) {
1556 submission.cbs.push_back(command_buffer);
John Zulauf79f06582021-02-27 18:38:39 -07001557 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001558 submission.cbs.push_back(secondary_cmd_buffer->commandBuffer());
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001559 secondary_cmd_buffer->IncrementResources();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001560 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001561 cb_node->IncrementResources();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001562 // increment use count for all bound objects including secondary cbs
1563 cb_node->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001564
1565 VkQueryPool first_pool = VK_NULL_HANDLE;
1566 EventToStageMap local_event_to_stage_map;
1567 QueryMap local_query_to_state_map;
1568 for (auto &function : cb_node->queryUpdates) {
1569 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
1570 }
1571
John Zulauf79f06582021-02-27 18:38:39 -07001572 for (const auto &query_state_pair : local_query_to_state_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001573 queryToStateMap[query_state_pair.first] = query_state_pair.second;
1574 }
1575
John Zulauf79f06582021-02-27 18:38:39 -07001576 for (const auto &function : cb_node->eventUpdates) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001577 function(nullptr, /*do_validate*/ false, &local_event_to_stage_map);
1578 }
1579
John Zulauf79f06582021-02-27 18:38:39 -07001580 for (const auto &eventStagePair : local_event_to_stage_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001581 eventMap[eventStagePair.first]->stageMask = eventStagePair.second;
1582 }
1583 }
1584}
1585
1586void ValidationStateTracker::RecordSubmitWaitSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1587 uint64_t value, uint64_t next_seq) {
1588 auto semaphore_state = GetSemaphoreState(semaphore);
1589 if (semaphore_state) {
1590 if (semaphore_state->scope == kSyncScopeInternal) {
1591 SEMAPHORE_WAIT wait;
1592 wait.semaphore = semaphore;
1593 wait.type = semaphore_state->type;
1594 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1595 if (semaphore_state->signaler.first != VK_NULL_HANDLE) {
1596 wait.queue = semaphore_state->signaler.first;
1597 wait.seq = semaphore_state->signaler.second;
1598 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001599 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001600 }
1601 semaphore_state->signaler.first = VK_NULL_HANDLE;
1602 semaphore_state->signaled = false;
1603 } else if (semaphore_state->payload < value) {
1604 wait.queue = queue;
1605 wait.seq = next_seq;
1606 wait.payload = value;
1607 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001608 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001609 }
1610 } else {
1611 submission.externalSemaphores.push_back(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001612 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001613 if (semaphore_state->scope == kSyncScopeExternalTemporary) {
1614 semaphore_state->scope = kSyncScopeInternal;
1615 }
1616 }
1617 }
1618}
1619
1620bool ValidationStateTracker::RecordSubmitSignalSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1621 uint64_t value, uint64_t next_seq) {
1622 bool retire_early = false;
1623 auto semaphore_state = GetSemaphoreState(semaphore);
1624 if (semaphore_state) {
1625 if (semaphore_state->scope == kSyncScopeInternal) {
1626 SEMAPHORE_SIGNAL signal;
1627 signal.semaphore = semaphore;
1628 signal.seq = next_seq;
1629 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1630 semaphore_state->signaler.first = queue;
1631 semaphore_state->signaler.second = next_seq;
1632 semaphore_state->signaled = true;
1633 } else {
1634 signal.payload = value;
1635 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001636 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001637 submission.signalSemaphores.emplace_back(std::move(signal));
1638 } else {
1639 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1640 retire_early = true;
1641 }
1642 }
1643 return retire_early;
1644}
1645
1646void ValidationStateTracker::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
1647 VkFence fence, VkResult result) {
1648 if (result != VK_SUCCESS) return;
1649 auto queue_state = GetQueueState(queue);
1650
1651 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001652
1653 // Now process each individual submit
1654 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001655 CB_SUBMISSION submission;
locke-lunargd556cc32019-09-17 01:21:23 -06001656 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001657 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001658 auto *timeline_semaphore_submit = LvlFindInChain<VkTimelineSemaphoreSubmitInfo>(submit->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001659 for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001660 uint64_t value = 0;
1661 if (timeline_semaphore_submit && timeline_semaphore_submit->pWaitSemaphoreValues != nullptr &&
1662 (i < timeline_semaphore_submit->waitSemaphoreValueCount)) {
1663 value = timeline_semaphore_submit->pWaitSemaphoreValues[i];
1664 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001665 RecordSubmitWaitSemaphore(submission, queue, submit->pWaitSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001666 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001667
1668 bool retire_early = false;
locke-lunargd556cc32019-09-17 01:21:23 -06001669 for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001670 uint64_t value = 0;
1671 if (timeline_semaphore_submit && timeline_semaphore_submit->pSignalSemaphoreValues != nullptr &&
1672 (i < timeline_semaphore_submit->signalSemaphoreValueCount)) {
1673 value = timeline_semaphore_submit->pSignalSemaphoreValues[i];
1674 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001675 retire_early |= RecordSubmitSignalSemaphore(submission, queue, submit->pSignalSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001676 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001677 if (retire_early) {
1678 early_retire_seq = std::max(early_retire_seq, next_seq);
1679 }
1680
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001681 const auto perf_submit = LvlFindInChain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001682 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001683
locke-lunargd556cc32019-09-17 01:21:23 -06001684 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001685 RecordSubmitCommandBuffer(submission, submit->pCommandBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06001686 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001687 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1688 queue_state->submissions.emplace_back(std::move(submission));
1689 }
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001690
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001691 if (early_retire_seq) {
1692 RetireWorkOnQueue(queue_state, early_retire_seq);
1693 }
1694}
1695
1696void ValidationStateTracker::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1697 VkFence fence, VkResult result) {
1698 if (result != VK_SUCCESS) return;
1699 auto queue_state = GetQueueState(queue);
1700
1701 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
1702
1703 // Now process each individual submit
1704 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1705 CB_SUBMISSION submission;
1706 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1707 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
1708 for (uint32_t i = 0; i < submit->waitSemaphoreInfoCount; ++i) {
1709 const auto &sem_info = submit->pWaitSemaphoreInfos[i];
1710 RecordSubmitWaitSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1711 }
1712 bool retire_early = false;
1713 for (uint32_t i = 0; i < submit->signalSemaphoreInfoCount; ++i) {
1714 const auto &sem_info = submit->pSignalSemaphoreInfos[i];
1715 retire_early |= RecordSubmitSignalSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1716 }
1717 if (retire_early) {
1718 early_retire_seq = std::max(early_retire_seq, next_seq);
1719 }
1720 const auto perf_submit = lvl_find_in_chain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
1721 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
1722
1723 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1724 RecordSubmitCommandBuffer(submission, submit->pCommandBufferInfos[i].commandBuffer);
1725 }
1726 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1727 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001728 }
1729
1730 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001731 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001732 }
1733}
1734
1735void ValidationStateTracker::PostCallRecordAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
1736 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory,
1737 VkResult result) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001738 if (VK_SUCCESS != result) {
1739 return;
locke-lunargd556cc32019-09-17 01:21:23 -06001740 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001741 const auto &memory_type = phys_dev_mem_props.memoryTypes[pAllocateInfo->memoryTypeIndex];
1742 const auto &memory_heap = phys_dev_mem_props.memoryHeaps[memory_type.heapIndex];
1743 auto fake_address = fake_memory.Alloc(pAllocateInfo->allocationSize);
1744
1745 layer_data::optional<DedicatedBinding> dedicated_binding;
1746
1747 auto dedicated = LvlFindInChain<VkMemoryDedicatedAllocateInfo>(pAllocateInfo->pNext);
1748 if (dedicated) {
1749 if (dedicated->buffer) {
1750 const auto *buffer_state = GetBufferState(dedicated->buffer);
1751 assert(buffer_state);
1752 if (!buffer_state) {
1753 return;
1754 }
1755 dedicated_binding.emplace(dedicated->buffer, buffer_state->createInfo);
1756 } else if (dedicated->image) {
1757 const auto *image_state = GetImageState(dedicated->image);
1758 assert(image_state);
1759 if (!image_state) {
1760 return;
1761 }
1762 dedicated_binding.emplace(dedicated->image, image_state->createInfo);
1763 }
1764 }
1765 memObjMap[*pMemory] = std::make_shared<DEVICE_MEMORY_STATE>(*pMemory, pAllocateInfo, fake_address, memory_type, memory_heap,
1766 std::move(dedicated_binding));
locke-lunargd556cc32019-09-17 01:21:23 -06001767 return;
1768}
1769
1770void ValidationStateTracker::PreCallRecordFreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
1771 if (!mem) return;
1772 DEVICE_MEMORY_STATE *mem_info = GetDevMemState(mem);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001773 if (!mem_info) return;
locke-lunargd556cc32019-09-17 01:21:23 -06001774 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001775 mem_info->Destroy();
John Zulauf79952712020-04-07 11:25:54 -06001776 fake_memory.Free(mem_info->fake_base_address);
locke-lunargd556cc32019-09-17 01:21:23 -06001777 memObjMap.erase(mem);
1778}
1779
1780void ValidationStateTracker::PostCallRecordQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo,
1781 VkFence fence, VkResult result) {
1782 if (result != VK_SUCCESS) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001783 auto queue_state = GetQueueState(queue);
locke-lunargd556cc32019-09-17 01:21:23 -06001784
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001785 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, bindInfoCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001786
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001787 for (uint32_t bind_idx = 0; bind_idx < bindInfoCount; ++bind_idx) {
1788 const VkBindSparseInfo &bind_info = pBindInfo[bind_idx];
locke-lunargd556cc32019-09-17 01:21:23 -06001789 // Track objects tied to memory
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001790 for (uint32_t j = 0; j < bind_info.bufferBindCount; j++) {
1791 for (uint32_t k = 0; k < bind_info.pBufferBinds[j].bindCount; k++) {
1792 auto sparse_binding = bind_info.pBufferBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001793 auto buffer_state = GetBufferState(bind_info.pBufferBinds[j].buffer);
1794 auto mem_state = GetDevMemShared(sparse_binding.memory);
1795 if (buffer_state && mem_state) {
1796 buffer_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1797 }
locke-lunargd556cc32019-09-17 01:21:23 -06001798 }
1799 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001800 for (uint32_t j = 0; j < bind_info.imageOpaqueBindCount; j++) {
1801 for (uint32_t k = 0; k < bind_info.pImageOpaqueBinds[j].bindCount; k++) {
1802 auto sparse_binding = bind_info.pImageOpaqueBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001803 auto image_state = GetImageState(bind_info.pImageOpaqueBinds[j].image);
1804 auto mem_state = GetDevMemShared(sparse_binding.memory);
1805 if (image_state && mem_state) {
1806 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1807 }
locke-lunargd556cc32019-09-17 01:21:23 -06001808 }
1809 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001810 for (uint32_t j = 0; j < bind_info.imageBindCount; j++) {
1811 for (uint32_t k = 0; k < bind_info.pImageBinds[j].bindCount; k++) {
1812 auto sparse_binding = bind_info.pImageBinds[j].pBinds[k];
locke-lunargd556cc32019-09-17 01:21:23 -06001813 // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data
1814 VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001815 auto image_state = GetImageState(bind_info.pImageBinds[j].image);
1816 auto mem_state = GetDevMemShared(sparse_binding.memory);
1817 if (image_state && mem_state) {
1818 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, size);
1819 }
locke-lunargd556cc32019-09-17 01:21:23 -06001820 }
1821 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001822 CB_SUBMISSION submission;
1823 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001824 for (uint32_t i = 0; i < bind_info.waitSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001825 RecordSubmitWaitSemaphore(submission, queue, bind_info.pWaitSemaphores[i], 0, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001826 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001827 bool retire_early = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001828 for (uint32_t i = 0; i < bind_info.signalSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001829 retire_early |= RecordSubmitSignalSemaphore(submission, queue, bind_info.pSignalSemaphores[i], 0, next_seq);
1830 }
1831 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1832 if (retire_early) {
1833 early_retire_seq = std::max(early_retire_seq, queue_state->seq + queue_state->submissions.size() + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06001834 }
1835
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001836 submission.fence = bind_idx == (bindInfoCount - 1) ? fence : VK_NULL_HANDLE;
1837 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001838 }
1839
1840 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001841 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001842 }
1843}
1844
1845void ValidationStateTracker::PostCallRecordCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
1846 const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore,
1847 VkResult result) {
1848 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001849 semaphoreMap[*pSemaphore] = std::make_shared<SEMAPHORE_STATE>(*pSemaphore, LvlFindInChain<VkSemaphoreTypeCreateInfo>(pCreateInfo->pNext));
locke-lunargd556cc32019-09-17 01:21:23 -06001850}
1851
Mike Schuchardt2df08912020-12-15 16:28:09 -08001852void ValidationStateTracker::RecordImportSemaphoreState(VkSemaphore semaphore, VkExternalSemaphoreHandleTypeFlagBits handle_type,
1853 VkSemaphoreImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06001854 SEMAPHORE_STATE *sema_node = GetSemaphoreState(semaphore);
1855 if (sema_node && sema_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001856 if ((handle_type == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06001857 sema_node->scope == kSyncScopeInternal) {
1858 sema_node->scope = kSyncScopeExternalTemporary;
1859 } else {
1860 sema_node->scope = kSyncScopeExternalPermanent;
1861 }
1862 }
1863}
1864
Mike Schuchardt2df08912020-12-15 16:28:09 -08001865void ValidationStateTracker::PostCallRecordSignalSemaphoreKHR(VkDevice device, const VkSemaphoreSignalInfo *pSignalInfo,
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001866 VkResult result) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001867 auto *semaphore_state = GetSemaphoreState(pSignalInfo->semaphore);
1868 semaphore_state->payload = pSignalInfo->value;
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001869}
1870
locke-lunargd556cc32019-09-17 01:21:23 -06001871void ValidationStateTracker::RecordMappedMemory(VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, void **ppData) {
1872 auto mem_info = GetDevMemState(mem);
1873 if (mem_info) {
1874 mem_info->mapped_range.offset = offset;
1875 mem_info->mapped_range.size = size;
1876 mem_info->p_driver_data = *ppData;
1877 }
1878}
1879
1880void ValidationStateTracker::RetireFence(VkFence fence) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001881 auto fence_state = GetFenceState(fence);
1882 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1883 if (fence_state->signaler.first != VK_NULL_HANDLE) {
locke-lunargd556cc32019-09-17 01:21:23 -06001884 // Fence signaller is a queue -- use this as proof that prior operations on that queue have completed.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001885 RetireWorkOnQueue(GetQueueState(fence_state->signaler.first), fence_state->signaler.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001886 } else {
1887 // Fence signaller is the WSI. We're not tracking what the WSI op actually /was/ in CV yet, but we need to mark
1888 // the fence as retired.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001889 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001890 }
1891 }
1892}
1893
1894void ValidationStateTracker::PostCallRecordWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
1895 VkBool32 waitAll, uint64_t timeout, VkResult result) {
1896 if (VK_SUCCESS != result) return;
1897
1898 // When we know that all fences are complete we can clean/remove their CBs
1899 if ((VK_TRUE == waitAll) || (1 == fenceCount)) {
1900 for (uint32_t i = 0; i < fenceCount; i++) {
1901 RetireFence(pFences[i]);
1902 }
1903 }
1904 // NOTE : Alternate case not handled here is when some fences have completed. In
1905 // this case for app to guarantee which fences completed it will have to call
1906 // vkGetFenceStatus() at which point we'll clean/remove their CBs if complete.
1907}
1908
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001909void ValidationStateTracker::RetireTimelineSemaphore(VkSemaphore semaphore, uint64_t until_payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001910 auto semaphore_state = GetSemaphoreState(semaphore);
1911 if (semaphore_state) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001912 for (auto &pair : queueMap) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001913 QUEUE_STATE &queue_state = pair.second;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001914 uint64_t max_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001915 for (const auto &submission : queue_state.submissions) {
1916 for (const auto &signal_semaphore : submission.signalSemaphores) {
1917 if (signal_semaphore.semaphore == semaphore && signal_semaphore.payload <= until_payload) {
1918 if (signal_semaphore.seq > max_seq) {
1919 max_seq = signal_semaphore.seq;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001920 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001921 }
1922 }
1923 }
Tony-LunarG47d5e272020-04-07 15:35:55 -06001924 if (max_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001925 RetireWorkOnQueue(&queue_state, max_seq);
Tony-LunarG47d5e272020-04-07 15:35:55 -06001926 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001927 }
1928 }
1929}
1930
John Zulauff89de662020-04-13 18:57:34 -06001931void ValidationStateTracker::RecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1932 VkResult result) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001933 if (VK_SUCCESS != result) return;
1934
1935 for (uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++) {
1936 RetireTimelineSemaphore(pWaitInfo->pSemaphores[i], pWaitInfo->pValues[i]);
1937 }
1938}
1939
John Zulauff89de662020-04-13 18:57:34 -06001940void ValidationStateTracker::PostCallRecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1941 VkResult result) {
1942 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1943}
1944
1945void ValidationStateTracker::PostCallRecordWaitSemaphoresKHR(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo,
1946 uint64_t timeout, VkResult result) {
1947 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1948}
1949
Adrian Coca Lorentec7d76102020-09-28 13:58:16 +02001950void ValidationStateTracker::RecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1951 VkResult result) {
1952 if (VK_SUCCESS != result) return;
1953
1954 RetireTimelineSemaphore(semaphore, *pValue);
1955}
1956
1957void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1958 VkResult result) {
1959 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1960}
1961void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1962 VkResult result) {
1963 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1964}
1965
locke-lunargd556cc32019-09-17 01:21:23 -06001966void ValidationStateTracker::PostCallRecordGetFenceStatus(VkDevice device, VkFence fence, VkResult result) {
1967 if (VK_SUCCESS != result) return;
1968 RetireFence(fence);
1969}
1970
1971void ValidationStateTracker::RecordGetDeviceQueueState(uint32_t queue_family_index, VkQueue queue) {
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06001972 queueMap.emplace(queue, QUEUE_STATE(queue, queue_family_index));
locke-lunargd556cc32019-09-17 01:21:23 -06001973}
1974
1975void ValidationStateTracker::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
1976 VkQueue *pQueue) {
1977 RecordGetDeviceQueueState(queueFamilyIndex, *pQueue);
1978}
1979
1980void ValidationStateTracker::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
1981 RecordGetDeviceQueueState(pQueueInfo->queueFamilyIndex, *pQueue);
1982}
1983
1984void ValidationStateTracker::PostCallRecordQueueWaitIdle(VkQueue queue, VkResult result) {
1985 if (VK_SUCCESS != result) return;
1986 QUEUE_STATE *queue_state = GetQueueState(queue);
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001987 RetireWorkOnQueue(queue_state, queue_state->seq + queue_state->submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001988}
1989
1990void ValidationStateTracker::PostCallRecordDeviceWaitIdle(VkDevice device, VkResult result) {
1991 if (VK_SUCCESS != result) return;
1992 for (auto &queue : queueMap) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001993 RetireWorkOnQueue(&queue.second, queue.second.seq + queue.second.submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001994 }
1995}
1996
1997void ValidationStateTracker::PreCallRecordDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
1998 if (!fence) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001999 auto fence_state = GetFenceState(fence);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002000 fence_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002001 fenceMap.erase(fence);
2002}
2003
2004void ValidationStateTracker::PreCallRecordDestroySemaphore(VkDevice device, VkSemaphore semaphore,
2005 const VkAllocationCallbacks *pAllocator) {
2006 if (!semaphore) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002007 auto semaphore_state = GetSemaphoreState(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002008 semaphore_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002009 semaphoreMap.erase(semaphore);
2010}
2011
2012void ValidationStateTracker::PreCallRecordDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
2013 if (!event) return;
John Zulauf48057322020-12-02 11:59:31 -07002014 EVENT_STATE *event_state = Get<EVENT_STATE>(event);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002015 event_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002016 eventMap.erase(event);
2017}
2018
2019void ValidationStateTracker::PreCallRecordDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
2020 const VkAllocationCallbacks *pAllocator) {
2021 if (!queryPool) return;
2022 QUERY_POOL_STATE *qp_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002023 qp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002024 queryPoolMap.erase(queryPool);
2025}
2026
locke-lunargd556cc32019-09-17 01:21:23 -06002027void ValidationStateTracker::UpdateBindBufferMemoryState(VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memoryOffset) {
2028 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2029 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002030 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002031 auto mem_state = GetDevMemShared(mem);
2032 if (mem_state) {
2033 buffer_state->SetMemBinding(mem_state, memoryOffset);
2034 }
locke-lunargd556cc32019-09-17 01:21:23 -06002035 }
2036}
2037
2038void ValidationStateTracker::PostCallRecordBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
2039 VkDeviceSize memoryOffset, VkResult result) {
2040 if (VK_SUCCESS != result) return;
2041 UpdateBindBufferMemoryState(buffer, mem, memoryOffset);
2042}
2043
2044void ValidationStateTracker::PostCallRecordBindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002045 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002046 for (uint32_t i = 0; i < bindInfoCount; i++) {
2047 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2048 }
2049}
2050
2051void ValidationStateTracker::PostCallRecordBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002052 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002053 for (uint32_t i = 0; i < bindInfoCount; i++) {
2054 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2055 }
2056}
2057
Spencer Fricke6c127102020-04-16 06:25:20 -07002058void ValidationStateTracker::RecordGetBufferMemoryRequirementsState(VkBuffer buffer) {
locke-lunargd556cc32019-09-17 01:21:23 -06002059 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2060 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002061 buffer_state->memory_requirements_checked = true;
2062 }
2063}
2064
2065void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
2066 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002067 RecordGetBufferMemoryRequirementsState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002068}
2069
2070void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002071 const VkBufferMemoryRequirementsInfo2 *pInfo,
2072 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002073 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002074}
2075
2076void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2KHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002077 const VkBufferMemoryRequirementsInfo2 *pInfo,
2078 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002079 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002080}
2081
Spencer Fricke6c127102020-04-16 06:25:20 -07002082void ValidationStateTracker::RecordGetImageMemoryRequirementsState(VkImage image, const VkImageMemoryRequirementsInfo2 *pInfo) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002083 const VkImagePlaneMemoryRequirementsInfo *plane_info =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002084 (pInfo == nullptr) ? nullptr : LvlFindInChain<VkImagePlaneMemoryRequirementsInfo>(pInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06002085 IMAGE_STATE *image_state = GetImageState(image);
2086 if (image_state) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002087 if (plane_info != nullptr) {
2088 // Multi-plane image
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002089 if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_0_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002090 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002091 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_1_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002092 image_state->memory_requirements_checked[1] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002093 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_2_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002094 image_state->memory_requirements_checked[2] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002095 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002096 } else if (!image_state->disjoint) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002097 // Single Plane image
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002098 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002099 }
locke-lunargd556cc32019-09-17 01:21:23 -06002100 }
2101}
2102
2103void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements(VkDevice device, VkImage image,
2104 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002105 RecordGetImageMemoryRequirementsState(image, nullptr);
locke-lunargd556cc32019-09-17 01:21:23 -06002106}
2107
2108void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo,
2109 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002110 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002111}
2112
2113void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2KHR(VkDevice device,
2114 const VkImageMemoryRequirementsInfo2 *pInfo,
2115 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002116 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002117}
2118
2119static void RecordGetImageSparseMemoryRequirementsState(IMAGE_STATE *image_state,
2120 VkSparseImageMemoryRequirements *sparse_image_memory_requirements) {
2121 image_state->sparse_requirements.emplace_back(*sparse_image_memory_requirements);
2122 if (sparse_image_memory_requirements->formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) {
2123 image_state->sparse_metadata_required = true;
2124 }
2125}
2126
2127void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements(
2128 VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
2129 VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
2130 auto image_state = GetImageState(image);
2131 image_state->get_sparse_reqs_called = true;
2132 if (!pSparseMemoryRequirements) return;
2133 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2134 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i]);
2135 }
2136}
2137
2138void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002139 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2140 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002141 auto image_state = GetImageState(pInfo->image);
2142 image_state->get_sparse_reqs_called = true;
2143 if (!pSparseMemoryRequirements) return;
2144 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2145 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2146 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2147 }
2148}
2149
2150void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002151 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2152 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002153 auto image_state = GetImageState(pInfo->image);
2154 image_state->get_sparse_reqs_called = true;
2155 if (!pSparseMemoryRequirements) return;
2156 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2157 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2158 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2159 }
2160}
2161
2162void ValidationStateTracker::PreCallRecordDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
2163 const VkAllocationCallbacks *pAllocator) {
2164 if (!shaderModule) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002165 auto shader_module_state = GetShaderModuleState(shaderModule);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002166 shader_module_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002167 shaderModuleMap.erase(shaderModule);
2168}
2169
2170void ValidationStateTracker::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline,
2171 const VkAllocationCallbacks *pAllocator) {
2172 if (!pipeline) return;
2173 PIPELINE_STATE *pipeline_state = GetPipelineState(pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06002174 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002175 pipeline_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002176 pipelineMap.erase(pipeline);
2177}
2178
2179void ValidationStateTracker::PreCallRecordDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
2180 const VkAllocationCallbacks *pAllocator) {
2181 if (!pipelineLayout) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002182 auto pipeline_layout_state = GetPipelineLayout(pipelineLayout);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002183 pipeline_layout_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002184 pipelineLayoutMap.erase(pipelineLayout);
2185}
2186
2187void ValidationStateTracker::PreCallRecordDestroySampler(VkDevice device, VkSampler sampler,
2188 const VkAllocationCallbacks *pAllocator) {
2189 if (!sampler) return;
2190 SAMPLER_STATE *sampler_state = GetSamplerState(sampler);
locke-lunargd556cc32019-09-17 01:21:23 -06002191 // Any bound cmd buffers are now invalid
2192 if (sampler_state) {
Yuly Novikov424cdd52020-05-26 16:45:12 -04002193 if (sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2194 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
2195 custom_border_color_sampler_count--;
2196 }
2197
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002198 sampler_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002199 }
2200 samplerMap.erase(sampler);
2201}
2202
2203void ValidationStateTracker::PreCallRecordDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
2204 const VkAllocationCallbacks *pAllocator) {
2205 if (!descriptorSetLayout) return;
2206 auto layout_it = descriptorSetLayoutMap.find(descriptorSetLayout);
2207 if (layout_it != descriptorSetLayoutMap.end()) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002208 layout_it->second.get()->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002209 descriptorSetLayoutMap.erase(layout_it);
2210 }
2211}
2212
2213void ValidationStateTracker::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2214 const VkAllocationCallbacks *pAllocator) {
2215 if (!descriptorPool) return;
2216 DESCRIPTOR_POOL_STATE *desc_pool_state = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002217 if (desc_pool_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002218 // Free sets that were in this pool
John Zulauf79f06582021-02-27 18:38:39 -07002219 for (auto *ds : desc_pool_state->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002220 FreeDescriptorSet(ds);
2221 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002222 desc_pool_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002223 descriptorPoolMap.erase(descriptorPool);
2224 }
2225}
2226
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002227// 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 -06002228void ValidationStateTracker::FreeCommandBufferStates(COMMAND_POOL_STATE *pool_state, const uint32_t command_buffer_count,
2229 const VkCommandBuffer *command_buffers) {
2230 for (uint32_t i = 0; i < command_buffer_count; i++) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002231 auto cb_state = Get<CMD_BUFFER_STATE>(command_buffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002232 // Remove references to command buffer's state and delete
2233 if (cb_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002234 cb_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002235 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002236 // Remove CBState from CB map
2237 pool_state->commandBuffers.erase(command_buffers[i]);
2238 commandBufferMap.erase(command_buffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002239 }
2240}
2241
2242void ValidationStateTracker::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
2243 uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002244 auto pool = GetCommandPoolState(commandPool);
2245 FreeCommandBufferStates(pool, commandBufferCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06002246}
2247
2248void ValidationStateTracker::PostCallRecordCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
2249 const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool,
2250 VkResult result) {
2251 if (VK_SUCCESS != result) return;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06002252 auto queue_flags = GetPhysicalDeviceState()->queue_family_properties[pCreateInfo->queueFamilyIndex].queueFlags;
2253 commandPoolMap[*pCommandPool] = std::make_shared<COMMAND_POOL_STATE>(*pCommandPool, pCreateInfo, queue_flags);
locke-lunargd556cc32019-09-17 01:21:23 -06002254}
2255
2256void ValidationStateTracker::PostCallRecordCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
2257 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool,
2258 VkResult result) {
2259 if (VK_SUCCESS != result) return;
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002260
2261 uint32_t index_count = 0, n_perf_pass = 0;
2262 bool has_cb = false, has_rb = false;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002263 if (pCreateInfo->queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002264 const auto *perf = LvlFindInChain<VkQueryPoolPerformanceCreateInfoKHR>(pCreateInfo->pNext);
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002265 index_count = perf->counterIndexCount;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002266
Mark Lobodzinski7e948e42020-09-09 10:23:36 -06002267 const QUEUE_FAMILY_PERF_COUNTERS &counters = *physical_device_state->perf_counters[perf->queueFamilyIndex];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002268 for (uint32_t i = 0; i < perf->counterIndexCount; i++) {
2269 const auto &counter = counters.counters[perf->pCounterIndices[i]];
2270 switch (counter.scope) {
2271 case VK_QUERY_SCOPE_COMMAND_BUFFER_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002272 has_cb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002273 break;
2274 case VK_QUERY_SCOPE_RENDER_PASS_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002275 has_rb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002276 break;
2277 default:
2278 break;
2279 }
2280 }
2281
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002282 DispatchGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physical_device_state->phys_device, perf, &n_perf_pass);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002283 }
2284
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002285 queryPoolMap[*pQueryPool] =
2286 std::make_shared<QUERY_POOL_STATE>(*pQueryPool, pCreateInfo, index_count, n_perf_pass, has_cb, has_rb);
locke-lunargd556cc32019-09-17 01:21:23 -06002287
2288 QueryObject query_obj{*pQueryPool, 0u};
2289 for (uint32_t i = 0; i < pCreateInfo->queryCount; ++i) {
2290 query_obj.query = i;
2291 queryToStateMap[query_obj] = QUERYSTATE_UNKNOWN;
2292 }
2293}
2294
2295void ValidationStateTracker::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
2296 const VkAllocationCallbacks *pAllocator) {
2297 if (!commandPool) return;
2298 COMMAND_POOL_STATE *cp_state = GetCommandPoolState(commandPool);
2299 // Remove cmdpool from cmdpoolmap, after freeing layer data for the command buffers
2300 // "When a pool is destroyed, all command buffers allocated from the pool are freed."
2301 if (cp_state) {
2302 // Create a vector, as FreeCommandBufferStates deletes from cp_state->commandBuffers during iteration.
2303 std::vector<VkCommandBuffer> cb_vec{cp_state->commandBuffers.begin(), cp_state->commandBuffers.end()};
2304 FreeCommandBufferStates(cp_state, static_cast<uint32_t>(cb_vec.size()), cb_vec.data());
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002305 cp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002306 commandPoolMap.erase(commandPool);
2307 }
2308}
2309
2310void ValidationStateTracker::PostCallRecordResetCommandPool(VkDevice device, VkCommandPool commandPool,
2311 VkCommandPoolResetFlags flags, VkResult result) {
2312 if (VK_SUCCESS != result) return;
2313 // Reset all of the CBs allocated from this pool
2314 auto command_pool_state = GetCommandPoolState(commandPool);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002315 for (auto cmd_buffer : command_pool_state->commandBuffers) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002316 auto cb_state = Get<CMD_BUFFER_STATE>(cmd_buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002317 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002318 }
2319}
2320
2321void ValidationStateTracker::PostCallRecordResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
2322 VkResult result) {
2323 for (uint32_t i = 0; i < fenceCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002324 auto fence_state = GetFenceState(pFences[i]);
2325 if (fence_state) {
2326 if (fence_state->scope == kSyncScopeInternal) {
2327 fence_state->state = FENCE_UNSIGNALED;
2328 } else if (fence_state->scope == kSyncScopeExternalTemporary) {
2329 fence_state->scope = kSyncScopeInternal;
locke-lunargd556cc32019-09-17 01:21:23 -06002330 }
2331 }
2332 }
2333}
2334
locke-lunargd556cc32019-09-17 01:21:23 -06002335void ValidationStateTracker::PreCallRecordDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
2336 const VkAllocationCallbacks *pAllocator) {
2337 if (!framebuffer) return;
2338 FRAMEBUFFER_STATE *framebuffer_state = GetFramebufferState(framebuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002339 framebuffer_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002340 frameBufferMap.erase(framebuffer);
2341}
2342
2343void ValidationStateTracker::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
2344 const VkAllocationCallbacks *pAllocator) {
2345 if (!renderPass) return;
2346 RENDER_PASS_STATE *rp_state = GetRenderPassState(renderPass);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002347 rp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002348 renderPassMap.erase(renderPass);
2349}
2350
2351void ValidationStateTracker::PostCallRecordCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
2352 const VkAllocationCallbacks *pAllocator, VkFence *pFence, VkResult result) {
2353 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002354 fenceMap[*pFence] = std::make_shared<FENCE_STATE>(*pFence, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002355}
2356
2357bool ValidationStateTracker::PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2358 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2359 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002360 void *cgpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002361 // Set up the state that CoreChecks, gpu_validation and later StateTracker Record will use.
2362 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2363 cgpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2364 cgpl_state->pipe_state.reserve(count);
2365 for (uint32_t i = 0; i < count; i++) {
Jeremy Gebben11af9792021-08-20 10:20:09 -06002366 cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i],
2367 GetRenderPassShared(pCreateInfos[i].renderPass),
2368 GetPipelineLayoutShared(pCreateInfos[i].layout)));
locke-lunargd556cc32019-09-17 01:21:23 -06002369 }
2370 return false;
2371}
2372
2373void ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2374 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2375 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2376 VkResult result, void *cgpl_state_data) {
2377 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2378 // This API may create pipelines regardless of the return value
2379 for (uint32_t i = 0; i < count; i++) {
2380 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002381 (cgpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002382 pipelineMap[pPipelines[i]] = std::move((cgpl_state->pipe_state)[i]);
2383 }
2384 }
2385 cgpl_state->pipe_state.clear();
2386}
2387
2388bool ValidationStateTracker::PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2389 const VkComputePipelineCreateInfo *pCreateInfos,
2390 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002391 void *ccpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002392 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2393 ccpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2394 ccpl_state->pipe_state.reserve(count);
2395 for (uint32_t i = 0; i < count; i++) {
2396 // Create and initialize internal tracking data structure
Jeremy Gebben11af9792021-08-20 10:20:09 -06002397 ccpl_state->pipe_state.push_back(
2398 std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i], GetPipelineLayoutShared(pCreateInfos[i].layout)));
locke-lunargd556cc32019-09-17 01:21:23 -06002399 }
2400 return false;
2401}
2402
2403void ValidationStateTracker::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2404 const VkComputePipelineCreateInfo *pCreateInfos,
2405 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2406 VkResult result, void *ccpl_state_data) {
2407 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2408
2409 // This API may create pipelines regardless of the return value
2410 for (uint32_t i = 0; i < count; i++) {
2411 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002412 (ccpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002413 pipelineMap[pPipelines[i]] = std::move((ccpl_state->pipe_state)[i]);
2414 }
2415 }
2416 ccpl_state->pipe_state.clear();
2417}
2418
2419bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache,
2420 uint32_t count,
2421 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2422 const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002423 VkPipeline *pPipelines, void *crtpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002424 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2425 crtpl_state->pipe_state.reserve(count);
2426 for (uint32_t i = 0; i < count; i++) {
2427 // Create and initialize internal tracking data structure
Jeremy Gebben11af9792021-08-20 10:20:09 -06002428 crtpl_state->pipe_state.push_back(
2429 std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i], GetPipelineLayoutShared(pCreateInfos[i].layout)));
locke-lunargd556cc32019-09-17 01:21:23 -06002430 }
2431 return false;
2432}
2433
2434void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(
2435 VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2436 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines, VkResult result, void *crtpl_state_data) {
2437 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2438 // This API may create pipelines regardless of the return value
2439 for (uint32_t i = 0; i < count; i++) {
2440 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002441 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002442 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2443 }
2444 }
2445 crtpl_state->pipe_state.clear();
2446}
2447
sourav parmarcd5fb182020-07-17 12:58:44 -07002448bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2449 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002450 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2451 const VkAllocationCallbacks *pAllocator,
2452 VkPipeline *pPipelines, void *crtpl_state_data) const {
2453 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2454 crtpl_state->pipe_state.reserve(count);
2455 for (uint32_t i = 0; i < count; i++) {
2456 // Create and initialize internal tracking data structure
Jeremy Gebben11af9792021-08-20 10:20:09 -06002457 crtpl_state->pipe_state.push_back(
2458 std::make_shared<PIPELINE_STATE>(this, &pCreateInfos[i], GetPipelineLayoutShared(pCreateInfos[i].layout)));
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002459 }
2460 return false;
2461}
2462
sourav parmarcd5fb182020-07-17 12:58:44 -07002463void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2464 VkPipelineCache pipelineCache, uint32_t count,
2465 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2466 const VkAllocationCallbacks *pAllocator,
2467 VkPipeline *pPipelines, VkResult result,
2468 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002469 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2470 // This API may create pipelines regardless of the return value
2471 for (uint32_t i = 0; i < count; i++) {
2472 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002473 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002474 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2475 }
2476 }
2477 crtpl_state->pipe_state.clear();
2478}
2479
locke-lunargd556cc32019-09-17 01:21:23 -06002480void ValidationStateTracker::PostCallRecordCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
2481 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler,
2482 VkResult result) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002483 samplerMap[*pSampler] = std::make_shared<SAMPLER_STATE>(pSampler, pCreateInfo);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002484 if (pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2485 pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
Tony-LunarG7337b312020-04-15 16:40:25 -06002486 custom_border_color_sampler_count++;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002487 }
locke-lunargd556cc32019-09-17 01:21:23 -06002488}
2489
2490void ValidationStateTracker::PostCallRecordCreateDescriptorSetLayout(VkDevice device,
2491 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
2492 const VkAllocationCallbacks *pAllocator,
2493 VkDescriptorSetLayout *pSetLayout, VkResult result) {
2494 if (VK_SUCCESS != result) return;
2495 descriptorSetLayoutMap[*pSetLayout] = std::make_shared<cvdescriptorset::DescriptorSetLayout>(pCreateInfo, *pSetLayout);
2496}
2497
locke-lunargd556cc32019-09-17 01:21:23 -06002498void ValidationStateTracker::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
2499 const VkAllocationCallbacks *pAllocator,
2500 VkPipelineLayout *pPipelineLayout, VkResult result) {
2501 if (VK_SUCCESS != result) return;
2502
Jeremy Gebbene6e45542021-08-05 16:39:49 -06002503 pipelineLayoutMap[*pPipelineLayout] = std::make_shared<PIPELINE_LAYOUT_STATE>(this, *pPipelineLayout, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002504}
2505
2506void ValidationStateTracker::PostCallRecordCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
2507 const VkAllocationCallbacks *pAllocator,
2508 VkDescriptorPool *pDescriptorPool, VkResult result) {
2509 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002510 descriptorPoolMap[*pDescriptorPool] = std::make_shared<DESCRIPTOR_POOL_STATE>(*pDescriptorPool, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002511}
2512
2513void ValidationStateTracker::PostCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2514 VkDescriptorPoolResetFlags flags, VkResult result) {
2515 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002516 DESCRIPTOR_POOL_STATE *pool = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002517 // TODO: validate flags
2518 // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
John Zulauf79f06582021-02-27 18:38:39 -07002519 for (auto *ds : pool->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002520 FreeDescriptorSet(ds);
2521 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002522 pool->sets.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06002523 // Reset available count for each type and available sets for this pool
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002524 for (auto it = pool->availableDescriptorTypeCount.begin(); it != pool->availableDescriptorTypeCount.end(); ++it) {
2525 pool->availableDescriptorTypeCount[it->first] = pool->maxDescriptorTypeCount[it->first];
locke-lunargd556cc32019-09-17 01:21:23 -06002526 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002527 pool->availableSets = pool->maxSets;
locke-lunargd556cc32019-09-17 01:21:23 -06002528}
2529
2530bool ValidationStateTracker::PreCallValidateAllocateDescriptorSets(VkDevice device,
2531 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002532 VkDescriptorSet *pDescriptorSets, void *ads_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002533 // Always update common data
2534 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2535 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2536 UpdateAllocateDescriptorSetsData(pAllocateInfo, ads_state);
2537
2538 return false;
2539}
2540
2541// Allocation state was good and call down chain was made so update state based on allocating descriptor sets
2542void ValidationStateTracker::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
2543 VkDescriptorSet *pDescriptorSets, VkResult result,
2544 void *ads_state_data) {
2545 if (VK_SUCCESS != result) return;
2546 // All the updates are contained in a single cvdescriptorset function
2547 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2548 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2549 PerformAllocateDescriptorSets(pAllocateInfo, pDescriptorSets, ads_state);
2550}
2551
2552void ValidationStateTracker::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count,
2553 const VkDescriptorSet *pDescriptorSets) {
2554 DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(descriptorPool);
2555 // Update available descriptor sets in pool
2556 pool_state->availableSets += count;
2557
2558 // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
2559 for (uint32_t i = 0; i < count; ++i) {
2560 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
2561 auto descriptor_set = setMap[pDescriptorSets[i]].get();
2562 uint32_t type_index = 0, descriptor_count = 0;
2563 for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) {
2564 type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j));
2565 descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j);
2566 pool_state->availableDescriptorTypeCount[type_index] += descriptor_count;
2567 }
2568 FreeDescriptorSet(descriptor_set);
2569 pool_state->sets.erase(descriptor_set);
2570 }
2571 }
2572}
2573
2574void ValidationStateTracker::PreCallRecordUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
2575 const VkWriteDescriptorSet *pDescriptorWrites,
2576 uint32_t descriptorCopyCount,
2577 const VkCopyDescriptorSet *pDescriptorCopies) {
2578 cvdescriptorset::PerformUpdateDescriptorSets(this, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
2579 pDescriptorCopies);
2580}
2581
2582void ValidationStateTracker::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo,
2583 VkCommandBuffer *pCommandBuffer, VkResult result) {
2584 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002585 auto pool = GetCommandPoolShared(pCreateInfo->commandPool);
2586 if (pool) {
locke-lunargd556cc32019-09-17 01:21:23 -06002587 for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) {
2588 // Add command buffer to its commandPool map
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002589 pool->commandBuffers.insert(pCommandBuffer[i]);
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002590 commandBufferMap[pCommandBuffer[i]] = CreateCmdBufferState(pCommandBuffer[i], pCreateInfo, pool);
locke-lunargfc78e932020-11-19 17:06:24 -07002591 }
2592 }
2593}
2594
locke-lunargd556cc32019-09-17 01:21:23 -06002595void ValidationStateTracker::PreCallRecordBeginCommandBuffer(VkCommandBuffer commandBuffer,
2596 const VkCommandBufferBeginInfo *pBeginInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002597 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002598 if (!cb_state) return;
locke-lunargfc78e932020-11-19 17:06:24 -07002599
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002600 cb_state->Begin(pBeginInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002601}
2602
2603void ValidationStateTracker::PostCallRecordEndCommandBuffer(VkCommandBuffer commandBuffer, VkResult result) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002604 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002605 if (!cb_state) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002606
2607 cb_state->End(result);
locke-lunargd556cc32019-09-17 01:21:23 -06002608}
2609
2610void ValidationStateTracker::PostCallRecordResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags,
2611 VkResult result) {
2612 if (VK_SUCCESS == result) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002613 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002614 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002615 }
2616}
2617
2618CBStatusFlags MakeStaticStateMask(VkPipelineDynamicStateCreateInfo const *ds) {
2619 // initially assume everything is static state
2620 CBStatusFlags flags = CBSTATUS_ALL_STATE_SET;
2621
2622 if (ds) {
2623 for (uint32_t i = 0; i < ds->dynamicStateCount; i++) {
locke-lunarg4189aa22020-10-21 00:23:48 -06002624 flags &= ~ConvertToCBStatusFlagBits(ds->pDynamicStates[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002625 }
2626 }
locke-lunargd556cc32019-09-17 01:21:23 -06002627 return flags;
2628}
2629
2630// Validation cache:
2631// CV is the bottommost implementor of this extension. Don't pass calls down.
locke-lunargd556cc32019-09-17 01:21:23 -06002632
2633void ValidationStateTracker::PreCallRecordCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
2634 VkPipeline pipeline) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002635 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002636 assert(cb_state);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002637 cb_state->RecordCmd(CMD_BINDPIPELINE);
locke-lunargd556cc32019-09-17 01:21:23 -06002638
2639 auto pipe_state = GetPipelineState(pipeline);
2640 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
Jeremy Gebben11af9792021-08-20 10:20:09 -06002641 const auto &create_info = pipe_state->create_info.graphics;
2642 bool rasterization_enabled = VK_FALSE == create_info.pRasterizationState->rasterizerDiscardEnable;
2643 const auto *viewport_state = create_info.pViewportState;
2644 const auto *dynamic_state = create_info.pDynamicState;
locke-lunargd556cc32019-09-17 01:21:23 -06002645 cb_state->status &= ~cb_state->static_status;
Jeremy Gebben11af9792021-08-20 10:20:09 -06002646 cb_state->static_status = MakeStaticStateMask(dynamic_state->ptr());
locke-lunargd556cc32019-09-17 01:21:23 -06002647 cb_state->status |= cb_state->static_status;
locke-lunarg4189aa22020-10-21 00:23:48 -06002648 cb_state->dynamic_status = CBSTATUS_ALL_STATE_SET & (~cb_state->static_status);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002649
2650 // Used to calculate CMD_BUFFER_STATE::usedViewportScissorCount upon draw command with this graphics pipeline.
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002651 // If rasterization disabled (no viewport/scissors used), or the actual number of viewports/scissors is dynamic (unknown at
2652 // this time), then these are set to 0 to disable this checking.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002653 auto has_dynamic_viewport_count = cb_state->dynamic_status & CBSTATUS_VIEWPORT_WITH_COUNT_SET;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002654 auto has_dynamic_scissor_count = cb_state->dynamic_status & CBSTATUS_SCISSOR_WITH_COUNT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002655 cb_state->pipelineStaticViewportCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002656 has_dynamic_viewport_count || !rasterization_enabled ? 0 : viewport_state->viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002657 cb_state->pipelineStaticScissorCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002658 has_dynamic_scissor_count || !rasterization_enabled ? 0 : viewport_state->scissorCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002659
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002660 // Trash dynamic viewport/scissor state if pipeline defines static state and enabled rasterization.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002661 // akeley98 NOTE: There's a bit of an ambiguity in the spec, whether binding such a pipeline overwrites
2662 // the entire viewport (scissor) array, or only the subsection defined by the viewport (scissor) count.
2663 // I am taking the latter interpretation based on the implementation details of NVIDIA's Vulkan driver.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002664 if (!has_dynamic_viewport_count) {
2665 cb_state->trashedViewportCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002666 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_VIEWPORT_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002667 cb_state->trashedViewportMask |= (uint32_t(1) << viewport_state->viewportCount) - 1u;
2668 // should become = ~uint32_t(0) if the other interpretation is correct.
2669 }
2670 }
2671 if (!has_dynamic_scissor_count) {
2672 cb_state->trashedScissorCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002673 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_SCISSOR_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002674 cb_state->trashedScissorMask |= (uint32_t(1) << viewport_state->scissorCount) - 1u;
2675 // should become = ~uint32_t(0) if the other interpretation is correct.
2676 }
2677 }
locke-lunargd556cc32019-09-17 01:21:23 -06002678 }
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002679 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
2680 cb_state->lastBound[lv_bind_point].pipeline_state = pipe_state;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002681 if (!disabled[command_buffer_state]) {
2682 cb_state->AddChild(pipe_state);
2683 }
locke-lunargb8be8222020-10-20 00:34:37 -06002684 for (auto &slot : pipe_state->active_slots) {
2685 for (auto &req : slot.second) {
2686 for (auto &sampler : req.second.samplers_used_by_image) {
2687 for (auto &des : sampler) {
2688 des.second = nullptr;
2689 }
2690 }
2691 }
2692 }
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06002693 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
locke-lunargd556cc32019-09-17 01:21:23 -06002694}
2695
2696void ValidationStateTracker::PreCallRecordCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2697 uint32_t viewportCount, const VkViewport *pViewports) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002698 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002699 cb_state->RecordStateCmd(CMD_SETVIEWPORT, CBSTATUS_VIEWPORT_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002700 uint32_t bits = ((1u << viewportCount) - 1u) << firstViewport;
2701 cb_state->viewportMask |= bits;
2702 cb_state->trashedViewportMask &= ~bits;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002703
2704 cb_state->dynamicViewports.resize(std::max(size_t(firstViewport + viewportCount), cb_state->dynamicViewports.size()));
2705 for (size_t i = 0; i < viewportCount; ++i) {
2706 cb_state->dynamicViewports[firstViewport + i] = pViewports[i];
2707 }
locke-lunargd556cc32019-09-17 01:21:23 -06002708}
2709
2710void ValidationStateTracker::PreCallRecordCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
2711 uint32_t exclusiveScissorCount,
2712 const VkRect2D *pExclusiveScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002713 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002714 cb_state->RecordStateCmd(CMD_SETEXCLUSIVESCISSORNV, CBSTATUS_EXCLUSIVE_SCISSOR_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002715 // TODO: We don't have VUIDs for validating that all exclusive scissors have been set.
2716 // cb_state->exclusiveScissorMask |= ((1u << exclusiveScissorCount) - 1u) << firstExclusiveScissor;
locke-lunargd556cc32019-09-17 01:21:23 -06002717}
2718
2719void ValidationStateTracker::PreCallRecordCmdBindShadingRateImageNV(VkCommandBuffer commandBuffer, VkImageView imageView,
2720 VkImageLayout imageLayout) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002721 if (disabled[command_buffer_state]) return;
2722
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002723 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002724 cb_state->RecordCmd(CMD_BINDSHADINGRATEIMAGENV);
locke-lunargd556cc32019-09-17 01:21:23 -06002725
2726 if (imageView != VK_NULL_HANDLE) {
2727 auto view_state = GetImageViewState(imageView);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002728 cb_state->AddChild(view_state);
locke-lunargd556cc32019-09-17 01:21:23 -06002729 }
2730}
2731
2732void ValidationStateTracker::PreCallRecordCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2733 uint32_t viewportCount,
2734 const VkShadingRatePaletteNV *pShadingRatePalettes) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002735 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002736 cb_state->RecordStateCmd(CMD_SETVIEWPORTSHADINGRATEPALETTENV, CBSTATUS_SHADING_RATE_PALETTE_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002737 // TODO: We don't have VUIDs for validating that all shading rate palettes have been set.
2738 // cb_state->shadingRatePaletteMask |= ((1u << viewportCount) - 1u) << firstViewport;
locke-lunargd556cc32019-09-17 01:21:23 -06002739}
2740
2741void ValidationStateTracker::PostCallRecordCreateAccelerationStructureNV(VkDevice device,
2742 const VkAccelerationStructureCreateInfoNV *pCreateInfo,
2743 const VkAllocationCallbacks *pAllocator,
2744 VkAccelerationStructureNV *pAccelerationStructure,
2745 VkResult result) {
2746 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002747 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE>(*pAccelerationStructure, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002748
2749 // Query the requirements in case the application doesn't (to avoid bind/validation time query)
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002750 auto as_memory_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002751 as_memory_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002752 as_memory_requirements_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002753 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &as_memory_requirements_info, &as_state->memory_requirements);
2754
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002755 auto scratch_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002756 scratch_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002757 scratch_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002758 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &scratch_memory_req_info,
2759 &as_state->build_scratch_memory_requirements);
2760
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002761 auto update_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002762 update_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002763 update_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002764 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &update_memory_req_info,
2765 &as_state->update_scratch_memory_requirements);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002766 as_state->allocator = pAllocator;
locke-lunargd556cc32019-09-17 01:21:23 -06002767 accelerationStructureMap[*pAccelerationStructure] = std::move(as_state);
2768}
2769
Jeff Bolz95176d02020-04-01 00:36:16 -05002770void ValidationStateTracker::PostCallRecordCreateAccelerationStructureKHR(VkDevice device,
2771 const VkAccelerationStructureCreateInfoKHR *pCreateInfo,
2772 const VkAllocationCallbacks *pAllocator,
2773 VkAccelerationStructureKHR *pAccelerationStructure,
2774 VkResult result) {
2775 if (VK_SUCCESS != result) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07002776 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE_KHR>(*pAccelerationStructure, pCreateInfo);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002777 as_state->allocator = pAllocator;
sourav parmarcd5fb182020-07-17 12:58:44 -07002778 accelerationStructureMap_khr[*pAccelerationStructure] = std::move(as_state);
Jeff Bolz95176d02020-04-01 00:36:16 -05002779}
2780
sourav parmarcd5fb182020-07-17 12:58:44 -07002781void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresKHR(
2782 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2783 const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002784 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmarcd5fb182020-07-17 12:58:44 -07002785 if (cb_state == nullptr) {
2786 return;
2787 }
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002788 cb_state->RecordCmd(CMD_BUILDACCELERATIONSTRUCTURESKHR);
sourav parmarcd5fb182020-07-17 12:58:44 -07002789 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002790 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002791 if (dst_as_state != nullptr) {
2792 dst_as_state->built = true;
2793 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002794 if (!disabled[command_buffer_state]) {
2795 cb_state->AddChild(dst_as_state);
2796 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002797 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002798 if (!disabled[command_buffer_state]) {
2799 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2800 if (src_as_state != nullptr) {
2801 cb_state->AddChild(src_as_state);
2802 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002803 }
2804 }
2805 cb_state->hasBuildAccelerationStructureCmd = true;
2806}
2807
2808void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresIndirectKHR(
2809 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2810 const VkDeviceAddress *pIndirectDeviceAddresses, const uint32_t *pIndirectStrides,
2811 const uint32_t *const *ppMaxPrimitiveCounts) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002812 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmarcd5fb182020-07-17 12:58:44 -07002813 if (cb_state == nullptr) {
2814 return;
2815 }
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002816 cb_state->RecordCmd(CMD_BUILDACCELERATIONSTRUCTURESINDIRECTKHR);
sourav parmarcd5fb182020-07-17 12:58:44 -07002817 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002818 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002819 if (dst_as_state != nullptr) {
2820 dst_as_state->built = true;
2821 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002822 if (!disabled[command_buffer_state]) {
2823 cb_state->AddChild(dst_as_state);
2824 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002825 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002826 if (!disabled[command_buffer_state]) {
2827 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2828 if (src_as_state != nullptr) {
2829 cb_state->AddChild(src_as_state);
2830 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002831 }
2832 }
2833 cb_state->hasBuildAccelerationStructureCmd = true;
2834}
locke-lunargd556cc32019-09-17 01:21:23 -06002835void ValidationStateTracker::PostCallRecordGetAccelerationStructureMemoryRequirementsNV(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002836 VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV *pInfo, VkMemoryRequirements2 *pMemoryRequirements) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002837 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(pInfo->accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002838 if (as_state != nullptr) {
2839 if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV) {
2840 as_state->memory_requirements = *pMemoryRequirements;
2841 as_state->memory_requirements_checked = true;
2842 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV) {
2843 as_state->build_scratch_memory_requirements = *pMemoryRequirements;
2844 as_state->build_scratch_memory_requirements_checked = true;
2845 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV) {
2846 as_state->update_scratch_memory_requirements = *pMemoryRequirements;
2847 as_state->update_scratch_memory_requirements_checked = true;
2848 }
2849 }
2850}
2851
sourav parmarcd5fb182020-07-17 12:58:44 -07002852void ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(
2853 VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002854 if (VK_SUCCESS != result) return;
2855 for (uint32_t i = 0; i < bindInfoCount; i++) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002856 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
locke-lunargd556cc32019-09-17 01:21:23 -06002857
sourav parmarcd5fb182020-07-17 12:58:44 -07002858 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(info.accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002859 if (as_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002860 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002861 auto mem_state = GetDevMemShared(info.memory);
2862 if (mem_state) {
2863 as_state->SetMemBinding(mem_state, info.memoryOffset);
2864 }
locke-lunargd556cc32019-09-17 01:21:23 -06002865
2866 // GPU validation of top level acceleration structure building needs acceleration structure handles.
Jeff Bolz95176d02020-04-01 00:36:16 -05002867 // XXX TODO: Query device address for KHR extension
sourav parmarcd5fb182020-07-17 12:58:44 -07002868 if (enabled[gpu_validation]) {
locke-lunargd556cc32019-09-17 01:21:23 -06002869 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
2870 }
2871 }
2872 }
2873}
2874
2875void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructureNV(
2876 VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset,
2877 VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002878 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002879 if (cb_state == nullptr) {
2880 return;
2881 }
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002882 cb_state->RecordCmd(CMD_BUILDACCELERATIONSTRUCTURENV);
locke-lunargd556cc32019-09-17 01:21:23 -06002883
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002884 auto *dst_as_state = GetAccelerationStructureStateNV(dst);
locke-lunargd556cc32019-09-17 01:21:23 -06002885 if (dst_as_state != nullptr) {
2886 dst_as_state->built = true;
2887 dst_as_state->build_info.initialize(pInfo);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002888 if (!disabled[command_buffer_state]) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002889 cb_state->AddChild(dst_as_state);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002890 }
locke-lunargd556cc32019-09-17 01:21:23 -06002891 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002892 if (!disabled[command_buffer_state]) {
2893 auto *src_as_state = GetAccelerationStructureStateNV(src);
2894 if (src_as_state != nullptr) {
2895 cb_state->AddChild(src_as_state);
2896 }
locke-lunargd556cc32019-09-17 01:21:23 -06002897 }
2898 cb_state->hasBuildAccelerationStructureCmd = true;
2899}
2900
2901void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureNV(VkCommandBuffer commandBuffer,
2902 VkAccelerationStructureNV dst,
2903 VkAccelerationStructureNV src,
2904 VkCopyAccelerationStructureModeNV mode) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002905 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002906 if (cb_state) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002907 ACCELERATION_STRUCTURE_STATE *src_as_state = GetAccelerationStructureStateNV(src);
2908 ACCELERATION_STRUCTURE_STATE *dst_as_state = GetAccelerationStructureStateNV(dst);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002909 if (!disabled[command_buffer_state]) {
2910 cb_state->RecordTransferCmd(CMD_COPYACCELERATIONSTRUCTURENV, src_as_state, dst_as_state);
2911 }
locke-lunargd556cc32019-09-17 01:21:23 -06002912 if (dst_as_state != nullptr && src_as_state != nullptr) {
2913 dst_as_state->built = true;
2914 dst_as_state->build_info = src_as_state->build_info;
locke-lunargd556cc32019-09-17 01:21:23 -06002915 }
2916 }
2917}
2918
Jeff Bolz95176d02020-04-01 00:36:16 -05002919void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureKHR(VkDevice device,
2920 VkAccelerationStructureKHR accelerationStructure,
2921 const VkAllocationCallbacks *pAllocator) {
locke-lunargd556cc32019-09-17 01:21:23 -06002922 if (!accelerationStructure) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07002923 auto *as_state = GetAccelerationStructureStateKHR(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002924 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002925 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07002926 accelerationStructureMap_khr.erase(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002927 }
2928}
2929
Jeff Bolz95176d02020-04-01 00:36:16 -05002930void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureNV(VkDevice device,
2931 VkAccelerationStructureNV accelerationStructure,
2932 const VkAllocationCallbacks *pAllocator) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002933 if (!accelerationStructure) return;
2934 auto *as_state = GetAccelerationStructureStateNV(accelerationStructure);
2935 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002936 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07002937 accelerationStructureMap.erase(accelerationStructure);
2938 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002939}
2940
Chris Mayer9ded5eb2019-09-19 16:33:26 +02002941void ValidationStateTracker::PreCallRecordCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2942 uint32_t viewportCount,
2943 const VkViewportWScalingNV *pViewportWScalings) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002944 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002945 cb_state->RecordStateCmd(CMD_SETVIEWPORTWSCALINGNV, CBSTATUS_VIEWPORT_W_SCALING_SET);
Chris Mayer9ded5eb2019-09-19 16:33:26 +02002946}
2947
locke-lunargd556cc32019-09-17 01:21:23 -06002948void ValidationStateTracker::PreCallRecordCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002949 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002950 cb_state->RecordStateCmd(CMD_SETLINEWIDTH, CBSTATUS_LINE_WIDTH_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002951}
2952
2953void ValidationStateTracker::PreCallRecordCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
2954 uint16_t lineStipplePattern) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002955 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002956 cb_state->RecordStateCmd(CMD_SETLINESTIPPLEEXT, CBSTATUS_LINE_STIPPLE_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002957}
2958
2959void ValidationStateTracker::PreCallRecordCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
2960 float depthBiasClamp, float depthBiasSlopeFactor) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002961 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002962 cb_state->RecordStateCmd(CMD_SETDEPTHBIAS, CBSTATUS_DEPTH_BIAS_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002963}
2964
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002965void ValidationStateTracker::PreCallRecordCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
2966 const VkRect2D *pScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002967 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002968 cb_state->RecordStateCmd(CMD_SETSCISSOR, CBSTATUS_SCISSOR_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002969 uint32_t bits = ((1u << scissorCount) - 1u) << firstScissor;
2970 cb_state->scissorMask |= bits;
2971 cb_state->trashedScissorMask &= ~bits;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002972}
2973
locke-lunargd556cc32019-09-17 01:21:23 -06002974void ValidationStateTracker::PreCallRecordCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002975 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002976 cb_state->RecordStateCmd(CMD_SETBLENDCONSTANTS, CBSTATUS_BLEND_CONSTANTS_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002977}
2978
2979void ValidationStateTracker::PreCallRecordCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
2980 float maxDepthBounds) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002981 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002982 cb_state->RecordStateCmd(CMD_SETDEPTHBOUNDS, CBSTATUS_DEPTH_BOUNDS_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002983}
2984
2985void ValidationStateTracker::PreCallRecordCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
2986 uint32_t compareMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002987 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002988 cb_state->RecordStateCmd(CMD_SETSTENCILCOMPAREMASK, CBSTATUS_STENCIL_READ_MASK_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002989}
2990
2991void ValidationStateTracker::PreCallRecordCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
2992 uint32_t writeMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002993 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002994 cb_state->RecordStateCmd(CMD_SETSTENCILWRITEMASK, CBSTATUS_STENCIL_WRITE_MASK_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002995}
2996
2997void ValidationStateTracker::PreCallRecordCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
2998 uint32_t reference) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002999 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003000 cb_state->RecordStateCmd(CMD_SETSTENCILREFERENCE, CBSTATUS_STENCIL_REFERENCE_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06003001}
3002
locke-lunargd556cc32019-09-17 01:21:23 -06003003
3004// Update the bound state for the bind point, including the effects of incompatible pipeline layouts
3005void ValidationStateTracker::PreCallRecordCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
3006 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3007 uint32_t firstSet, uint32_t setCount,
3008 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
3009 const uint32_t *pDynamicOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003010 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003011 cb_state->RecordCmd(CMD_BINDDESCRIPTORSETS);
locke-lunargd556cc32019-09-17 01:21:23 -06003012 auto pipeline_layout = GetPipelineLayout(layout);
3013
3014 // Resize binding arrays
3015 uint32_t last_set_index = firstSet + setCount - 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003016 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
3017 if (last_set_index >= cb_state->lastBound[lv_bind_point].per_set.size()) {
3018 cb_state->lastBound[lv_bind_point].per_set.resize(last_set_index + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06003019 }
3020
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003021 cb_state->UpdateLastBoundDescriptorSets(pipelineBindPoint, pipeline_layout, firstSet, setCount, pDescriptorSets, nullptr,
3022 dynamicOffsetCount, pDynamicOffsets);
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003023 cb_state->lastBound[lv_bind_point].pipeline_layout = layout;
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06003024 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06003025}
3026
locke-lunargd556cc32019-09-17 01:21:23 -06003027void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
3028 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3029 uint32_t set, uint32_t descriptorWriteCount,
3030 const VkWriteDescriptorSet *pDescriptorWrites) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003031 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003032 auto pipeline_layout = GetPipelineLayout(layout);
3033 cb_state->PushDescriptorSetState(pipelineBindPoint, pipeline_layout, set, descriptorWriteCount, pDescriptorWrites);
locke-lunargd556cc32019-09-17 01:21:23 -06003034}
3035
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003036void ValidationStateTracker::PostCallRecordCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
3037 VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
3038 const void *pValues) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003039 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003040 if (cb_state != nullptr) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003041 cb_state->RecordCmd(CMD_PUSHCONSTANTS);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003042 cb_state->ResetPushConstantDataIfIncompatible(GetPipelineLayout(layout));
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003043
3044 auto &push_constant_data = cb_state->push_constant_data;
3045 assert((offset + size) <= static_cast<uint32_t>(push_constant_data.size()));
3046 std::memcpy(push_constant_data.data() + offset, pValues, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003047 cb_state->push_constant_pipeline_layout_set = layout;
3048
3049 auto flags = stageFlags;
3050 uint32_t bit_shift = 0;
3051 while (flags) {
3052 if (flags & 1) {
3053 VkShaderStageFlagBits flag = static_cast<VkShaderStageFlagBits>(1 << bit_shift);
3054 const auto it = cb_state->push_constant_data_update.find(flag);
3055
3056 if (it != cb_state->push_constant_data_update.end()) {
locke-lunarg3d8b8f32020-10-26 17:04:16 -06003057 std::memset(it->second.data() + offset, PC_Byte_Updated, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003058 }
3059 }
3060 flags = flags >> 1;
3061 ++bit_shift;
3062 }
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003063 }
3064}
3065
locke-lunargd556cc32019-09-17 01:21:23 -06003066void ValidationStateTracker::PreCallRecordCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
3067 VkIndexType indexType) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003068 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003069
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003070 cb_state->RecordStateCmd(CMD_BINDINDEXBUFFER, CBSTATUS_INDEX_BUFFER_BOUND);
locke-lunarg1ae57d62020-11-18 10:49:19 -07003071 cb_state->index_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(buffer);
3072 cb_state->index_buffer_binding.size = cb_state->index_buffer_binding.buffer_state->createInfo.size;
locke-lunargd556cc32019-09-17 01:21:23 -06003073 cb_state->index_buffer_binding.offset = offset;
3074 cb_state->index_buffer_binding.index_type = indexType;
3075 // Add binding for this index buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003076 if (!disabled[command_buffer_state]) {
3077 cb_state->AddChild(cb_state->index_buffer_binding.buffer_state.get());
3078 }
locke-lunargd556cc32019-09-17 01:21:23 -06003079}
3080
3081void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
3082 uint32_t bindingCount, const VkBuffer *pBuffers,
3083 const VkDeviceSize *pOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003084 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003085 cb_state->RecordCmd(CMD_BINDVERTEXBUFFERS);
locke-lunargd556cc32019-09-17 01:21:23 -06003086
3087 uint32_t end = firstBinding + bindingCount;
3088 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
3089 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
3090 }
3091
3092 for (uint32_t i = 0; i < bindingCount; ++i) {
3093 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07003094 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003095 vertex_buffer_binding.offset = pOffsets[i];
Piers Daniell39842ee2020-07-10 16:42:33 -06003096 vertex_buffer_binding.size = VK_WHOLE_SIZE;
3097 vertex_buffer_binding.stride = 0;
locke-lunargd556cc32019-09-17 01:21:23 -06003098 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003099 if (pBuffers[i] && !disabled[command_buffer_state]) {
3100 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Jeff Bolz165818a2020-05-08 11:19:03 -05003101 }
locke-lunargd556cc32019-09-17 01:21:23 -06003102 }
3103}
3104
3105void ValidationStateTracker::PostCallRecordCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
3106 VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003107 if (disabled[command_buffer_state]) return;
3108
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003109 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003110 cb_state->RecordTransferCmd(CMD_UPDATEBUFFER, GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -06003111}
3112
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003113void ValidationStateTracker::PreCallRecordCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3114 VkPipelineStageFlags stageMask) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003115 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3116 cb_state->RecordSetEvent(CMD_SETEVENT, event, stageMask);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003117}
3118
3119void ValidationStateTracker::PreCallRecordCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3120 const VkDependencyInfoKHR *pDependencyInfo) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003121 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003122 auto stage_masks = sync_utils::GetGlobalStageMasks(*pDependencyInfo);
3123
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003124 cb_state->RecordSetEvent(CMD_SETEVENT2KHR, event, stage_masks.src);
3125 cb_state->RecordBarriers(*pDependencyInfo);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003126}
3127
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003128void ValidationStateTracker::PreCallRecordCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3129 VkPipelineStageFlags stageMask) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003130 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3131 cb_state->RecordResetEvent(CMD_RESETEVENT, event, stageMask);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003132}
3133
3134void ValidationStateTracker::PreCallRecordCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3135 VkPipelineStageFlags2KHR stageMask) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003136 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3137 cb_state->RecordResetEvent(CMD_RESETEVENT2KHR, event, stageMask);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003138}
3139
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003140void ValidationStateTracker::PreCallRecordCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
3141 VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
3142 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3143 uint32_t bufferMemoryBarrierCount,
3144 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3145 uint32_t imageMemoryBarrierCount,
3146 const VkImageMemoryBarrier *pImageMemoryBarriers) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003147 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3148 cb_state->RecordWaitEvents(CMD_WAITEVENTS, eventCount, pEvents);
3149 cb_state->RecordBarriers(memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3150 imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003151}
3152
3153void ValidationStateTracker::PreCallRecordCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount,
3154 const VkEvent *pEvents, const VkDependencyInfoKHR *pDependencyInfos) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003155 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3156 cb_state->RecordWaitEvents(CMD_WAITEVENTS2KHR, eventCount, pEvents);
Jeremy Gebben79649152021-06-22 14:46:24 -06003157 for (uint32_t i = 0; i < eventCount; i++) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003158 cb_state->RecordBarriers(pDependencyInfos[i]);
Jeremy Gebben79649152021-06-22 14:46:24 -06003159 }
3160}
3161
3162void ValidationStateTracker::PostCallRecordCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
3163 VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
3164 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3165 uint32_t bufferMemoryBarrierCount,
3166 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3167 uint32_t imageMemoryBarrierCount,
3168 const VkImageMemoryBarrier *pImageMemoryBarriers) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003169 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3170 cb_state->RecordCmd(CMD_PIPELINEBARRIER);
3171 cb_state->RecordBarriers(memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3172 imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Gebben79649152021-06-22 14:46:24 -06003173}
3174
3175void ValidationStateTracker::PreCallRecordCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
3176 const VkDependencyInfoKHR *pDependencyInfo) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003177 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3178 cb_state->RecordCmd(CMD_PIPELINEBARRIER2KHR);
3179 cb_state->RecordBarriers(*pDependencyInfo);
Jeremy Gebben79649152021-06-22 14:46:24 -06003180}
3181
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003182QueryState ValidationStateTracker::GetQueryState(const QueryMap *localQueryToStateMap, VkQueryPool queryPool, uint32_t queryIndex,
3183 uint32_t perfPass) const {
3184 QueryObject query = QueryObject(QueryObject(queryPool, queryIndex), perfPass);
locke-lunargd556cc32019-09-17 01:21:23 -06003185
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003186 auto iter = localQueryToStateMap->find(query);
3187 if (iter != localQueryToStateMap->end()) return iter->second;
Jeff Bolz310775c2019-10-09 00:46:33 -05003188
Jeff Bolz310775c2019-10-09 00:46:33 -05003189 return QUERYSTATE_UNKNOWN;
locke-lunargd556cc32019-09-17 01:21:23 -06003190}
3191
locke-lunargd556cc32019-09-17 01:21:23 -06003192void ValidationStateTracker::PostCallRecordCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot,
3193 VkFlags flags) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003194 if (disabled[query_validation]) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003195
locke-lunargd556cc32019-09-17 01:21:23 -06003196 QueryObject query = {queryPool, slot};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003197 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003198 cb_state->RecordCmd(CMD_BEGINQUERY);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003199 if (!disabled[query_validation]) {
3200 cb_state->BeginQuery(query);
3201 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003202 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003203 auto pool_state = GetQueryPoolState(query.pool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003204 cb_state->AddChild(pool_state);
3205 }
locke-lunargd556cc32019-09-17 01:21:23 -06003206}
3207
3208void ValidationStateTracker::PostCallRecordCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003209 if (disabled[query_validation]) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003210 QueryObject query_obj = {queryPool, slot};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003211 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003212 cb_state->RecordCmd(CMD_ENDQUERY);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003213 if (!disabled[query_validation]) {
3214 cb_state->EndQuery(query_obj);
3215 }
3216 if (!disabled[command_buffer_state]) {
3217 auto pool_state = GetQueryPoolState(query_obj.pool);
3218 cb_state->AddChild(pool_state);
3219 }
locke-lunargd556cc32019-09-17 01:21:23 -06003220}
3221
3222void ValidationStateTracker::PostCallRecordCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3223 uint32_t firstQuery, uint32_t queryCount) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003224 if (disabled[query_validation]) return;
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003225 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003226
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003227 cb_state->RecordCmd(CMD_RESETQUERYPOOL);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003228 cb_state->ResetQueryPool(queryPool, firstQuery, queryCount);
Lionel Landwerlinb1e5a422020-02-18 16:49:09 +02003229
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003230 if (!disabled[command_buffer_state]) {
3231 auto pool_state = GetQueryPoolState(queryPool);
3232 cb_state->AddChild(pool_state);
3233 }
locke-lunargd556cc32019-09-17 01:21:23 -06003234}
3235
3236void ValidationStateTracker::PostCallRecordCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3237 uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer,
3238 VkDeviceSize dstOffset, VkDeviceSize stride,
3239 VkQueryResultFlags flags) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003240 if (disabled[query_validation] || disabled[command_buffer_state]) return;
3241
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003242 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003243 cb_state->RecordCmd(CMD_COPYQUERYPOOLRESULTS);
locke-lunargd556cc32019-09-17 01:21:23 -06003244 auto dst_buff_state = GetBufferState(dstBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003245 cb_state->AddChild(dst_buff_state);
Jeff Bolzadbfa852019-10-04 13:53:30 -05003246 auto pool_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003247 cb_state->AddChild(pool_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003248}
3249
3250void ValidationStateTracker::PostCallRecordCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
3251 VkQueryPool queryPool, uint32_t slot) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003252 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3253 cb_state->RecordWriteTimestamp(CMD_WRITETIMESTAMP, pipelineStage, queryPool, slot);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003254}
3255
3256void ValidationStateTracker::PostCallRecordCmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer,
3257 VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool,
3258 uint32_t slot) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003259 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3260 cb_state->RecordWriteTimestamp(CMD_WRITETIMESTAMP2KHR, pipelineStage, queryPool, slot);
locke-lunargd556cc32019-09-17 01:21:23 -06003261}
3262
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003263void ValidationStateTracker::PostCallRecordCmdWriteAccelerationStructuresPropertiesKHR(
3264 VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR *pAccelerationStructures,
3265 VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery) {
3266 if (disabled[query_validation]) return;
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003267 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003268 cb_state->RecordCmd(CMD_WRITEACCELERATIONSTRUCTURESPROPERTIESKHR);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003269 if (!disabled[command_buffer_state]) {
3270 auto pool_state = GetQueryPoolState(queryPool);
3271 cb_state->AddChild(pool_state);
3272 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003273 cb_state->EndQueries(queryPool, firstQuery, accelerationStructureCount);
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003274}
3275
locke-lunargd556cc32019-09-17 01:21:23 -06003276void ValidationStateTracker::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
3277 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
3278 VkResult result) {
3279 if (VK_SUCCESS != result) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003280
Jeremy Gebben88f58142021-06-01 10:07:52 -06003281 std::vector<std::shared_ptr<IMAGE_VIEW_STATE>> views;
Mike Schuchardt2df08912020-12-15 16:28:09 -08003282 if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) == 0) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003283 views.resize(pCreateInfo->attachmentCount);
locke-lunarg1ae57d62020-11-18 10:49:19 -07003284
locke-lunargd556cc32019-09-17 01:21:23 -06003285 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003286 views[i] = GetShared<IMAGE_VIEW_STATE>(pCreateInfo->pAttachments[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003287 }
3288 }
Jeremy Gebben88f58142021-06-01 10:07:52 -06003289
3290 frameBufferMap[*pFramebuffer] = std::make_shared<FRAMEBUFFER_STATE>(
3291 *pFramebuffer, pCreateInfo, GetRenderPassShared(pCreateInfo->renderPass), std::move(views));
locke-lunargd556cc32019-09-17 01:21:23 -06003292}
3293
locke-lunargd556cc32019-09-17 01:21:23 -06003294void ValidationStateTracker::PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
3295 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3296 VkResult result) {
3297 if (VK_SUCCESS != result) return;
Jeremy Gebben88f58142021-06-01 10:07:52 -06003298 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06003299}
3300
Mike Schuchardt2df08912020-12-15 16:28:09 -08003301void ValidationStateTracker::PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003302 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3303 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003304 if (VK_SUCCESS != result) return;
3305
3306 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003307}
3308
Mike Schuchardt2df08912020-12-15 16:28:09 -08003309void ValidationStateTracker::PostCallRecordCreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003310 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3311 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003312 if (VK_SUCCESS != result) return;
3313
3314 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003315}
3316
locke-lunargd556cc32019-09-17 01:21:23 -06003317void ValidationStateTracker::PreCallRecordCmdBeginRenderPass(VkCommandBuffer commandBuffer,
3318 const VkRenderPassBeginInfo *pRenderPassBegin,
3319 VkSubpassContents contents) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003320 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3321 cb_state->BeginRenderPass(CMD_BEGINRENDERPASS, pRenderPassBegin, contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003322}
3323
3324void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
3325 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003326 const VkSubpassBeginInfo *pSubpassBeginInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003327 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3328 cb_state->BeginRenderPass(CMD_BEGINRENDERPASS2, pRenderPassBegin, pSubpassBeginInfo->contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003329}
3330
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003331void ValidationStateTracker::PostCallRecordCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3332 uint32_t counterBufferCount,
3333 const VkBuffer *pCounterBuffers,
3334 const VkDeviceSize *pCounterBufferOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003335 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003336
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003337 cb_state->RecordCmd(CMD_BEGINTRANSFORMFEEDBACKEXT);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003338 cb_state->transform_feedback_active = true;
3339}
3340
3341void ValidationStateTracker::PostCallRecordCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3342 uint32_t counterBufferCount, const VkBuffer *pCounterBuffers,
3343 const VkDeviceSize *pCounterBufferOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003344 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003345
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003346 cb_state->RecordCmd(CMD_ENDTRANSFORMFEEDBACKEXT);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003347 cb_state->transform_feedback_active = false;
3348}
3349
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003350void ValidationStateTracker::PostCallRecordCmdBeginConditionalRenderingEXT(
3351 VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin) {
Jeremy Gebbenc8b51a92021-08-16 15:19:00 -06003352 auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003353
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003354 cb_state->RecordCmd(CMD_BEGINCONDITIONALRENDERINGEXT);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003355 cb_state->conditional_rendering_active = true;
3356}
3357
3358void ValidationStateTracker::PostCallRecordCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer) {
Jeremy Gebbenc8b51a92021-08-16 15:19:00 -06003359 auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003360
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003361 cb_state->RecordCmd(CMD_ENDCONDITIONALRENDERINGEXT);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003362 cb_state->conditional_rendering_active = false;
3363
3364}
3365
Tony-LunarG977448c2019-12-02 14:52:02 -07003366void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
3367 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003368 const VkSubpassBeginInfo *pSubpassBeginInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003369 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3370 cb_state->BeginRenderPass(CMD_BEGINRENDERPASS2, pRenderPassBegin, pSubpassBeginInfo->contents);
Tony-LunarG977448c2019-12-02 14:52:02 -07003371}
3372
locke-lunargd556cc32019-09-17 01:21:23 -06003373
3374void ValidationStateTracker::PostCallRecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003375 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3376 cb_state->NextSubpass(CMD_NEXTSUBPASS, contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003377}
3378
3379void ValidationStateTracker::PostCallRecordCmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003380 const VkSubpassBeginInfo *pSubpassBeginInfo,
3381 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003382 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3383 cb_state->NextSubpass(CMD_NEXTSUBPASS2, pSubpassBeginInfo->contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003384}
3385
Tony-LunarG977448c2019-12-02 14:52:02 -07003386void ValidationStateTracker::PostCallRecordCmdNextSubpass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003387 const VkSubpassBeginInfo *pSubpassBeginInfo,
3388 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003389 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003390 cb_state->NextSubpass(CMD_NEXTSUBPASS2, pSubpassBeginInfo->contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003391}
3392
3393void ValidationStateTracker::PostCallRecordCmdEndRenderPass(VkCommandBuffer commandBuffer) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003394 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3395 cb_state->EndRenderPass(CMD_ENDRENDERPASS);
locke-lunargd556cc32019-09-17 01:21:23 -06003396}
3397
3398void ValidationStateTracker::PostCallRecordCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003399 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003400 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3401 cb_state->EndRenderPass(CMD_ENDRENDERPASS2);
locke-lunargd556cc32019-09-17 01:21:23 -06003402}
3403
Tony-LunarG977448c2019-12-02 14:52:02 -07003404void ValidationStateTracker::PostCallRecordCmdEndRenderPass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003405 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003406 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3407 cb_state->EndRenderPass(CMD_ENDRENDERPASS2);
Tony-LunarG977448c2019-12-02 14:52:02 -07003408}
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003409
locke-lunargd556cc32019-09-17 01:21:23 -06003410void ValidationStateTracker::PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
3411 const VkCommandBuffer *pCommandBuffers) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003412 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003413
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003414 cb_state->ExecuteCommands(commandBuffersCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06003415}
3416
3417void ValidationStateTracker::PostCallRecordMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size,
3418 VkFlags flags, void **ppData, VkResult result) {
3419 if (VK_SUCCESS != result) return;
3420 RecordMappedMemory(mem, offset, size, ppData);
3421}
3422
3423void ValidationStateTracker::PreCallRecordUnmapMemory(VkDevice device, VkDeviceMemory mem) {
3424 auto mem_info = GetDevMemState(mem);
3425 if (mem_info) {
3426 mem_info->mapped_range = MemRange();
3427 mem_info->p_driver_data = nullptr;
3428 }
3429}
3430
3431void ValidationStateTracker::UpdateBindImageMemoryState(const VkBindImageMemoryInfo &bindInfo) {
Jeremy Gebben8ee02af2021-07-16 10:15:55 -06003432 auto image_state = GetShared<IMAGE_STATE>(bindInfo.image);
locke-lunargd556cc32019-09-17 01:21:23 -06003433 if (image_state) {
locke-lunargae26eac2020-04-16 15:29:05 -06003434 // An Android sepcial image cannot get VkSubresourceLayout until the image binds a memory.
3435 // See: VUID-vkGetImageSubresourceLayout-image-01895
3436 image_state->fragment_encoder =
3437 std::unique_ptr<const subresource_adapter::ImageRangeEncoder>(new subresource_adapter::ImageRangeEncoder(*image_state));
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003438 const auto swapchain_info = LvlFindInChain<VkBindImageMemorySwapchainInfoKHR>(bindInfo.pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003439 if (swapchain_info) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003440 auto swapchain = GetShared<SWAPCHAIN_NODE>(swapchain_info->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003441 if (swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003442 SWAPCHAIN_IMAGE &swapchain_image = swapchain->images[swapchain_info->imageIndex];
John Zulaufd13b38e2021-03-05 08:17:38 -07003443
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003444 if (!swapchain_image.fake_base_address) {
3445 auto size = image_state->fragment_encoder->TotalSize();
3446 swapchain_image.fake_base_address = fake_memory.Alloc(size);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06003447 }
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003448 // All images bound to this swapchain and index are aliases
3449 image_state->SetSwapchain(swapchain, swapchain_info->imageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003450 }
3451 } else {
3452 // Track bound memory range information
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003453 auto mem_info = GetDevMemShared(bindInfo.memory);
locke-lunargd556cc32019-09-17 01:21:23 -06003454 if (mem_info) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003455 image_state->SetMemBinding(mem_info, bindInfo.memoryOffset);
locke-lunargd556cc32019-09-17 01:21:23 -06003456 }
locke-lunargd556cc32019-09-17 01:21:23 -06003457 }
locke-lunargd556cc32019-09-17 01:21:23 -06003458 }
3459}
3460
3461void ValidationStateTracker::PostCallRecordBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
3462 VkDeviceSize memoryOffset, VkResult result) {
3463 if (VK_SUCCESS != result) return;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003464 auto bind_info = LvlInitStruct<VkBindImageMemoryInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003465 bind_info.image = image;
3466 bind_info.memory = mem;
3467 bind_info.memoryOffset = memoryOffset;
3468 UpdateBindImageMemoryState(bind_info);
locke-lunargd556cc32019-09-17 01:21:23 -06003469}
3470
3471void ValidationStateTracker::PostCallRecordBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003472 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003473 if (VK_SUCCESS != result) return;
3474 for (uint32_t i = 0; i < bindInfoCount; i++) {
3475 UpdateBindImageMemoryState(pBindInfos[i]);
3476 }
3477}
3478
3479void ValidationStateTracker::PostCallRecordBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003480 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003481 if (VK_SUCCESS != result) return;
3482 for (uint32_t i = 0; i < bindInfoCount; i++) {
3483 UpdateBindImageMemoryState(pBindInfos[i]);
3484 }
3485}
3486
3487void ValidationStateTracker::PreCallRecordSetEvent(VkDevice device, VkEvent event) {
3488 auto event_state = GetEventState(event);
3489 if (event_state) {
3490 event_state->stageMask = VK_PIPELINE_STAGE_HOST_BIT;
3491 }
locke-lunargd556cc32019-09-17 01:21:23 -06003492}
3493
3494void ValidationStateTracker::PostCallRecordImportSemaphoreFdKHR(VkDevice device,
3495 const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo,
3496 VkResult result) {
3497 if (VK_SUCCESS != result) return;
3498 RecordImportSemaphoreState(pImportSemaphoreFdInfo->semaphore, pImportSemaphoreFdInfo->handleType,
3499 pImportSemaphoreFdInfo->flags);
3500}
3501
3502void ValidationStateTracker::RecordGetExternalSemaphoreState(VkSemaphore semaphore,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003503 VkExternalSemaphoreHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003504 SEMAPHORE_STATE *semaphore_state = GetSemaphoreState(semaphore);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003505 if (semaphore_state && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003506 // Cannot track semaphore state once it is exported, except for Sync FD handle types which have copy transference
3507 semaphore_state->scope = kSyncScopeExternalPermanent;
3508 }
3509}
3510
3511#ifdef VK_USE_PLATFORM_WIN32_KHR
3512void ValidationStateTracker::PostCallRecordImportSemaphoreWin32HandleKHR(
3513 VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR *pImportSemaphoreWin32HandleInfo, VkResult result) {
3514 if (VK_SUCCESS != result) return;
3515 RecordImportSemaphoreState(pImportSemaphoreWin32HandleInfo->semaphore, pImportSemaphoreWin32HandleInfo->handleType,
3516 pImportSemaphoreWin32HandleInfo->flags);
3517}
3518
3519void ValidationStateTracker::PostCallRecordGetSemaphoreWin32HandleKHR(VkDevice device,
3520 const VkSemaphoreGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3521 HANDLE *pHandle, VkResult result) {
3522 if (VK_SUCCESS != result) return;
3523 RecordGetExternalSemaphoreState(pGetWin32HandleInfo->semaphore, pGetWin32HandleInfo->handleType);
3524}
3525
3526void ValidationStateTracker::PostCallRecordImportFenceWin32HandleKHR(
3527 VkDevice device, const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo, VkResult result) {
3528 if (VK_SUCCESS != result) return;
3529 RecordImportFenceState(pImportFenceWin32HandleInfo->fence, pImportFenceWin32HandleInfo->handleType,
3530 pImportFenceWin32HandleInfo->flags);
3531}
3532
3533void ValidationStateTracker::PostCallRecordGetFenceWin32HandleKHR(VkDevice device,
3534 const VkFenceGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3535 HANDLE *pHandle, VkResult result) {
3536 if (VK_SUCCESS != result) return;
3537 RecordGetExternalFenceState(pGetWin32HandleInfo->fence, pGetWin32HandleInfo->handleType);
3538}
3539#endif
3540
3541void ValidationStateTracker::PostCallRecordGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *pGetFdInfo, int *pFd,
3542 VkResult result) {
3543 if (VK_SUCCESS != result) return;
3544 RecordGetExternalSemaphoreState(pGetFdInfo->semaphore, pGetFdInfo->handleType);
3545}
3546
Mike Schuchardt2df08912020-12-15 16:28:09 -08003547void ValidationStateTracker::RecordImportFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type,
3548 VkFenceImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06003549 FENCE_STATE *fence_node = GetFenceState(fence);
3550 if (fence_node && fence_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003551 if ((handle_type == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_FENCE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06003552 fence_node->scope == kSyncScopeInternal) {
3553 fence_node->scope = kSyncScopeExternalTemporary;
3554 } else {
3555 fence_node->scope = kSyncScopeExternalPermanent;
3556 }
3557 }
3558}
3559
3560void ValidationStateTracker::PostCallRecordImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo,
3561 VkResult result) {
3562 if (VK_SUCCESS != result) return;
3563 RecordImportFenceState(pImportFenceFdInfo->fence, pImportFenceFdInfo->handleType, pImportFenceFdInfo->flags);
3564}
3565
Mike Schuchardt2df08912020-12-15 16:28:09 -08003566void ValidationStateTracker::RecordGetExternalFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003567 FENCE_STATE *fence_state = GetFenceState(fence);
3568 if (fence_state) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003569 if (handle_type != VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003570 // Export with reference transference becomes external
3571 fence_state->scope = kSyncScopeExternalPermanent;
3572 } else if (fence_state->scope == kSyncScopeInternal) {
3573 // Export with copy transference has a side effect of resetting the fence
3574 fence_state->state = FENCE_UNSIGNALED;
3575 }
3576 }
3577}
3578
3579void ValidationStateTracker::PostCallRecordGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *pGetFdInfo, int *pFd,
3580 VkResult result) {
3581 if (VK_SUCCESS != result) return;
3582 RecordGetExternalFenceState(pGetFdInfo->fence, pGetFdInfo->handleType);
3583}
3584
3585void ValidationStateTracker::PostCallRecordCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
3586 const VkAllocationCallbacks *pAllocator, VkEvent *pEvent, VkResult result) {
3587 if (VK_SUCCESS != result) return;
John Zulaufd5115702021-01-18 12:34:33 -07003588 const auto event = *pEvent;
Jeremy Gebbencbf22862021-03-03 12:01:22 -07003589 eventMap.emplace(event, std::make_shared<EVENT_STATE>(event, pCreateInfo->flags));
locke-lunargd556cc32019-09-17 01:21:23 -06003590}
3591
3592void ValidationStateTracker::RecordCreateSwapchainState(VkResult result, const VkSwapchainCreateInfoKHR *pCreateInfo,
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003593 VkSwapchainKHR *pSwapchain, std::shared_ptr<SURFACE_STATE> &&surface_state,
locke-lunargd556cc32019-09-17 01:21:23 -06003594 SWAPCHAIN_NODE *old_swapchain_state) {
3595 if (VK_SUCCESS == result) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003596 if (surface_state->swapchain) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003597 surface_state->RemoveParent(surface_state->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003598 }
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003599 auto swapchain = CreateSwapchainState(pCreateInfo, *pSwapchain);
3600 surface_state->AddParent(swapchain.get());
3601 surface_state->swapchain = swapchain.get();
3602 swapchain->surface = std::move(surface_state);
3603 swapchainMap[*pSwapchain] = std::move(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003604 } else {
3605 surface_state->swapchain = nullptr;
3606 }
3607 // Spec requires that even if CreateSwapchainKHR fails, oldSwapchain is retired
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003608 // Retired swapchains remain associated with the surface until they are destroyed.
locke-lunargd556cc32019-09-17 01:21:23 -06003609 if (old_swapchain_state) {
3610 old_swapchain_state->retired = true;
3611 }
3612 return;
3613}
3614
3615void ValidationStateTracker::PostCallRecordCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
3616 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain,
3617 VkResult result) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003618 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfo->surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003619 auto old_swapchain_state = GetSwapchainState(pCreateInfo->oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003620 RecordCreateSwapchainState(result, pCreateInfo, pSwapchain, std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003621}
3622
3623void ValidationStateTracker::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
3624 const VkAllocationCallbacks *pAllocator) {
3625 if (!swapchain) return;
3626 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003627 if (!swapchain_data) return;
John Zulauffaa7a522021-03-05 12:22:45 -07003628
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003629 swapchain_data->Destroy();
3630 swapchainMap.erase(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003631}
3632
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003633void ValidationStateTracker::PostCallRecordCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
3634 const VkDisplayModeCreateInfoKHR *pCreateInfo,
3635 const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode,
3636 VkResult result) {
3637 if (VK_SUCCESS != result) return;
3638 if (!pMode) return;
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06003639 display_mode_map[*pMode] = std::make_shared<DISPLAY_MODE_STATE>(*pMode, physicalDevice);
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003640}
3641
locke-lunargd556cc32019-09-17 01:21:23 -06003642void ValidationStateTracker::PostCallRecordQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo, VkResult result) {
3643 // Semaphore waits occur before error generation, if the call reached the ICD. (Confirm?)
3644 for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003645 auto semaphore_state = GetSemaphoreState(pPresentInfo->pWaitSemaphores[i]);
3646 if (semaphore_state) {
3647 semaphore_state->signaler.first = VK_NULL_HANDLE;
3648 semaphore_state->signaled = false;
locke-lunargd556cc32019-09-17 01:21:23 -06003649 }
3650 }
3651
Tony-LunarG6f887e52021-07-27 11:23:14 -06003652 const auto *present_id_info = LvlFindInChain<VkPresentIdKHR>(pPresentInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003653 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
3654 // 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
3655 // confused itself just as much.
3656 auto local_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result;
3657 if (local_result != VK_SUCCESS && local_result != VK_SUBOPTIMAL_KHR) continue; // this present didn't actually happen.
3658 // Mark the image as having been released to the WSI
3659 auto swapchain_data = GetSwapchainState(pPresentInfo->pSwapchains[i]);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003660 if (swapchain_data) {
3661 swapchain_data->PresentImage(pPresentInfo->pImageIndices[i]);
Tony-LunarG6f887e52021-07-27 11:23:14 -06003662 if (present_id_info) {
3663 if (i < present_id_info->swapchainCount && present_id_info->pPresentIds[i] > swapchain_data->max_present_id) {
3664 swapchain_data->max_present_id = present_id_info->pPresentIds[i];
3665 }
3666 }
locke-lunargd556cc32019-09-17 01:21:23 -06003667 }
3668 }
3669 // Note: even though presentation is directed to a queue, there is no direct ordering between QP and subsequent work, so QP (and
3670 // its semaphore waits) /never/ participate in any completion proof.
3671}
3672
3673void ValidationStateTracker::PostCallRecordCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
3674 const VkSwapchainCreateInfoKHR *pCreateInfos,
3675 const VkAllocationCallbacks *pAllocator,
3676 VkSwapchainKHR *pSwapchains, VkResult result) {
3677 if (pCreateInfos) {
3678 for (uint32_t i = 0; i < swapchainCount; i++) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003679 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfos[i].surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003680 auto old_swapchain_state = GetSwapchainState(pCreateInfos[i].oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003681 RecordCreateSwapchainState(result, &pCreateInfos[i], &pSwapchains[i], std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003682 }
3683 }
3684}
3685
3686void ValidationStateTracker::RecordAcquireNextImageState(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3687 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003688 auto fence_state = GetFenceState(fence);
3689 if (fence_state && fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003690 // Treat as inflight since it is valid to wait on this fence, even in cases where it is technically a temporary
3691 // import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003692 fence_state->state = FENCE_INFLIGHT;
3693 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 -06003694 }
3695
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003696 auto semaphore_state = GetSemaphoreState(semaphore);
3697 if (semaphore_state && semaphore_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003698 // Treat as signaled since it is valid to wait on this semaphore, even in cases where it is technically a
3699 // temporary import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003700 semaphore_state->signaled = true;
3701 semaphore_state->signaler.first = VK_NULL_HANDLE;
locke-lunargd556cc32019-09-17 01:21:23 -06003702 }
3703
3704 // Mark the image as acquired.
3705 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003706 if (swapchain_data) {
3707 swapchain_data->AcquireImage(*pImageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003708 }
3709}
3710
3711void ValidationStateTracker::PostCallRecordAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3712 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex,
3713 VkResult result) {
3714 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3715 RecordAcquireNextImageState(device, swapchain, timeout, semaphore, fence, pImageIndex);
3716}
3717
3718void ValidationStateTracker::PostCallRecordAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
3719 uint32_t *pImageIndex, VkResult result) {
3720 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3721 RecordAcquireNextImageState(device, pAcquireInfo->swapchain, pAcquireInfo->timeout, pAcquireInfo->semaphore,
3722 pAcquireInfo->fence, pImageIndex);
3723}
3724
3725void ValidationStateTracker::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
3726 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
3727 if ((NULL != pPhysicalDevices) && ((result == VK_SUCCESS || result == VK_INCOMPLETE))) {
3728 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
3729 auto &phys_device_state = physical_device_map[pPhysicalDevices[i]];
3730 phys_device_state.phys_device = pPhysicalDevices[i];
3731 // Init actual features for each physical device
3732 DispatchGetPhysicalDeviceFeatures(pPhysicalDevices[i], &phys_device_state.features2.features);
3733 }
3734 }
3735}
3736
3737// Common function to update state for GetPhysicalDeviceQueueFamilyProperties & 2KHR version
3738static void StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003739 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003740 pd_state->queue_family_known_count = std::max(pd_state->queue_family_known_count, count);
3741
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003742 if (pQueueFamilyProperties) { // Save queue family properties
locke-lunargd556cc32019-09-17 01:21:23 -06003743 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
3744 for (uint32_t i = 0; i < count; ++i) {
3745 pd_state->queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
3746 }
3747 }
3748}
3749
3750void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
3751 uint32_t *pQueueFamilyPropertyCount,
3752 VkQueueFamilyProperties *pQueueFamilyProperties) {
3753 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3754 assert(physical_device_state);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003755 VkQueueFamilyProperties2 *pqfp = nullptr;
3756 std::vector<VkQueueFamilyProperties2> qfp;
locke-lunargd556cc32019-09-17 01:21:23 -06003757 qfp.resize(*pQueueFamilyPropertyCount);
3758 if (pQueueFamilyProperties) {
3759 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003760 qfp[i] = LvlInitStruct<VkQueueFamilyProperties2>();
locke-lunargd556cc32019-09-17 01:21:23 -06003761 qfp[i].queueFamilyProperties = pQueueFamilyProperties[i];
3762 }
3763 pqfp = qfp.data();
3764 }
3765 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount, pqfp);
3766}
3767
3768void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003769 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003770 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3771 assert(physical_device_state);
3772 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3773 pQueueFamilyProperties);
3774}
3775
3776void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003777 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003778 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3779 assert(physical_device_state);
3780 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3781 pQueueFamilyProperties);
3782}
3783void ValidationStateTracker::PreCallRecordDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
3784 const VkAllocationCallbacks *pAllocator) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003785 if (!surface) return;
3786 auto surface_state = GetSurfaceState(surface);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003787 surface_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06003788 surface_map.erase(surface);
3789}
3790
3791void ValidationStateTracker::RecordVulkanSurface(VkSurfaceKHR *pSurface) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003792 surface_map[*pSurface] = std::make_shared<SURFACE_STATE>(*pSurface);
locke-lunargd556cc32019-09-17 01:21:23 -06003793}
3794
3795void ValidationStateTracker::PostCallRecordCreateDisplayPlaneSurfaceKHR(VkInstance instance,
3796 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
3797 const VkAllocationCallbacks *pAllocator,
3798 VkSurfaceKHR *pSurface, VkResult result) {
3799 if (VK_SUCCESS != result) return;
3800 RecordVulkanSurface(pSurface);
3801}
3802
3803#ifdef VK_USE_PLATFORM_ANDROID_KHR
3804void ValidationStateTracker::PostCallRecordCreateAndroidSurfaceKHR(VkInstance instance,
3805 const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
3806 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3807 VkResult result) {
3808 if (VK_SUCCESS != result) return;
3809 RecordVulkanSurface(pSurface);
3810}
3811#endif // VK_USE_PLATFORM_ANDROID_KHR
3812
3813#ifdef VK_USE_PLATFORM_IOS_MVK
3814void ValidationStateTracker::PostCallRecordCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
3815 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3816 VkResult result) {
3817 if (VK_SUCCESS != result) return;
3818 RecordVulkanSurface(pSurface);
3819}
3820#endif // VK_USE_PLATFORM_IOS_MVK
3821
3822#ifdef VK_USE_PLATFORM_MACOS_MVK
3823void ValidationStateTracker::PostCallRecordCreateMacOSSurfaceMVK(VkInstance instance,
3824 const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
3825 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3826 VkResult result) {
3827 if (VK_SUCCESS != result) return;
3828 RecordVulkanSurface(pSurface);
3829}
3830#endif // VK_USE_PLATFORM_MACOS_MVK
3831
Jeremy Kniagerf33a67c2019-12-09 09:44:39 -07003832#ifdef VK_USE_PLATFORM_METAL_EXT
3833void ValidationStateTracker::PostCallRecordCreateMetalSurfaceEXT(VkInstance instance,
3834 const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
3835 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3836 VkResult result) {
3837 if (VK_SUCCESS != result) return;
3838 RecordVulkanSurface(pSurface);
3839}
3840#endif // VK_USE_PLATFORM_METAL_EXT
3841
locke-lunargd556cc32019-09-17 01:21:23 -06003842#ifdef VK_USE_PLATFORM_WAYLAND_KHR
3843void ValidationStateTracker::PostCallRecordCreateWaylandSurfaceKHR(VkInstance instance,
3844 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
3845 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3846 VkResult result) {
3847 if (VK_SUCCESS != result) return;
3848 RecordVulkanSurface(pSurface);
3849}
3850#endif // VK_USE_PLATFORM_WAYLAND_KHR
3851
3852#ifdef VK_USE_PLATFORM_WIN32_KHR
3853void ValidationStateTracker::PostCallRecordCreateWin32SurfaceKHR(VkInstance instance,
3854 const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
3855 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3856 VkResult result) {
3857 if (VK_SUCCESS != result) return;
3858 RecordVulkanSurface(pSurface);
3859}
3860#endif // VK_USE_PLATFORM_WIN32_KHR
3861
3862#ifdef VK_USE_PLATFORM_XCB_KHR
3863void ValidationStateTracker::PostCallRecordCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
3864 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3865 VkResult result) {
3866 if (VK_SUCCESS != result) return;
3867 RecordVulkanSurface(pSurface);
3868}
3869#endif // VK_USE_PLATFORM_XCB_KHR
3870
3871#ifdef VK_USE_PLATFORM_XLIB_KHR
3872void ValidationStateTracker::PostCallRecordCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
3873 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3874 VkResult result) {
3875 if (VK_SUCCESS != result) return;
3876 RecordVulkanSurface(pSurface);
3877}
3878#endif // VK_USE_PLATFORM_XLIB_KHR
3879
Niklas Haas8b84af12020-04-19 22:20:11 +02003880void ValidationStateTracker::PostCallRecordCreateHeadlessSurfaceEXT(VkInstance instance,
3881 const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
3882 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3883 VkResult result) {
3884 if (VK_SUCCESS != result) return;
3885 RecordVulkanSurface(pSurface);
3886}
3887
Cort23cf2282019-09-20 18:58:18 +02003888void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02003889 VkPhysicalDeviceFeatures *pFeatures) {
3890 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Yilong Li358152a2020-07-08 02:16:45 -07003891 // Reset the features2 safe struct before setting up the features field.
3892 physical_device_state->features2 = safe_VkPhysicalDeviceFeatures2();
Cortffba2642019-09-20 22:09:41 +02003893 physical_device_state->features2.features = *pFeatures;
Cort23cf2282019-09-20 18:58:18 +02003894}
3895
3896void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02003897 VkPhysicalDeviceFeatures2 *pFeatures) {
3898 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02003899 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02003900}
3901
3902void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02003903 VkPhysicalDeviceFeatures2 *pFeatures) {
3904 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02003905 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02003906}
3907
locke-lunargd556cc32019-09-17 01:21:23 -06003908void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
3909 VkSurfaceKHR surface,
3910 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities,
3911 VkResult result) {
3912 if (VK_SUCCESS != result) return;
3913 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003914 physical_device_state->surfaceCapabilities = *pSurfaceCapabilities;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003915
3916 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
3917 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06003918}
3919
3920void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(
3921 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
3922 VkSurfaceCapabilities2KHR *pSurfaceCapabilities, VkResult result) {
3923 if (VK_SUCCESS != result) return;
3924 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003925 physical_device_state->surfaceCapabilities = pSurfaceCapabilities->surfaceCapabilities;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003926
3927 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
3928 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06003929}
3930
3931void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,
3932 VkSurfaceKHR surface,
3933 VkSurfaceCapabilities2EXT *pSurfaceCapabilities,
3934 VkResult result) {
3935 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003936 physical_device_state->surfaceCapabilities.minImageCount = pSurfaceCapabilities->minImageCount;
3937 physical_device_state->surfaceCapabilities.maxImageCount = pSurfaceCapabilities->maxImageCount;
3938 physical_device_state->surfaceCapabilities.currentExtent = pSurfaceCapabilities->currentExtent;
3939 physical_device_state->surfaceCapabilities.minImageExtent = pSurfaceCapabilities->minImageExtent;
3940 physical_device_state->surfaceCapabilities.maxImageExtent = pSurfaceCapabilities->maxImageExtent;
3941 physical_device_state->surfaceCapabilities.maxImageArrayLayers = pSurfaceCapabilities->maxImageArrayLayers;
3942 physical_device_state->surfaceCapabilities.supportedTransforms = pSurfaceCapabilities->supportedTransforms;
3943 physical_device_state->surfaceCapabilities.currentTransform = pSurfaceCapabilities->currentTransform;
3944 physical_device_state->surfaceCapabilities.supportedCompositeAlpha = pSurfaceCapabilities->supportedCompositeAlpha;
3945 physical_device_state->surfaceCapabilities.supportedUsageFlags = pSurfaceCapabilities->supportedUsageFlags;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003946
3947 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
3948 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06003949}
3950
3951void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
3952 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
3953 VkBool32 *pSupported, VkResult result) {
3954 if (VK_SUCCESS != result) return;
3955 auto surface_state = GetSurfaceState(surface);
3956 surface_state->gpu_queue_support[{physicalDevice, queueFamilyIndex}] = (*pSupported == VK_TRUE);
3957}
3958
3959void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
3960 VkSurfaceKHR surface,
3961 uint32_t *pPresentModeCount,
3962 VkPresentModeKHR *pPresentModes,
3963 VkResult result) {
3964 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
3965
3966 // TODO: This isn't quite right -- available modes may differ by surface AND physical device.
3967 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003968
3969 if (*pPresentModeCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003970 if (*pPresentModeCount > physical_device_state->present_modes.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06003971 physical_device_state->present_modes.resize(*pPresentModeCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003972 }
locke-lunargd556cc32019-09-17 01:21:23 -06003973 }
3974 if (pPresentModes) {
locke-lunargd556cc32019-09-17 01:21:23 -06003975 for (uint32_t i = 0; i < *pPresentModeCount; i++) {
3976 physical_device_state->present_modes[i] = pPresentModes[i];
3977 }
3978 }
3979}
3980
3981void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
3982 uint32_t *pSurfaceFormatCount,
3983 VkSurfaceFormatKHR *pSurfaceFormats,
3984 VkResult result) {
3985 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
3986
3987 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003988
3989 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003990 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06003991 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003992 }
locke-lunargd556cc32019-09-17 01:21:23 -06003993 }
3994 if (pSurfaceFormats) {
locke-lunargd556cc32019-09-17 01:21:23 -06003995 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
3996 physical_device_state->surface_formats[i] = pSurfaceFormats[i];
3997 }
3998 }
3999}
4000
4001void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
4002 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
4003 uint32_t *pSurfaceFormatCount,
4004 VkSurfaceFormat2KHR *pSurfaceFormats,
4005 VkResult result) {
4006 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4007
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004008 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004009 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004010 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
4011 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
4012 }
locke-lunargd556cc32019-09-17 01:21:23 -06004013 }
4014 if (pSurfaceFormats) {
locke-lunargd556cc32019-09-17 01:21:23 -06004015 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004016 physical_device_state->surface_formats[i] = pSurfaceFormats[i].surfaceFormat;
locke-lunargd556cc32019-09-17 01:21:23 -06004017 }
4018 }
4019}
4020
4021void ValidationStateTracker::PreCallRecordCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4022 const VkDebugUtilsLabelEXT *pLabelInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004023 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
4024 cb_state->RecordCmd(CMD_BEGINDEBUGUTILSLABELEXT);
locke-lunargd556cc32019-09-17 01:21:23 -06004025 BeginCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4026}
4027
4028void ValidationStateTracker::PostCallRecordCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004029 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
4030 cb_state->RecordCmd(CMD_ENDDEBUGUTILSLABELEXT);
locke-lunargd556cc32019-09-17 01:21:23 -06004031 EndCmdDebugUtilsLabel(report_data, commandBuffer);
4032}
4033
4034void ValidationStateTracker::PreCallRecordCmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4035 const VkDebugUtilsLabelEXT *pLabelInfo) {
4036 InsertCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4037
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004038 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004039 cb_state->RecordCmd(CMD_INSERTDEBUGUTILSLABELEXT);
4040 // Squirrel away an easily accessible copy.
locke-lunargd556cc32019-09-17 01:21:23 -06004041 cb_state->debug_label = LoggingLabel(pLabelInfo);
4042}
4043
4044void ValidationStateTracker::RecordEnumeratePhysicalDeviceGroupsState(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004045 uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06004046 if (NULL != pPhysicalDeviceGroupProperties) {
4047 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
4048 for (uint32_t j = 0; j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount; j++) {
4049 VkPhysicalDevice cur_phys_dev = pPhysicalDeviceGroupProperties[i].physicalDevices[j];
4050 auto &phys_device_state = physical_device_map[cur_phys_dev];
4051 phys_device_state.phys_device = cur_phys_dev;
4052 // Init actual features for each physical device
4053 DispatchGetPhysicalDeviceFeatures(cur_phys_dev, &phys_device_state.features2.features);
4054 }
4055 }
4056 }
4057}
4058
4059void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroups(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004060 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004061 VkResult result) {
4062 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4063 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4064}
4065
4066void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroupsKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004067 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004068 VkResult result) {
4069 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4070 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4071}
4072
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004073void ValidationStateTracker::RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(VkPhysicalDevice physicalDevice,
4074 uint32_t queueFamilyIndex,
4075 uint32_t *pCounterCount,
4076 VkPerformanceCounterKHR *pCounters) {
4077 if (NULL == pCounters) return;
4078
4079 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4080 assert(physical_device_state);
4081
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004082 std::unique_ptr<QUEUE_FAMILY_PERF_COUNTERS> queue_family_counters(new QUEUE_FAMILY_PERF_COUNTERS());
4083 queue_family_counters->counters.resize(*pCounterCount);
4084 for (uint32_t i = 0; i < *pCounterCount; i++) queue_family_counters->counters[i] = pCounters[i];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004085
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004086 physical_device_state->perf_counters[queueFamilyIndex] = std::move(queue_family_counters);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004087}
4088
4089void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
4090 VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t *pCounterCount, VkPerformanceCounterKHR *pCounters,
4091 VkPerformanceCounterDescriptionKHR *pCounterDescriptions, VkResult result) {
4092 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4093 RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(physicalDevice, queueFamilyIndex, pCounterCount, pCounters);
4094}
4095
4096void ValidationStateTracker::PostCallRecordAcquireProfilingLockKHR(VkDevice device, const VkAcquireProfilingLockInfoKHR *pInfo,
4097 VkResult result) {
4098 if (result == VK_SUCCESS) performance_lock_acquired = true;
4099}
4100
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004101void ValidationStateTracker::PostCallRecordReleaseProfilingLockKHR(VkDevice device) {
4102 performance_lock_acquired = false;
4103 for (auto &cmd_buffer : commandBufferMap) {
4104 cmd_buffer.second->performance_lock_released = true;
4105 }
4106}
4107
locke-lunargd556cc32019-09-17 01:21:23 -06004108void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplate(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004109 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004110 const VkAllocationCallbacks *pAllocator) {
4111 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004112 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4113 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004114 desc_template_map.erase(descriptorUpdateTemplate);
4115}
4116
4117void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplateKHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004118 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004119 const VkAllocationCallbacks *pAllocator) {
4120 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004121 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4122 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004123 desc_template_map.erase(descriptorUpdateTemplate);
4124}
4125
Mike Schuchardt2df08912020-12-15 16:28:09 -08004126void ValidationStateTracker::RecordCreateDescriptorUpdateTemplateState(const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4127 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
locke-lunargd556cc32019-09-17 01:21:23 -06004128 safe_VkDescriptorUpdateTemplateCreateInfo local_create_info(pCreateInfo);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004129 auto template_state = std::make_shared<TEMPLATE_STATE>(*pDescriptorUpdateTemplate, &local_create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004130 desc_template_map[*pDescriptorUpdateTemplate] = std::move(template_state);
4131}
4132
Mike Schuchardt2df08912020-12-15 16:28:09 -08004133void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplate(VkDevice device,
4134 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4135 const VkAllocationCallbacks *pAllocator,
4136 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate,
4137 VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004138 if (VK_SUCCESS != result) return;
4139 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4140}
4141
4142void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplateKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004143 VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
4144 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004145 if (VK_SUCCESS != result) return;
4146 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4147}
4148
4149void ValidationStateTracker::RecordUpdateDescriptorSetWithTemplateState(VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004150 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004151 const void *pData) {
4152 auto const template_map_entry = desc_template_map.find(descriptorUpdateTemplate);
4153 if ((template_map_entry == desc_template_map.end()) || (template_map_entry->second.get() == nullptr)) {
4154 assert(0);
4155 } else {
4156 const TEMPLATE_STATE *template_state = template_map_entry->second.get();
4157 // TODO: Record template push descriptor updates
4158 if (template_state->create_info.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET) {
4159 PerformUpdateDescriptorSetsWithTemplateKHR(descriptorSet, template_state, pData);
4160 }
4161 }
4162}
4163
4164void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
4165 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4166 const void *pData) {
4167 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4168}
4169
4170void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004171 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004172 const void *pData) {
4173 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4174}
4175
Mike Schuchardt2df08912020-12-15 16:28:09 -08004176void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
4177 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4178 VkPipelineLayout layout, uint32_t set,
4179 const void *pData) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004180 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004181
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004182 cb_state->RecordCmd(CMD_PUSHDESCRIPTORSETWITHTEMPLATEKHR);
locke-lunargd556cc32019-09-17 01:21:23 -06004183 const auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4184 if (template_state) {
4185 auto layout_data = GetPipelineLayout(layout);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06004186 auto dsl = layout_data ? layout_data->GetDsl(set) : nullptr;
locke-lunargd556cc32019-09-17 01:21:23 -06004187 const auto &template_ci = template_state->create_info;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004188 // Decode the template into a set of write updates
4189 cvdescriptorset::DecodedTemplateUpdate decoded_template(this, VK_NULL_HANDLE, template_state, pData,
4190 dsl->GetDescriptorSetLayout());
4191 cb_state->PushDescriptorSetState(template_ci.pipelineBindPoint, layout_data, set,
4192 static_cast<uint32_t>(decoded_template.desc_writes.size()),
4193 decoded_template.desc_writes.data());
locke-lunargd556cc32019-09-17 01:21:23 -06004194 }
4195}
4196
4197void ValidationStateTracker::RecordGetPhysicalDeviceDisplayPlanePropertiesState(VkPhysicalDevice physicalDevice,
4198 uint32_t *pPropertyCount, void *pProperties) {
4199 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4200 if (*pPropertyCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004201 physical_device_state->display_plane_property_count = *pPropertyCount;
4202 }
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004203 if (*pPropertyCount || pProperties) {
4204 physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004205 }
4206}
4207
4208void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
4209 uint32_t *pPropertyCount,
4210 VkDisplayPlanePropertiesKHR *pProperties,
4211 VkResult result) {
4212 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4213 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4214}
4215
4216void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
4217 uint32_t *pPropertyCount,
4218 VkDisplayPlaneProperties2KHR *pProperties,
4219 VkResult result) {
4220 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4221 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4222}
4223
4224void ValidationStateTracker::PostCallRecordCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4225 uint32_t query, VkQueryControlFlags flags, uint32_t index) {
4226 QueryObject query_obj = {queryPool, query, index};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004227 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004228 cb_state->RecordCmd(CMD_BEGINQUERYINDEXEDEXT);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004229 cb_state->BeginQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004230}
4231
4232void ValidationStateTracker::PostCallRecordCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4233 uint32_t query, uint32_t index) {
4234 QueryObject query_obj = {queryPool, query, index};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004235 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004236 cb_state->RecordCmd(CMD_ENDQUERYINDEXEDEXT);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004237 cb_state->EndQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004238}
4239
4240void ValidationStateTracker::RecordCreateSamplerYcbcrConversionState(const VkSamplerYcbcrConversionCreateInfo *create_info,
4241 VkSamplerYcbcrConversion ycbcr_conversion) {
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004242 VkFormatFeatureFlags format_features = 0;
4243
4244 if (create_info->format != VK_FORMAT_UNDEFINED) {
4245 format_features = GetPotentialFormatFeatures(create_info->format);
4246 } else if (device_extensions.vk_android_external_memory_android_hardware_buffer) {
4247 // If format is VK_FORMAT_UNDEFINED, format_features will be set by external AHB features
4248 format_features = GetExternalFormatFeaturesANDROID(create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004249 }
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004250
4251 samplerYcbcrConversionMap[ycbcr_conversion] =
4252 std::make_shared<SAMPLER_YCBCR_CONVERSION_STATE>(ycbcr_conversion, create_info, format_features);
locke-lunargd556cc32019-09-17 01:21:23 -06004253}
4254
4255void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversion(VkDevice device,
4256 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4257 const VkAllocationCallbacks *pAllocator,
4258 VkSamplerYcbcrConversion *pYcbcrConversion,
4259 VkResult result) {
4260 if (VK_SUCCESS != result) return;
4261 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4262}
4263
4264void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversionKHR(VkDevice device,
4265 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4266 const VkAllocationCallbacks *pAllocator,
4267 VkSamplerYcbcrConversion *pYcbcrConversion,
4268 VkResult result) {
4269 if (VK_SUCCESS != result) return;
4270 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4271}
4272
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004273void ValidationStateTracker::RecordDestroySamplerYcbcrConversionState(VkSamplerYcbcrConversion ycbcr_conversion) {
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004274 auto ycbcr_state = GetSamplerYcbcrConversionState(ycbcr_conversion);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004275 ycbcr_state->Destroy();
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004276 samplerYcbcrConversionMap.erase(ycbcr_conversion);
4277}
4278
locke-lunargd556cc32019-09-17 01:21:23 -06004279void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
4280 const VkAllocationCallbacks *pAllocator) {
4281 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004282 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004283}
4284
4285void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversionKHR(VkDevice device,
4286 VkSamplerYcbcrConversion ycbcrConversion,
4287 const VkAllocationCallbacks *pAllocator) {
4288 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004289 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004290}
4291
Tony-LunarG977448c2019-12-02 14:52:02 -07004292void ValidationStateTracker::RecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4293 uint32_t queryCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004294 // Do nothing if the feature is not enabled.
Piers Daniell41b8c5d2020-01-10 15:42:00 -07004295 if (!enabled_features.core12.hostQueryReset) return;
locke-lunargd556cc32019-09-17 01:21:23 -06004296
4297 // Do nothing if the query pool has been destroyed.
4298 auto query_pool_state = GetQueryPoolState(queryPool);
4299 if (!query_pool_state) return;
4300
4301 // Reset the state of existing entries.
4302 QueryObject query_obj{queryPool, 0};
4303 const uint32_t max_query_count = std::min(queryCount, query_pool_state->createInfo.queryCount - firstQuery);
4304 for (uint32_t i = 0; i < max_query_count; ++i) {
4305 query_obj.query = firstQuery + i;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004306 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004307 if (query_pool_state->createInfo.queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004308 for (uint32_t pass_index = 0; pass_index < query_pool_state->n_performance_passes; pass_index++) {
4309 query_obj.perf_pass = pass_index;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004310 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004311 }
4312 }
locke-lunargd556cc32019-09-17 01:21:23 -06004313 }
4314}
4315
Tony-LunarG977448c2019-12-02 14:52:02 -07004316void ValidationStateTracker::PostCallRecordResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4317 uint32_t queryCount) {
4318 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4319}
4320
4321void ValidationStateTracker::PostCallRecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4322 uint32_t queryCount) {
4323 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4324}
4325
locke-lunargd556cc32019-09-17 01:21:23 -06004326void ValidationStateTracker::PerformUpdateDescriptorSetsWithTemplateKHR(VkDescriptorSet descriptorSet,
4327 const TEMPLATE_STATE *template_state, const void *pData) {
4328 // Translate the templated update into a normal update for validation...
4329 cvdescriptorset::DecodedTemplateUpdate decoded_update(this, descriptorSet, template_state, pData);
4330 cvdescriptorset::PerformUpdateDescriptorSets(this, static_cast<uint32_t>(decoded_update.desc_writes.size()),
4331 decoded_update.desc_writes.data(), 0, NULL);
4332}
4333
4334// Update the common AllocateDescriptorSetsData
4335void ValidationStateTracker::UpdateAllocateDescriptorSetsData(const VkDescriptorSetAllocateInfo *p_alloc_info,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05004336 cvdescriptorset::AllocateDescriptorSetsData *ds_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004337 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05004338 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06004339 if (layout) {
4340 ds_data->layout_nodes[i] = layout;
4341 // Count total descriptors required per type
4342 for (uint32_t j = 0; j < layout->GetBindingCount(); ++j) {
4343 const auto &binding_layout = layout->GetDescriptorSetLayoutBindingPtrFromIndex(j);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004344 uint32_t type_index = static_cast<uint32_t>(binding_layout->descriptorType);
4345 ds_data->required_descriptors_by_type[type_index] += binding_layout->descriptorCount;
locke-lunargd556cc32019-09-17 01:21:23 -06004346 }
4347 }
4348 // Any unknown layouts will be flagged as errors during ValidateAllocateDescriptorSets() call
4349 }
4350}
4351
4352// Decrement allocated sets from the pool and insert new sets into set_map
4353void ValidationStateTracker::PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
4354 const VkDescriptorSet *descriptor_sets,
4355 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) {
4356 auto pool_state = descriptorPoolMap[p_alloc_info->descriptorPool].get();
4357 // Account for sets and individual descriptors allocated from pool
4358 pool_state->availableSets -= p_alloc_info->descriptorSetCount;
4359 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
4360 pool_state->availableDescriptorTypeCount[it->first] -= ds_data->required_descriptors_by_type.at(it->first);
4361 }
4362
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07004363 const auto *variable_count_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(p_alloc_info->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06004364 bool variable_count_valid = variable_count_info && variable_count_info->descriptorSetCount == p_alloc_info->descriptorSetCount;
4365
4366 // Create tracking object for each descriptor set; insert into global map and the pool's set.
4367 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
4368 uint32_t variable_count = variable_count_valid ? variable_count_info->pDescriptorCounts[i] : 0;
4369
Jeff Bolz41a1ced2019-10-11 11:40:49 -05004370 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 -07004371 variable_count, this);
locke-lunargd556cc32019-09-17 01:21:23 -06004372 pool_state->sets.insert(new_ds.get());
locke-lunargd556cc32019-09-17 01:21:23 -06004373 setMap[descriptor_sets[i]] = std::move(new_ds);
4374 }
4375}
4376
locke-lunargd556cc32019-09-17 01:21:23 -06004377void ValidationStateTracker::PostCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
4378 uint32_t firstVertex, uint32_t firstInstance) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004379 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004380 cb_state->UpdateStateCmdDrawType(CMD_DRAW, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDraw()");
locke-lunargd556cc32019-09-17 01:21:23 -06004381}
4382
Tony-LunarG745150c2021-07-02 15:07:31 -06004383void ValidationStateTracker::PostCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4384 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
4385 uint32_t firstInstance, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004386 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004387 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004388}
4389
locke-lunargd556cc32019-09-17 01:21:23 -06004390void ValidationStateTracker::PostCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
4391 uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
4392 uint32_t firstInstance) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004393 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004394 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXED, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexed()");
locke-lunargd556cc32019-09-17 01:21:23 -06004395}
4396
Tony-LunarG745150c2021-07-02 15:07:31 -06004397void ValidationStateTracker::PostCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4398 const VkMultiDrawIndexedInfoEXT *pIndexInfo,
4399 uint32_t instanceCount, uint32_t firstInstance, uint32_t stride,
4400 const int32_t *pVertexOffset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004401 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004402 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIINDEXEDEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiIndexedEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004403}
4404
locke-lunargd556cc32019-09-17 01:21:23 -06004405void ValidationStateTracker::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4406 uint32_t count, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004407 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004408 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004409 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004410 if (!disabled[command_buffer_state]) {
4411 cb_state->AddChild(buffer_state);
4412 }
locke-lunargd556cc32019-09-17 01:21:23 -06004413}
4414
4415void ValidationStateTracker::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4416 VkDeviceSize offset, uint32_t count, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004417 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004418 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004419 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexedIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004420 if (!disabled[command_buffer_state]) {
4421 cb_state->AddChild(buffer_state);
4422 }
locke-lunargd556cc32019-09-17 01:21:23 -06004423}
4424
4425void ValidationStateTracker::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004426 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004427 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCH, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatch()");
locke-lunargd556cc32019-09-17 01:21:23 -06004428}
4429
4430void ValidationStateTracker::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4431 VkDeviceSize offset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004432 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004433 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCHINDIRECT, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatchIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004434 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004435 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004436 cb_state->AddChild(buffer_state);
4437 }
locke-lunargd556cc32019-09-17 01:21:23 -06004438}
4439
Tony-LunarG977448c2019-12-02 14:52:02 -07004440void ValidationStateTracker::RecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4441 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
locke-lunarg540b2252020-08-03 13:23:36 -06004442 uint32_t stride, const char *function) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004443 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004444 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004445 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004446 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4447 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004448 cb_state->AddChild(buffer_state);
4449 cb_state->AddChild(count_buffer_state);
4450 }
Tony-LunarG977448c2019-12-02 14:52:02 -07004451}
4452
locke-lunargd556cc32019-09-17 01:21:23 -06004453void ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4454 VkDeviceSize offset, VkBuffer countBuffer,
4455 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4456 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004457 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4458 "vkCmdDrawIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004459}
4460
4461void ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4462 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
4463 uint32_t maxDrawCount, uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004464 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4465 "vkCmdDrawIndirectCount()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004466}
4467
4468void ValidationStateTracker::RecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4469 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
locke-lunarg540b2252020-08-03 13:23:36 -06004470 uint32_t maxDrawCount, uint32_t stride, const char *function) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004471 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004472 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004473 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004474 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4475 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004476 cb_state->AddChild(buffer_state);
4477 cb_state->AddChild(count_buffer_state);
4478 }
locke-lunargd556cc32019-09-17 01:21:23 -06004479}
4480
4481void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4482 VkDeviceSize offset, VkBuffer countBuffer,
4483 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4484 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004485 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4486 "vkCmdDrawIndexedIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004487}
4488
4489void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
4490 VkDeviceSize offset, VkBuffer countBuffer,
4491 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4492 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004493 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4494 "vkCmdDrawIndexedIndirectCount()");
locke-lunargd556cc32019-09-17 01:21:23 -06004495}
4496
4497void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount,
4498 uint32_t firstTask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004499 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004500 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSNV, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMeshTasksNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004501}
4502
4503void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4504 VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004505 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004506 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4507 "vkCmdDrawMeshTasksIndirectNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004508 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004509 if (!disabled[command_buffer_state] && buffer_state) {
4510 cb_state->AddChild(buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -06004511 }
4512}
4513
4514void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4515 VkDeviceSize offset, VkBuffer countBuffer,
4516 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4517 uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004518 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004519 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTCOUNTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4520 "vkCmdDrawMeshTasksIndirectCountNV()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004521 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004522 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4523 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004524 if (buffer_state) {
4525 cb_state->AddChild(buffer_state);
4526 }
4527 if (count_buffer_state) {
4528 cb_state->AddChild(count_buffer_state);
4529 }
locke-lunargd556cc32019-09-17 01:21:23 -06004530 }
4531}
4532
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004533void ValidationStateTracker::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
4534 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
4535 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
4536 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
4537 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
4538 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
4539 uint32_t width, uint32_t height, uint32_t depth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004540 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004541 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSNV, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, "vkCmdTraceRaysNV()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004542 cb_state->hasTraceRaysCmd = true;
4543}
4544
4545
4546void ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
4547 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4548 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4549 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4550 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
4551 uint32_t height, uint32_t depth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004552 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004553 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, "vkCmdTraceRaysKHR()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004554 cb_state->hasTraceRaysCmd = true;
4555}
4556
4557void ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
4558 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4559 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4560 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4561 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
4562 VkDeviceAddress indirectDeviceAddress) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004563 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004564 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSINDIRECTKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004565 "vkCmdTraceRaysIndirectKHR()");
4566 cb_state->hasTraceRaysCmd = true;
4567}
4568
locke-lunargd556cc32019-09-17 01:21:23 -06004569void ValidationStateTracker::PostCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
4570 const VkAllocationCallbacks *pAllocator,
4571 VkShaderModule *pShaderModule, VkResult result,
4572 void *csm_state_data) {
4573 if (VK_SUCCESS != result) return;
4574 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
4575
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06004576 spv_target_env spirv_environment = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
locke-lunargd556cc32019-09-17 01:21:23 -06004577 bool is_spirv = (pCreateInfo->pCode[0] == spv::MagicNumber);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004578 auto new_shader_module = is_spirv ? std::make_shared<SHADER_MODULE_STATE>(pCreateInfo, *pShaderModule, spirv_environment,
4579 csm_state->unique_shader_id)
4580 : std::make_shared<SHADER_MODULE_STATE>();
sfricke-samsung962cad92021-04-13 00:46:29 -07004581 new_shader_module->SetPushConstantUsedInShader();
locke-lunargd556cc32019-09-17 01:21:23 -06004582 shaderModuleMap[*pShaderModule] = std::move(new_shader_module);
4583}
4584
4585void ValidationStateTracker::RecordPipelineShaderStage(VkPipelineShaderStageCreateInfo const *pStage, PIPELINE_STATE *pipeline,
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06004586 PipelineStageState *stage_state) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004587 // Validation shouldn't rely on anything in stage state being valid if the spirv isn't
locke-lunargde3f0fa2020-09-10 11:55:31 -06004588 stage_state->entry_point_name = pStage->pName;
4589 stage_state->shader_state = GetShared<SHADER_MODULE_STATE>(pStage->module);
4590 auto module = stage_state->shader_state.get();
locke-lunargd556cc32019-09-17 01:21:23 -06004591 if (!module->has_valid_spirv) return;
4592
4593 // Validation shouldn't rely on anything in stage state being valid if the entrypoint isn't present
sfricke-samsung962cad92021-04-13 00:46:29 -07004594 auto entrypoint = module->FindEntrypoint(pStage->pName, pStage->stage);
locke-lunargd556cc32019-09-17 01:21:23 -06004595 if (entrypoint == module->end()) return;
4596
locke-lunarg654e3692020-06-04 17:19:15 -06004597 stage_state->stage_flag = pStage->stage;
4598
locke-lunargd556cc32019-09-17 01:21:23 -06004599 // Mark accessible ids
sfricke-samsung962cad92021-04-13 00:46:29 -07004600 stage_state->accessible_ids = module->MarkAccessibleIds(entrypoint);
4601 module->ProcessExecutionModes(entrypoint, pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06004602
sfricke-samsung962cad92021-04-13 00:46:29 -07004603 stage_state->descriptor_uses = module->CollectInterfaceByDescriptorSlot(
4604 stage_state->accessible_ids, &stage_state->has_writable_descriptor, &stage_state->has_atomic_descriptor);
locke-lunargd556cc32019-09-17 01:21:23 -06004605 // Capture descriptor uses for the pipeline
locke-lunarg36045992020-08-20 16:54:37 -06004606 for (const auto &use : stage_state->descriptor_uses) {
locke-lunargd556cc32019-09-17 01:21:23 -06004607 // While validating shaders capture which slots are used by the pipeline
Jeremy Gebben7fc88a22021-08-25 13:30:45 -06004608 const uint32_t slot = use.first.set;
4609 pipeline->active_slots[slot][use.first.binding].is_writable |= use.second.is_writable;
4610 auto &reqs = pipeline->active_slots[slot][use.first.binding].reqs;
Jeremy Gebben90ce4162021-08-25 14:23:07 -06004611 reqs |= module->DescriptorTypeToReqs(use.second.type_id);
4612 if (use.second.is_atomic_operation) reqs |= DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION;
4613 if (use.second.is_sampler_implicitLod_dref_proj) reqs |= DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ;
4614 if (use.second.is_sampler_bias_offset) reqs |= DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET;
locke-lunarg12d20992020-09-21 12:46:49 -06004615
John Zulauf649edd52019-10-02 14:39:41 -06004616 pipeline->max_active_slot = std::max(pipeline->max_active_slot, slot);
locke-lunarg36045992020-08-20 16:54:37 -06004617 if (use.second.samplers_used_by_image.size()) {
Jeremy Gebben7fc88a22021-08-25 13:30:45 -06004618 auto &samplers_used_by_image = pipeline->active_slots[slot][use.first.binding].samplers_used_by_image;
locke-lunarg654a9052020-10-13 16:28:42 -06004619 if (use.second.samplers_used_by_image.size() > samplers_used_by_image.size()) {
4620 samplers_used_by_image.resize(use.second.samplers_used_by_image.size());
4621 }
locke-lunarg654a9052020-10-13 16:28:42 -06004622 uint32_t image_index = 0;
4623 for (const auto &samplers : use.second.samplers_used_by_image) {
4624 for (const auto &sampler : samplers) {
locke-lunargb8be8222020-10-20 00:34:37 -06004625 samplers_used_by_image[image_index].emplace(sampler, nullptr);
locke-lunarg654a9052020-10-13 16:28:42 -06004626 }
4627 ++image_index;
4628 }
locke-lunarg36045992020-08-20 16:54:37 -06004629 }
locke-lunargd556cc32019-09-17 01:21:23 -06004630 }
locke-lunarg78486832020-09-09 19:39:42 -06004631
locke-lunarg96dc9632020-06-10 17:22:18 -06004632 if (pStage->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
sfricke-samsung962cad92021-04-13 00:46:29 -07004633 pipeline->fragmentShader_writable_output_location_list = module->CollectWritableOutputLocationinFS(*pStage);
locke-lunarg96dc9632020-06-10 17:22:18 -06004634 }
locke-lunargd556cc32019-09-17 01:21:23 -06004635}
4636
John Zulauf22b0fbe2019-10-15 06:26:16 -06004637void ValidationStateTracker::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
4638 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages,
4639 VkResult result) {
4640 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004641 auto swapchain_state = GetShared<SWAPCHAIN_NODE>(swapchain);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004642
4643 if (*pSwapchainImageCount > swapchain_state->images.size()) swapchain_state->images.resize(*pSwapchainImageCount);
4644
4645 if (pSwapchainImages) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004646 for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
John Zulauf29d00532021-03-04 13:28:54 -07004647 SWAPCHAIN_IMAGE &swapchain_image = swapchain_state->images[i];
John Zulauffaa7a522021-03-05 12:22:45 -07004648 if (swapchain_image.image_state) continue; // Already retrieved this.
John Zulauf22b0fbe2019-10-15 06:26:16 -06004649
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004650 auto format_features =
4651 GetImageFormatFeatures(physical_device, device, pSwapchainImages[i], swapchain_state->image_create_info.format,
4652 swapchain_state->image_create_info.tiling);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004653
Jeremy Gebbenbcba6d32021-07-16 11:41:41 -06004654 auto image_state = std::make_shared<IMAGE_STATE>(device, pSwapchainImages[i], swapchain_state->image_create_info.ptr(),
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004655 swapchain, i, format_features);
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004656 if (!swapchain_image.fake_base_address) {
4657 auto size = image_state->fragment_encoder->TotalSize();
4658 swapchain_image.fake_base_address = fake_memory.Alloc(size);
John Zulauf29d00532021-03-04 13:28:54 -07004659 }
4660
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004661 image_state->SetSwapchain(swapchain_state, i);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004662 swapchain_image.image_state = image_state.get();
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004663 imageMap[pSwapchainImages[i]] = std::move(image_state);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004664 }
4665 }
4666
4667 if (*pSwapchainImageCount) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004668 swapchain_state->get_swapchain_image_count = *pSwapchainImageCount;
4669 }
4670}
sourav parmar35e7a002020-06-09 17:58:44 -07004671
sourav parmar35e7a002020-06-09 17:58:44 -07004672void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer,
4673 const VkCopyAccelerationStructureInfoKHR *pInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004674 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmar35e7a002020-06-09 17:58:44 -07004675 if (cb_state) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004676 cb_state->RecordCmd(CMD_COPYACCELERATIONSTRUCTUREKHR);
sourav parmarcd5fb182020-07-17 12:58:44 -07004677 ACCELERATION_STRUCTURE_STATE_KHR *src_as_state = GetAccelerationStructureStateKHR(pInfo->src);
4678 ACCELERATION_STRUCTURE_STATE_KHR *dst_as_state = GetAccelerationStructureStateKHR(pInfo->dst);
sourav parmar35e7a002020-06-09 17:58:44 -07004679 if (dst_as_state != nullptr && src_as_state != nullptr) {
4680 dst_as_state->built = true;
4681 dst_as_state->build_info_khr = src_as_state->build_info_khr;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004682 if (!disabled[command_buffer_state]) {
4683 cb_state->AddChild(dst_as_state);
4684 cb_state->AddChild(src_as_state);
4685 }
sourav parmar35e7a002020-06-09 17:58:44 -07004686 }
4687 }
4688}
Piers Daniell39842ee2020-07-10 16:42:33 -06004689
4690void ValidationStateTracker::PreCallRecordCmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004691 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004692 cb_state->RecordStateCmd(CMD_SETCULLMODEEXT, CBSTATUS_CULL_MODE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004693}
4694
4695void ValidationStateTracker::PreCallRecordCmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004696 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004697 cb_state->RecordStateCmd(CMD_SETFRONTFACEEXT, CBSTATUS_FRONT_FACE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004698}
4699
4700void ValidationStateTracker::PreCallRecordCmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
4701 VkPrimitiveTopology primitiveTopology) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004702 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004703 cb_state->RecordStateCmd(CMD_SETPRIMITIVETOPOLOGYEXT, CBSTATUS_PRIMITIVE_TOPOLOGY_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004704 cb_state->primitiveTopology = primitiveTopology;
Piers Daniell39842ee2020-07-10 16:42:33 -06004705}
4706
4707void ValidationStateTracker::PreCallRecordCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer, uint32_t viewportCount,
4708 const VkViewport *pViewports) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004709 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004710 cb_state->RecordStateCmd(CMD_SETVIEWPORTWITHCOUNTEXT, CBSTATUS_VIEWPORT_WITH_COUNT_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004711 uint32_t bits = (1u << viewportCount) - 1u;
4712 cb_state->viewportWithCountMask |= bits;
4713 cb_state->trashedViewportMask &= ~bits;
Tobias Hector6663c9b2020-11-05 10:18:02 +00004714 cb_state->viewportWithCountCount = viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004715 cb_state->trashedViewportCount = false;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004716
4717 cb_state->dynamicViewports.resize(std::max(size_t(viewportCount), cb_state->dynamicViewports.size()));
4718 for (size_t i = 0; i < viewportCount; ++i) {
4719 cb_state->dynamicViewports[i] = pViewports[i];
4720 }
Piers Daniell39842ee2020-07-10 16:42:33 -06004721}
4722
4723void ValidationStateTracker::PreCallRecordCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount,
4724 const VkRect2D *pScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004725 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004726 cb_state->RecordStateCmd(CMD_SETSCISSORWITHCOUNTEXT, CBSTATUS_SCISSOR_WITH_COUNT_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004727 uint32_t bits = (1u << scissorCount) - 1u;
4728 cb_state->scissorWithCountMask |= bits;
4729 cb_state->trashedScissorMask &= ~bits;
4730 cb_state->scissorWithCountCount = scissorCount;
4731 cb_state->trashedScissorCount = false;
Piers Daniell39842ee2020-07-10 16:42:33 -06004732}
4733
4734void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
4735 uint32_t bindingCount, const VkBuffer *pBuffers,
4736 const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes,
4737 const VkDeviceSize *pStrides) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004738 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004739 cb_state->RecordStateCmd(CMD_BINDVERTEXBUFFERS2EXT, pStrides ? CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET : CBSTATUS_NONE);
Piers Daniell39842ee2020-07-10 16:42:33 -06004740
4741 uint32_t end = firstBinding + bindingCount;
4742 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
4743 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
4744 }
4745
4746 for (uint32_t i = 0; i < bindingCount; ++i) {
4747 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07004748 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
Piers Daniell39842ee2020-07-10 16:42:33 -06004749 vertex_buffer_binding.offset = pOffsets[i];
4750 vertex_buffer_binding.size = (pSizes) ? pSizes[i] : VK_WHOLE_SIZE;
4751 vertex_buffer_binding.stride = (pStrides) ? pStrides[i] : 0;
4752 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004753 if (!disabled[command_buffer_state] && pBuffers[i]) {
4754 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Piers Daniell39842ee2020-07-10 16:42:33 -06004755 }
4756 }
4757}
4758
4759void ValidationStateTracker::PreCallRecordCmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004760 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004761 cb_state->RecordStateCmd(CMD_SETDEPTHTESTENABLEEXT, CBSTATUS_DEPTH_TEST_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004762}
4763
4764void ValidationStateTracker::PreCallRecordCmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004765 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004766 cb_state->RecordStateCmd(CMD_SETDEPTHWRITEENABLEEXT, CBSTATUS_DEPTH_WRITE_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004767}
4768
4769void ValidationStateTracker::PreCallRecordCmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004770 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004771 cb_state->RecordStateCmd(CMD_SETDEPTHCOMPAREOPEXT, CBSTATUS_DEPTH_COMPARE_OP_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004772}
4773
4774void ValidationStateTracker::PreCallRecordCmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,
4775 VkBool32 depthBoundsTestEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004776 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004777 cb_state->RecordStateCmd(CMD_SETDEPTHBOUNDSTESTENABLEEXT, CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004778}
4779void ValidationStateTracker::PreCallRecordCmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004780 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004781 cb_state->RecordStateCmd(CMD_SETSTENCILTESTENABLEEXT, CBSTATUS_STENCIL_TEST_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004782}
4783
4784void ValidationStateTracker::PreCallRecordCmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
4785 VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
4786 VkCompareOp compareOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004787 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004788 cb_state->RecordStateCmd(CMD_SETSTENCILOPEXT, CBSTATUS_STENCIL_OP_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004789}
locke-lunarg4189aa22020-10-21 00:23:48 -06004790
4791void ValidationStateTracker::PreCallRecordCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle,
4792 uint32_t discardRectangleCount,
4793 const VkRect2D *pDiscardRectangles) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004794 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004795 cb_state->RecordStateCmd(CMD_SETDISCARDRECTANGLEEXT, CBSTATUS_DISCARD_RECTANGLE_SET);
locke-lunarg4189aa22020-10-21 00:23:48 -06004796}
4797
4798void ValidationStateTracker::PreCallRecordCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
4799 const VkSampleLocationsInfoEXT *pSampleLocationsInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004800 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004801 cb_state->RecordStateCmd(CMD_SETSAMPLELOCATIONSEXT, CBSTATUS_SAMPLE_LOCATIONS_SET);
locke-lunarg4189aa22020-10-21 00:23:48 -06004802}
4803
4804void ValidationStateTracker::PreCallRecordCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer,
4805 VkCoarseSampleOrderTypeNV sampleOrderType,
4806 uint32_t customSampleOrderCount,
4807 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004808 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004809 cb_state->RecordStateCmd(CMD_SETCOARSESAMPLEORDERNV, CBSTATUS_COARSE_SAMPLE_ORDER_SET);
locke-lunarg4189aa22020-10-21 00:23:48 -06004810}
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004811
4812void ValidationStateTracker::PreCallRecordCmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, uint32_t patchControlPoints) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004813 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004814 cb_state->RecordStateCmd(CMD_SETPATCHCONTROLPOINTSEXT, CBSTATUS_PATCH_CONTROL_POINTS_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004815}
4816
4817void ValidationStateTracker::PreCallRecordCmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004818 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004819 cb_state->RecordStateCmd(CMD_SETLOGICOPEXT, CBSTATUS_LOGIC_OP_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004820}
4821
4822void ValidationStateTracker::PreCallRecordCmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
4823 VkBool32 rasterizerDiscardEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004824 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004825 cb_state->RecordStateCmd(CMD_SETRASTERIZERDISCARDENABLEEXT, CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004826}
4827
4828void ValidationStateTracker::PreCallRecordCmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004829 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004830 cb_state->RecordStateCmd(CMD_SETDEPTHBIASENABLEEXT, CBSTATUS_DEPTH_BIAS_ENABLE_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004831}
4832
4833void ValidationStateTracker::PreCallRecordCmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,
4834 VkBool32 primitiveRestartEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004835 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004836 cb_state->RecordStateCmd(CMD_SETPRIMITIVERESTARTENABLEEXT, CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004837}
Piers Daniell924cd832021-05-18 13:48:47 -06004838
4839void ValidationStateTracker::PreCallRecordCmdSetVertexInputEXT(
4840 VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount,
4841 const VkVertexInputBindingDescription2EXT *pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount,
4842 const VkVertexInputAttributeDescription2EXT *pVertexAttributeDescriptions) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004843 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg4af0a8c2021-08-27 15:53:20 +02004844 CBStatusFlags status_flags = CBSTATUS_VERTEX_INPUT_SET;
4845
4846 const auto lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS);
4847 const auto pipeline_state = cb_state->lastBound[lv_bind_point].pipeline_state;
4848 if (pipeline_state) {
Jeremy Gebben11af9792021-08-20 10:20:09 -06004849 if (pipeline_state->create_info.graphics.pDynamicState) {
4850 for (uint32_t i = 0; i < pipeline_state->create_info.graphics.pDynamicState->dynamicStateCount; ++i) {
4851 if (pipeline_state->create_info.graphics.pDynamicState->pDynamicStates[i] ==
ziga-lunarg4af0a8c2021-08-27 15:53:20 +02004852 VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT) {
4853 status_flags |= CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET;
4854 break;
4855 }
4856 }
4857 }
4858 }
4859 cb_state->RecordStateCmd(CMD_SETVERTEXINPUTEXT, status_flags);
Piers Daniell924cd832021-05-18 13:48:47 -06004860}
Nathaniel Cesario42ac6ca2021-06-15 17:23:05 -06004861
4862void ValidationStateTracker::RecordGetBufferDeviceAddress(const VkBufferDeviceAddressInfo *pInfo, VkDeviceAddress address) {
4863 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
4864 if (buffer_state) {
4865 // address is used for GPU-AV and ray tracing buffer validation
4866 buffer_state->deviceAddress = address;
4867 buffer_address_map_.emplace(address, buffer_state);
4868 }
4869}
4870
4871void ValidationStateTracker::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
4872 VkDeviceAddress address) {
4873 RecordGetBufferDeviceAddress(pInfo, address);
4874}
4875
4876void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
4877 VkDeviceAddress address) {
4878 RecordGetBufferDeviceAddress(pInfo, address);
4879}
4880
4881void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
4882 VkDeviceAddress address) {
4883 RecordGetBufferDeviceAddress(pInfo, address);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06004884}
4885
4886std::shared_ptr<SWAPCHAIN_NODE> ValidationStateTracker::CreateSwapchainState(const VkSwapchainCreateInfoKHR *create_info,
4887 VkSwapchainKHR swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004888 return std::make_shared<SWAPCHAIN_NODE>(this, create_info, swapchain);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06004889}
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004890
4891std::shared_ptr<CMD_BUFFER_STATE> ValidationStateTracker::CreateCmdBufferState(VkCommandBuffer cb,
4892 const VkCommandBufferAllocateInfo *create_info,
4893 std::shared_ptr<COMMAND_POOL_STATE> &pool) {
4894 return std::make_shared<CMD_BUFFER_STATE>(this, cb, create_info, pool);
4895}