blob: bdefed90e6eaa9a4098a5b24c43093d78b448381 [file] [log] [blame]
sfricke-samsung486a51e2021-01-02 00:10:15 -08001/* Copyright (c) 2015-2021 The Khronos Group Inc.
2 * Copyright (c) 2015-2021 Valve Corporation
3 * Copyright (c) 2015-2021 LunarG, Inc.
4 * Copyright (C) 2015-2021 Google Inc.
Tobias Hector6663c9b2020-11-05 10:18:02 +00005 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
locke-lunargd556cc32019-09-17 01:21:23 -06006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * Author: Mark Lobodzinski <mark@lunarg.com>
20 * Author: Dave Houlton <daveh@lunarg.com>
21 * Shannon McPherson <shannon@lunarg.com>
Tobias Hector6663c9b2020-11-05 10:18:02 +000022 * Author: Tobias Hector <tobias.hector@amd.com>
locke-lunargd556cc32019-09-17 01:21:23 -060023 */
24
David Zhao Akeley44139b12021-04-26 16:16:13 -070025#include <algorithm>
locke-lunargd556cc32019-09-17 01:21:23 -060026#include <cmath>
locke-lunargd556cc32019-09-17 01:21:23 -060027
28#include "vk_enum_string_helper.h"
29#include "vk_format_utils.h"
30#include "vk_layer_data.h"
31#include "vk_layer_utils.h"
32#include "vk_layer_logging.h"
33#include "vk_typemap_helper.h"
34
35#include "chassis.h"
36#include "state_tracker.h"
37#include "shader_validation.h"
Jeremy Gebben74aa7622020-12-15 11:18:00 -070038#include "sync_utils.h"
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060039#include "cmd_buffer_state.h"
40#include "render_pass_state.h"
locke-lunarg4189aa22020-10-21 00:23:48 -060041
Mark Lobodzinskib4ab6ac2020-04-02 13:12:06 -060042void ValidationStateTracker::InitDeviceValidationObject(bool add_obj, ValidationObject *inst_obj, ValidationObject *dev_obj) {
43 if (add_obj) {
44 instance_state = reinterpret_cast<ValidationStateTracker *>(GetValidationObject(inst_obj->object_dispatch, container_type));
45 // Call base class
46 ValidationObject::InitDeviceValidationObject(add_obj, inst_obj, dev_obj);
47 }
48}
49
John Zulauf2bc1fde2020-04-24 15:09:51 -060050// NOTE: Beware the lifespan of the rp_begin when holding the return. If the rp_begin isn't a "safe" copy, "IMAGELESS"
51// attachments won't persist past the API entry point exit.
Jeremy Gebben88f58142021-06-01 10:07:52 -060052static std::pair<uint32_t, const VkImageView *> GetFramebufferAttachments(const VkRenderPassBeginInfo &rp_begin,
53 const FRAMEBUFFER_STATE &fb_state) {
John Zulauf2bc1fde2020-04-24 15:09:51 -060054 const VkImageView *attachments = fb_state.createInfo.pAttachments;
55 uint32_t count = fb_state.createInfo.attachmentCount;
56 if (fb_state.createInfo.flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -070057 const auto *framebuffer_attachments = LvlFindInChain<VkRenderPassAttachmentBeginInfo>(rp_begin.pNext);
John Zulauf2bc1fde2020-04-24 15:09:51 -060058 if (framebuffer_attachments) {
59 attachments = framebuffer_attachments->pAttachments;
60 count = framebuffer_attachments->attachmentCount;
61 }
62 }
63 return std::make_pair(count, attachments);
64}
65
John Zulauf64ffe552021-02-06 10:25:07 -070066template <typename ImageViewPointer, typename Get>
67std::vector<ImageViewPointer> GetAttachmentViewsImpl(const VkRenderPassBeginInfo &rp_begin, const FRAMEBUFFER_STATE &fb_state,
68 const Get &get_fn) {
69 std::vector<ImageViewPointer> views;
John Zulauf2bc1fde2020-04-24 15:09:51 -060070
71 const auto count_attachment = GetFramebufferAttachments(rp_begin, fb_state);
72 const auto attachment_count = count_attachment.first;
73 const auto *attachments = count_attachment.second;
74 views.resize(attachment_count, nullptr);
75 for (uint32_t i = 0; i < attachment_count; i++) {
76 if (attachments[i] != VK_NULL_HANDLE) {
John Zulauf64ffe552021-02-06 10:25:07 -070077 views[i] = get_fn(attachments[i]);
John Zulauf2bc1fde2020-04-24 15:09:51 -060078 }
79 }
80 return views;
81}
82
John Zulauf64ffe552021-02-06 10:25:07 -070083std::vector<std::shared_ptr<const IMAGE_VIEW_STATE>> ValidationStateTracker::GetSharedAttachmentViews(
84 const VkRenderPassBeginInfo &rp_begin, const FRAMEBUFFER_STATE &fb_state) const {
85 auto get_fn = [this](VkImageView handle) { return this->GetShared<IMAGE_VIEW_STATE>(handle); };
86 return GetAttachmentViewsImpl<std::shared_ptr<const IMAGE_VIEW_STATE>>(rp_begin, fb_state, get_fn);
87}
88
locke-lunargd556cc32019-09-17 01:21:23 -060089#ifdef VK_USE_PLATFORM_ANDROID_KHR
90// Android-specific validation that uses types defined only with VK_USE_PLATFORM_ANDROID_KHR
91// This could also move into a seperate core_validation_android.cpp file... ?
92
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -060093template <typename CreateInfo>
94VkFormatFeatureFlags ValidationStateTracker::GetExternalFormatFeaturesANDROID(const CreateInfo *create_info) const {
95 VkFormatFeatureFlags format_features = 0;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -070096 const VkExternalFormatANDROID *ext_fmt_android = LvlFindInChain<VkExternalFormatANDROID>(create_info->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -060097 if (ext_fmt_android && (0 != ext_fmt_android->externalFormat)) {
Spencer Fricke6bba8c72020-04-06 07:41:21 -070098 // VUID 01894 will catch if not found in map
99 auto it = ahb_ext_formats_map.find(ext_fmt_android->externalFormat);
100 if (it != ahb_ext_formats_map.end()) {
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600101 format_features = it->second;
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700102 }
locke-lunargd556cc32019-09-17 01:21:23 -0600103 }
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600104 return format_features;
locke-lunargd556cc32019-09-17 01:21:23 -0600105}
106
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700107void ValidationStateTracker::PostCallRecordGetAndroidHardwareBufferPropertiesANDROID(
108 VkDevice device, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties, VkResult result) {
109 if (VK_SUCCESS != result) return;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700110 auto ahb_format_props = LvlFindInChain<VkAndroidHardwareBufferFormatPropertiesANDROID>(pProperties->pNext);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700111 if (ahb_format_props) {
Jeremy Gebbenfc6f8152021-03-18 16:58:55 -0600112 ahb_ext_formats_map.emplace(ahb_format_props->externalFormat, ahb_format_props->formatFeatures);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700113 }
114}
115
locke-lunargd556cc32019-09-17 01:21:23 -0600116#else
117
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -0600118template <typename CreateInfo>
119VkFormatFeatureFlags ValidationStateTracker::GetExternalFormatFeaturesANDROID(const CreateInfo *create_info) const {
120 return 0;
121}
locke-lunargd556cc32019-09-17 01:21:23 -0600122
123#endif // VK_USE_PLATFORM_ANDROID_KHR
124
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600125VkFormatFeatureFlags GetImageFormatFeatures(VkPhysicalDevice physical_device, VkDevice device, VkImage image, VkFormat format,
126 VkImageTiling tiling) {
127 VkFormatFeatureFlags format_features = 0;
Petr Kraus44f1c482020-04-25 20:09:25 +0200128 // Add feature support according to Image Format Features (vkspec.html#resources-image-format-features)
129 // if format is AHB external format then the features are already set
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600130 if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
131 VkImageDrmFormatModifierPropertiesEXT drm_format_properties = {VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
132 nullptr};
133 DispatchGetImageDrmFormatModifierPropertiesEXT(device, image, &drm_format_properties);
Petr Kraus44f1c482020-04-25 20:09:25 +0200134
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600135 VkFormatProperties2 format_properties_2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, nullptr};
136 VkDrmFormatModifierPropertiesListEXT drm_properties_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
137 nullptr};
138 format_properties_2.pNext = (void *)&drm_properties_list;
139 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
140 std::vector<VkDrmFormatModifierPropertiesEXT> drm_properties;
141 drm_properties.resize(drm_properties_list.drmFormatModifierCount);
142 drm_properties_list.pDrmFormatModifierProperties = &drm_properties[0];
143 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
Petr Kraus44f1c482020-04-25 20:09:25 +0200144
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600145 for (uint32_t i = 0; i < drm_properties_list.drmFormatModifierCount; i++) {
146 if (drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifier == drm_format_properties.drmFormatModifier) {
147 format_features = drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
148 break;
Petr Kraus44f1c482020-04-25 20:09:25 +0200149 }
Petr Kraus44f1c482020-04-25 20:09:25 +0200150 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600151 } else {
152 VkFormatProperties format_properties;
153 DispatchGetPhysicalDeviceFormatProperties(physical_device, format, &format_properties);
154 format_features =
155 (tiling == VK_IMAGE_TILING_LINEAR) ? format_properties.linearTilingFeatures : format_properties.optimalTilingFeatures;
Petr Kraus44f1c482020-04-25 20:09:25 +0200156 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600157 return format_features;
Petr Kraus44f1c482020-04-25 20:09:25 +0200158}
159
locke-lunargd556cc32019-09-17 01:21:23 -0600160void ValidationStateTracker::PostCallRecordCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
161 const VkAllocationCallbacks *pAllocator, VkImage *pImage, VkResult result) {
162 if (VK_SUCCESS != result) return;
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600163 VkFormatFeatureFlags format_features = 0;
locke-lunargd556cc32019-09-17 01:21:23 -0600164 if (device_extensions.vk_android_external_memory_android_hardware_buffer) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600165 format_features = GetExternalFormatFeaturesANDROID(pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -0600166 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600167 if (format_features == 0) {
168 format_features = GetImageFormatFeatures(physical_device, device, *pImage, pCreateInfo->format, pCreateInfo->tiling);
locke-lunargd556cc32019-09-17 01:21:23 -0600169 }
170
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600171 auto is_node = std::make_shared<IMAGE_STATE>(device, *pImage, pCreateInfo, format_features);
locke-lunargd556cc32019-09-17 01:21:23 -0600172 // Record the memory requirements in case they won't be queried
sfricke-samsung013f1ef2020-05-14 22:56:20 -0700173 // External AHB memory can't be queried until after memory is bound
Jeremy Gebben6fbf8242021-06-21 09:14:46 -0600174 if (is_node->IsExternalAHB() == false) {
sfricke-samsung71bc6572020-04-29 15:49:43 -0700175 if (is_node->disjoint == false) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -0600176 DispatchGetImageMemoryRequirements(device, *pImage, &is_node->requirements[0]);
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700177 } else {
178 uint32_t plane_count = FormatPlaneCount(pCreateInfo->format);
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600179 static const std::array<VkImageAspectFlagBits, 3> aspects{VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT,
180 VK_IMAGE_ASPECT_PLANE_2_BIT};
181 assert(plane_count <= aspects.size());
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700182 VkImagePlaneMemoryRequirementsInfo image_plane_req = {VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, nullptr};
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600183 VkImageMemoryRequirementsInfo2 mem_req_info2 = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, &image_plane_req,
184 *pImage};
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700185
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600186 for (uint32_t i = 0; i < plane_count; i++) {
187 VkMemoryRequirements2 mem_reqs2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, nullptr};
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700188
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600189 image_plane_req.planeAspect = aspects[i];
Jeremy Gebbenb9b07b62021-08-16 11:38:47 -0600190 switch (device_extensions.vk_khr_get_memory_requirements2) {
191 case kEnabledByApiLevel:
192 DispatchGetImageMemoryRequirements2(device, &mem_req_info2, &mem_reqs2);
193 break;
194 case kEnabledByCreateinfo:
195 DispatchGetImageMemoryRequirements2KHR(device, &mem_req_info2, &mem_reqs2);
196 break;
197 default:
198 // The VK_KHR_sampler_ycbcr_conversion extension requires VK_KHR_get_memory_requirements2,
199 // so validation of this vkCreateImage call should have already failed.
200 assert(false);
Jeremy Gebben0c09bc92021-08-11 13:58:16 -0600201 }
202 is_node->requirements[i] = mem_reqs2.memoryRequirements;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700203 }
204 }
locke-lunargd556cc32019-09-17 01:21:23 -0600205 }
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700206
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600207 imageMap[*pImage] = std::move(is_node);
locke-lunargd556cc32019-09-17 01:21:23 -0600208}
209
210void ValidationStateTracker::PreCallRecordDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
211 if (!image) return;
212 IMAGE_STATE *image_state = GetImageState(image);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600213 if (!image_state) return;
214
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600215 image_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600216 imageMap.erase(image);
217}
218
219void ValidationStateTracker::PreCallRecordCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
220 VkImageLayout imageLayout, const VkClearColorValue *pColor,
221 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600222
223 if (disabled[command_buffer_state]) return;
224
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600225 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600226 if (cb_node) {
227 cb_node->RecordTransferCmd(CMD_CLEARCOLORIMAGE, GetImageState(image));
locke-lunargd556cc32019-09-17 01:21:23 -0600228 }
229}
230
231void ValidationStateTracker::PreCallRecordCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
232 VkImageLayout imageLayout,
233 const VkClearDepthStencilValue *pDepthStencil,
234 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600235 if (disabled[command_buffer_state]) return;
236
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600237 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600238 if (cb_node) {
239 cb_node->RecordTransferCmd(CMD_CLEARDEPTHSTENCILIMAGE, GetImageState(image));
locke-lunargd556cc32019-09-17 01:21:23 -0600240 }
241}
242
243void ValidationStateTracker::PreCallRecordCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
244 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
245 uint32_t regionCount, const VkImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600246 if (disabled[command_buffer_state]) return;
247
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600248 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600249 cb_node->RecordTransferCmd(CMD_COPYIMAGE, GetImageState(srcImage), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600250}
251
Jeff Leger178b1e52020-10-05 12:22:23 -0400252void ValidationStateTracker::PreCallRecordCmdCopyImage2KHR(VkCommandBuffer commandBuffer,
253 const VkCopyImageInfo2KHR *pCopyImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600254 if (disabled[command_buffer_state]) return;
255
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600256 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600257 cb_node->RecordTransferCmd(CMD_COPYIMAGE2KHR, GetImageState(pCopyImageInfo->srcImage), GetImageState(pCopyImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400258}
259
locke-lunargd556cc32019-09-17 01:21:23 -0600260void ValidationStateTracker::PreCallRecordCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
261 VkImageLayout srcImageLayout, VkImage dstImage,
262 VkImageLayout dstImageLayout, uint32_t regionCount,
263 const VkImageResolve *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600264 if (disabled[command_buffer_state]) return;
265
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600266 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600267 cb_node->RecordTransferCmd(CMD_RESOLVEIMAGE, GetImageState(srcImage), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600268}
269
Jeff Leger178b1e52020-10-05 12:22:23 -0400270void ValidationStateTracker::PreCallRecordCmdResolveImage2KHR(VkCommandBuffer commandBuffer,
271 const VkResolveImageInfo2KHR *pResolveImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600272 if (disabled[command_buffer_state]) return;
273
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600274 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600275 cb_node->RecordTransferCmd(CMD_RESOLVEIMAGE2KHR, GetImageState(pResolveImageInfo->srcImage),
276 GetImageState(pResolveImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400277}
278
locke-lunargd556cc32019-09-17 01:21:23 -0600279void ValidationStateTracker::PreCallRecordCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
280 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
281 uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600282 if (disabled[command_buffer_state]) return;
283
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600284 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600285 cb_node->RecordTransferCmd(CMD_BLITIMAGE, GetImageState(srcImage), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600286}
287
Jeff Leger178b1e52020-10-05 12:22:23 -0400288void ValidationStateTracker::PreCallRecordCmdBlitImage2KHR(VkCommandBuffer commandBuffer,
289 const VkBlitImageInfo2KHR *pBlitImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600290 if (disabled[command_buffer_state]) return;
291
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600292 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600293 cb_node->RecordTransferCmd(CMD_BLITIMAGE2KHR, GetImageState(pBlitImageInfo->srcImage), GetImageState(pBlitImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400294}
295
locke-lunargd556cc32019-09-17 01:21:23 -0600296void ValidationStateTracker::PostCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
297 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer,
298 VkResult result) {
299 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600300
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500301 auto buffer_state = std::make_shared<BUFFER_STATE>(*pBuffer, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -0600302
James Rumble2f6e7bb2021-07-13 15:21:20 +0100303 if (pCreateInfo) {
304 const auto *opaque_capture_address = LvlFindInChain<VkBufferOpaqueCaptureAddressCreateInfo>(pCreateInfo->pNext);
305 if (opaque_capture_address) {
306 // address is used for GPU-AV and ray tracing buffer validation
307 buffer_state->deviceAddress = opaque_capture_address->opaqueCaptureAddress;
308 buffer_address_map_.emplace(opaque_capture_address->opaqueCaptureAddress, buffer_state.get());
309 }
310 }
311
locke-lunargd556cc32019-09-17 01:21:23 -0600312 // Get a set of requirements in the case the app does not
sfricke-samsungad90e722020-07-08 20:54:24 -0700313 DispatchGetBufferMemoryRequirements(device, *pBuffer, &buffer_state->requirements);
locke-lunargd556cc32019-09-17 01:21:23 -0600314
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700315 bufferMap.emplace(*pBuffer, std::move(buffer_state));
locke-lunargd556cc32019-09-17 01:21:23 -0600316}
317
318void ValidationStateTracker::PostCallRecordCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
319 const VkAllocationCallbacks *pAllocator, VkBufferView *pView,
320 VkResult result) {
321 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600322
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500323 auto buffer_state = GetBufferShared(pCreateInfo->buffer);
locke-lunarg25b6c352020-08-06 17:44:18 -0600324
325 VkFormatProperties format_properties;
326 DispatchGetPhysicalDeviceFormatProperties(physical_device, pCreateInfo->format, &format_properties);
locke-lunarg25b6c352020-08-06 17:44:18 -0600327
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600328 bufferViewMap[*pView] =
329 std::make_shared<BUFFER_VIEW_STATE>(buffer_state, *pView, pCreateInfo, format_properties.bufferFeatures);
locke-lunargd556cc32019-09-17 01:21:23 -0600330}
331
332void ValidationStateTracker::PostCallRecordCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
333 const VkAllocationCallbacks *pAllocator, VkImageView *pView,
334 VkResult result) {
335 if (result != VK_SUCCESS) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500336 auto image_state = GetImageShared(pCreateInfo->image);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700337
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600338 VkFormatFeatureFlags format_features = 0;
339 if (image_state->HasAHBFormat() == true) {
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700340 // The ImageView uses same Image's format feature since they share same AHB
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600341 format_features = image_state->format_features;
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700342 } else {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600343 format_features = GetImageFormatFeatures(physical_device, device, image_state->image(), pCreateInfo->format,
344 image_state->createInfo.tiling);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700345 }
346
locke-lunarg9939d4b2020-10-26 20:11:08 -0600347 // 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 -0600348 auto filter_cubic_props = LvlInitStruct<VkFilterCubicImageViewImageFormatPropertiesEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600349 if (IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700350 auto imageview_format_info = LvlInitStruct<VkPhysicalDeviceImageViewImageFormatInfoEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600351 imageview_format_info.imageViewType = pCreateInfo->viewType;
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700352 auto image_format_info = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>(&imageview_format_info);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600353 image_format_info.type = image_state->createInfo.imageType;
354 image_format_info.format = image_state->createInfo.format;
355 image_format_info.tiling = image_state->createInfo.tiling;
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600356 auto usage_create_info = LvlFindInChain<VkImageViewUsageCreateInfo>(pCreateInfo->pNext);
357 image_format_info.usage = usage_create_info ? usage_create_info->usage : image_state->createInfo.usage;
locke-lunarg9939d4b2020-10-26 20:11:08 -0600358 image_format_info.flags = image_state->createInfo.flags;
359
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600360 auto image_format_properties = LvlInitStruct<VkImageFormatProperties2>(&filter_cubic_props);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600361
362 DispatchGetPhysicalDeviceImageFormatProperties2(physical_device, &image_format_info, &image_format_properties);
363 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600364
365 imageViewMap[*pView] =
366 std::make_shared<IMAGE_VIEW_STATE>(image_state, *pView, pCreateInfo, format_features, filter_cubic_props);
locke-lunargd556cc32019-09-17 01:21:23 -0600367}
368
369void ValidationStateTracker::PreCallRecordCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
370 uint32_t regionCount, const VkBufferCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600371 if (disabled[command_buffer_state]) return;
372
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600373 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600374 cb_node->RecordTransferCmd(CMD_COPYBUFFER, GetBufferState(srcBuffer), GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -0600375}
376
Jeff Leger178b1e52020-10-05 12:22:23 -0400377void ValidationStateTracker::PreCallRecordCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600378 const VkCopyBufferInfo2KHR *pCopyBufferInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600379 if (disabled[command_buffer_state]) return;
380
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600381 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600382 cb_node->RecordTransferCmd(CMD_COPYBUFFER2KHR, GetBufferState(pCopyBufferInfo->srcBuffer),
383 GetBufferState(pCopyBufferInfo->dstBuffer));
Jeff Leger178b1e52020-10-05 12:22:23 -0400384}
385
locke-lunargd556cc32019-09-17 01:21:23 -0600386void ValidationStateTracker::PreCallRecordDestroyImageView(VkDevice device, VkImageView imageView,
387 const VkAllocationCallbacks *pAllocator) {
388 IMAGE_VIEW_STATE *image_view_state = GetImageViewState(imageView);
389 if (!image_view_state) return;
locke-lunargd556cc32019-09-17 01:21:23 -0600390
391 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600392 image_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600393 imageViewMap.erase(imageView);
394}
395
396void ValidationStateTracker::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
397 if (!buffer) return;
398 auto buffer_state = GetBufferState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600399
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600400 buffer_state->Destroy();
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600401 bufferMap.erase(buffer_state->buffer());
locke-lunargd556cc32019-09-17 01:21:23 -0600402}
403
404void ValidationStateTracker::PreCallRecordDestroyBufferView(VkDevice device, VkBufferView bufferView,
405 const VkAllocationCallbacks *pAllocator) {
406 if (!bufferView) return;
407 auto buffer_view_state = GetBufferViewState(bufferView);
locke-lunargd556cc32019-09-17 01:21:23 -0600408
409 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600410 buffer_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600411 bufferViewMap.erase(bufferView);
412}
413
414void ValidationStateTracker::PreCallRecordCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
415 VkDeviceSize size, uint32_t data) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600416 if (disabled[command_buffer_state]) return;
417
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600418 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600419 cb_node->RecordTransferCmd(CMD_FILLBUFFER, GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -0600420}
421
422void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
423 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
424 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600425 if (disabled[command_buffer_state]) return;
426
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600427 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600428
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600429 cb_node->RecordTransferCmd(CMD_COPYIMAGETOBUFFER, GetImageState(srcImage), GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -0600430}
431
Jeff Leger178b1e52020-10-05 12:22:23 -0400432void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
433 const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600434 if (disabled[command_buffer_state]) return;
435
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600436 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600437 cb_node->RecordTransferCmd(CMD_COPYIMAGETOBUFFER2KHR, GetImageState(pCopyImageToBufferInfo->srcImage),
438 GetBufferState(pCopyImageToBufferInfo->dstBuffer));
Jeff Leger178b1e52020-10-05 12:22:23 -0400439}
440
locke-lunargd556cc32019-09-17 01:21:23 -0600441void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
442 VkImageLayout dstImageLayout, uint32_t regionCount,
443 const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600444 if (disabled[command_buffer_state]) return;
445
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600446 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600447 cb_node->RecordTransferCmd(CMD_COPYBUFFERTOIMAGE, GetBufferState(srcBuffer), GetImageState(dstImage));
locke-lunargd556cc32019-09-17 01:21:23 -0600448}
449
Jeff Leger178b1e52020-10-05 12:22:23 -0400450void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
451 const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600452
453 if (disabled[command_buffer_state]) return;
454
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600455 auto cb_node = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600456 cb_node->RecordTransferCmd(CMD_COPYBUFFERTOIMAGE2KHR, GetBufferState(pCopyBufferToImageInfo->srcBuffer),
457 GetImageState(pCopyBufferToImageInfo->dstImage));
Jeff Leger178b1e52020-10-05 12:22:23 -0400458}
459
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600460QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) {
461 auto it = queueMap.find(queue);
462 if (it == queueMap.end()) {
463 return nullptr;
464 }
465 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600466}
467
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600468const QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) const {
469 auto it = queueMap.find(queue);
470 if (it == queueMap.cend()) {
471 return nullptr;
472 }
473 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600474}
475
locke-lunargd556cc32019-09-17 01:21:23 -0600476const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) const {
477 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
478 auto it = phys_dev_map->find(phys);
479 if (it == phys_dev_map->end()) {
480 return nullptr;
481 }
482 return &it->second;
483}
484
485PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) {
486 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
487 auto it = phys_dev_map->find(phys);
488 if (it == phys_dev_map->end()) {
489 return nullptr;
490 }
491 return &it->second;
492}
493
494PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() { return physical_device_state; }
495const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() const { return physical_device_state; }
496
497// Return ptr to memory binding for given handle of specified type
498template <typename State, typename Result>
499static Result GetObjectMemBindingImpl(State state, const VulkanTypedHandle &typed_handle) {
500 switch (typed_handle.type) {
501 case kVulkanObjectTypeImage:
502 return state->GetImageState(typed_handle.Cast<VkImage>());
503 case kVulkanObjectTypeBuffer:
504 return state->GetBufferState(typed_handle.Cast<VkBuffer>());
505 case kVulkanObjectTypeAccelerationStructureNV:
sourav parmarcd5fb182020-07-17 12:58:44 -0700506 return state->GetAccelerationStructureStateNV(typed_handle.Cast<VkAccelerationStructureNV>());
locke-lunargd556cc32019-09-17 01:21:23 -0600507 default:
508 break;
509 }
510 return nullptr;
511}
512
513const BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) const {
514 return GetObjectMemBindingImpl<const ValidationStateTracker *, const BINDABLE *>(this, typed_handle);
515}
516
517BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) {
518 return GetObjectMemBindingImpl<ValidationStateTracker *, BINDABLE *>(this, typed_handle);
519}
520
locke-lunargd556cc32019-09-17 01:21:23 -0600521// Remove set from setMap and delete the set
522void ValidationStateTracker::FreeDescriptorSet(cvdescriptorset::DescriptorSet *descriptor_set) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500523 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600524 descriptor_set->Destroy();
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500525
locke-lunargd556cc32019-09-17 01:21:23 -0600526 setMap.erase(descriptor_set->GetSet());
527}
528
529// Free all DS Pools including their Sets & related sub-structs
530// NOTE : Calls to this function should be wrapped in mutex
531void ValidationStateTracker::DeleteDescriptorSetPools() {
532 for (auto ii = descriptorPoolMap.begin(); ii != descriptorPoolMap.end();) {
533 // Remove this pools' sets from setMap and delete them
John Zulauf79f06582021-02-27 18:38:39 -0700534 for (auto *ds : ii->second->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -0600535 FreeDescriptorSet(ds);
536 }
537 ii->second->sets.clear();
538 ii = descriptorPoolMap.erase(ii);
539 }
540}
541
542// For given object struct return a ptr of BASE_NODE type for its wrapping struct
543BASE_NODE *ValidationStateTracker::GetStateStructPtrFromObject(const VulkanTypedHandle &object_struct) {
Jeff Bolzadbfa852019-10-04 13:53:30 -0500544 if (object_struct.node) {
545#ifdef _DEBUG
546 // assert that lookup would find the same object
547 VulkanTypedHandle other = object_struct;
548 other.node = nullptr;
549 assert(object_struct.node == GetStateStructPtrFromObject(other));
550#endif
551 return object_struct.node;
552 }
locke-lunargd556cc32019-09-17 01:21:23 -0600553 BASE_NODE *base_ptr = nullptr;
554 switch (object_struct.type) {
555 case kVulkanObjectTypeDescriptorSet: {
556 base_ptr = GetSetNode(object_struct.Cast<VkDescriptorSet>());
557 break;
558 }
559 case kVulkanObjectTypeSampler: {
560 base_ptr = GetSamplerState(object_struct.Cast<VkSampler>());
561 break;
562 }
563 case kVulkanObjectTypeQueryPool: {
564 base_ptr = GetQueryPoolState(object_struct.Cast<VkQueryPool>());
565 break;
566 }
567 case kVulkanObjectTypePipeline: {
568 base_ptr = GetPipelineState(object_struct.Cast<VkPipeline>());
569 break;
570 }
571 case kVulkanObjectTypeBuffer: {
572 base_ptr = GetBufferState(object_struct.Cast<VkBuffer>());
573 break;
574 }
575 case kVulkanObjectTypeBufferView: {
576 base_ptr = GetBufferViewState(object_struct.Cast<VkBufferView>());
577 break;
578 }
579 case kVulkanObjectTypeImage: {
580 base_ptr = GetImageState(object_struct.Cast<VkImage>());
581 break;
582 }
583 case kVulkanObjectTypeImageView: {
584 base_ptr = GetImageViewState(object_struct.Cast<VkImageView>());
585 break;
586 }
587 case kVulkanObjectTypeEvent: {
588 base_ptr = GetEventState(object_struct.Cast<VkEvent>());
589 break;
590 }
591 case kVulkanObjectTypeDescriptorPool: {
592 base_ptr = GetDescriptorPoolState(object_struct.Cast<VkDescriptorPool>());
593 break;
594 }
595 case kVulkanObjectTypeCommandPool: {
596 base_ptr = GetCommandPoolState(object_struct.Cast<VkCommandPool>());
597 break;
598 }
599 case kVulkanObjectTypeFramebuffer: {
600 base_ptr = GetFramebufferState(object_struct.Cast<VkFramebuffer>());
601 break;
602 }
603 case kVulkanObjectTypeRenderPass: {
604 base_ptr = GetRenderPassState(object_struct.Cast<VkRenderPass>());
605 break;
606 }
607 case kVulkanObjectTypeDeviceMemory: {
608 base_ptr = GetDevMemState(object_struct.Cast<VkDeviceMemory>());
609 break;
610 }
611 case kVulkanObjectTypeAccelerationStructureNV: {
sourav parmarcd5fb182020-07-17 12:58:44 -0700612 base_ptr = GetAccelerationStructureStateNV(object_struct.Cast<VkAccelerationStructureNV>());
613 break;
614 }
615 case kVulkanObjectTypeAccelerationStructureKHR: {
616 base_ptr = GetAccelerationStructureStateKHR(object_struct.Cast<VkAccelerationStructureKHR>());
locke-lunargd556cc32019-09-17 01:21:23 -0600617 break;
618 }
Jeff Bolzadbfa852019-10-04 13:53:30 -0500619 case kVulkanObjectTypeUnknown:
620 // This can happen if an element of the object_bindings vector has been
621 // zeroed out, after an object is destroyed.
622 break;
locke-lunargd556cc32019-09-17 01:21:23 -0600623 default:
624 // TODO : Any other objects to be handled here?
625 assert(0);
626 break;
627 }
628 return base_ptr;
629}
630
sfricke-samsungbf1a2ed2020-06-14 23:31:00 -0700631// Gets union of all features defined by Potential Format Features
632// 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 -0700633VkFormatFeatureFlags ValidationStateTracker::GetPotentialFormatFeatures(VkFormat format) const {
634 VkFormatFeatureFlags format_features = 0;
635
636 if (format != VK_FORMAT_UNDEFINED) {
637 VkFormatProperties format_properties;
638 DispatchGetPhysicalDeviceFormatProperties(physical_device, format, &format_properties);
639 format_features |= format_properties.linearTilingFeatures;
640 format_features |= format_properties.optimalTilingFeatures;
641 if (device_extensions.vk_ext_image_drm_format_modifier) {
642 // VK_KHR_get_physical_device_properties2 is required in this case
643 VkFormatProperties2 format_properties_2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
644 VkDrmFormatModifierPropertiesListEXT drm_properties_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
645 nullptr};
646 format_properties_2.pNext = (void *)&drm_properties_list;
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100647
648 // First call is to get the number of modifiers compatible with the queried format
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700649 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100650
651 std::vector<VkDrmFormatModifierPropertiesEXT> drm_properties;
652 drm_properties.resize(drm_properties_list.drmFormatModifierCount);
653 drm_properties_list.pDrmFormatModifierProperties = drm_properties.data();
654
655 // Second call, now with an allocated array in pDrmFormatModifierProperties, is to get the modifiers
656 // compatible with the queried format
657 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
658
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700659 for (uint32_t i = 0; i < drm_properties_list.drmFormatModifierCount; i++) {
660 format_features |= drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
661 }
662 }
663 }
664
665 return format_features;
666}
667
locke-lunargd556cc32019-09-17 01:21:23 -0600668void ValidationStateTracker::PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
669 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
670 VkResult result) {
671 if (VK_SUCCESS != result) return;
672
Locke Linf3873542021-04-26 11:25:10 -0600673 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
674 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
675 ValidationStateTracker *state_tracker = static_cast<ValidationStateTracker *>(validation_data);
676
locke-lunargd556cc32019-09-17 01:21:23 -0600677 const VkPhysicalDeviceFeatures *enabled_features_found = pCreateInfo->pEnabledFeatures;
678 if (nullptr == enabled_features_found) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700679 const auto *features2 = LvlFindInChain<VkPhysicalDeviceFeatures2>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600680 if (features2) {
681 enabled_features_found = &(features2->features);
Locke Linf3873542021-04-26 11:25:10 -0600682
683 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(features2->pNext);
684 if (provoking_vertex_features) {
685 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
686 }
locke-lunargd556cc32019-09-17 01:21:23 -0600687 }
688 }
689
locke-lunargd556cc32019-09-17 01:21:23 -0600690 if (nullptr == enabled_features_found) {
691 state_tracker->enabled_features.core = {};
692 } else {
693 state_tracker->enabled_features.core = *enabled_features_found;
694 }
695
696 // Make sure that queue_family_properties are obtained for this device's physical_device, even if the app has not
697 // previously set them through an explicit API call.
698 uint32_t count;
699 auto pd_state = GetPhysicalDeviceState(gpu);
700 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
701 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
702 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, &pd_state->queue_family_properties[0]);
703 // Save local link to this device's physical device state
704 state_tracker->physical_device_state = pd_state;
705
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700706 const auto *vulkan_12_features = LvlFindInChain<VkPhysicalDeviceVulkan12Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700707 if (vulkan_12_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700708 state_tracker->enabled_features.core12 = *vulkan_12_features;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700709 } else {
sfricke-samsung27c70722020-05-02 08:42:39 -0700710 // Set Extension Feature Aliases to false as there is no struct to check
711 state_tracker->enabled_features.core12.drawIndirectCount = VK_FALSE;
712 state_tracker->enabled_features.core12.samplerMirrorClampToEdge = VK_FALSE;
713 state_tracker->enabled_features.core12.descriptorIndexing = VK_FALSE;
714 state_tracker->enabled_features.core12.samplerFilterMinmax = VK_FALSE;
715 state_tracker->enabled_features.core12.shaderOutputLayer = VK_FALSE;
716 state_tracker->enabled_features.core12.shaderOutputViewportIndex = VK_FALSE;
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800717 state_tracker->enabled_features.core12.subgroupBroadcastDynamicId = VK_FALSE;
sfricke-samsung27c70722020-05-02 08:42:39 -0700718
719 // These structs are only allowed in pNext chain if there is no VkPhysicalDeviceVulkan12Features
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700720
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700721 const auto *eight_bit_storage_features = LvlFindInChain<VkPhysicalDevice8BitStorageFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700722 if (eight_bit_storage_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700723 state_tracker->enabled_features.core12.storageBuffer8BitAccess = eight_bit_storage_features->storageBuffer8BitAccess;
724 state_tracker->enabled_features.core12.uniformAndStorageBuffer8BitAccess =
725 eight_bit_storage_features->uniformAndStorageBuffer8BitAccess;
726 state_tracker->enabled_features.core12.storagePushConstant8 = eight_bit_storage_features->storagePushConstant8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700727 }
728
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700729 const auto *float16_int8_features = LvlFindInChain<VkPhysicalDeviceShaderFloat16Int8Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700730 if (float16_int8_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700731 state_tracker->enabled_features.core12.shaderFloat16 = float16_int8_features->shaderFloat16;
732 state_tracker->enabled_features.core12.shaderInt8 = float16_int8_features->shaderInt8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700733 }
734
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700735 const auto *descriptor_indexing_features = LvlFindInChain<VkPhysicalDeviceDescriptorIndexingFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700736 if (descriptor_indexing_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700737 state_tracker->enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing =
738 descriptor_indexing_features->shaderInputAttachmentArrayDynamicIndexing;
739 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing =
740 descriptor_indexing_features->shaderUniformTexelBufferArrayDynamicIndexing;
741 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing =
742 descriptor_indexing_features->shaderStorageTexelBufferArrayDynamicIndexing;
743 state_tracker->enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing =
744 descriptor_indexing_features->shaderUniformBufferArrayNonUniformIndexing;
745 state_tracker->enabled_features.core12.shaderSampledImageArrayNonUniformIndexing =
746 descriptor_indexing_features->shaderSampledImageArrayNonUniformIndexing;
747 state_tracker->enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing =
748 descriptor_indexing_features->shaderStorageBufferArrayNonUniformIndexing;
749 state_tracker->enabled_features.core12.shaderStorageImageArrayNonUniformIndexing =
750 descriptor_indexing_features->shaderStorageImageArrayNonUniformIndexing;
751 state_tracker->enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing =
752 descriptor_indexing_features->shaderInputAttachmentArrayNonUniformIndexing;
753 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing =
754 descriptor_indexing_features->shaderUniformTexelBufferArrayNonUniformIndexing;
755 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing =
756 descriptor_indexing_features->shaderStorageTexelBufferArrayNonUniformIndexing;
757 state_tracker->enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind =
758 descriptor_indexing_features->descriptorBindingUniformBufferUpdateAfterBind;
759 state_tracker->enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind =
760 descriptor_indexing_features->descriptorBindingSampledImageUpdateAfterBind;
761 state_tracker->enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind =
762 descriptor_indexing_features->descriptorBindingStorageImageUpdateAfterBind;
763 state_tracker->enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind =
764 descriptor_indexing_features->descriptorBindingStorageBufferUpdateAfterBind;
765 state_tracker->enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind =
766 descriptor_indexing_features->descriptorBindingUniformTexelBufferUpdateAfterBind;
767 state_tracker->enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind =
768 descriptor_indexing_features->descriptorBindingStorageTexelBufferUpdateAfterBind;
769 state_tracker->enabled_features.core12.descriptorBindingUpdateUnusedWhilePending =
770 descriptor_indexing_features->descriptorBindingUpdateUnusedWhilePending;
771 state_tracker->enabled_features.core12.descriptorBindingPartiallyBound =
772 descriptor_indexing_features->descriptorBindingPartiallyBound;
773 state_tracker->enabled_features.core12.descriptorBindingVariableDescriptorCount =
774 descriptor_indexing_features->descriptorBindingVariableDescriptorCount;
775 state_tracker->enabled_features.core12.runtimeDescriptorArray = descriptor_indexing_features->runtimeDescriptorArray;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700776 }
777
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700778 const auto *scalar_block_layout_features = LvlFindInChain<VkPhysicalDeviceScalarBlockLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700779 if (scalar_block_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700780 state_tracker->enabled_features.core12.scalarBlockLayout = scalar_block_layout_features->scalarBlockLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700781 }
782
783 const auto *imageless_framebuffer_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700784 LvlFindInChain<VkPhysicalDeviceImagelessFramebufferFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700785 if (imageless_framebuffer_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700786 state_tracker->enabled_features.core12.imagelessFramebuffer = imageless_framebuffer_features->imagelessFramebuffer;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700787 }
788
789 const auto *uniform_buffer_standard_layout_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700790 LvlFindInChain<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700791 if (uniform_buffer_standard_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700792 state_tracker->enabled_features.core12.uniformBufferStandardLayout =
793 uniform_buffer_standard_layout_features->uniformBufferStandardLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700794 }
795
796 const auto *subgroup_extended_types_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700797 LvlFindInChain<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700798 if (subgroup_extended_types_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700799 state_tracker->enabled_features.core12.shaderSubgroupExtendedTypes =
800 subgroup_extended_types_features->shaderSubgroupExtendedTypes;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700801 }
802
803 const auto *separate_depth_stencil_layouts_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700804 LvlFindInChain<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700805 if (separate_depth_stencil_layouts_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700806 state_tracker->enabled_features.core12.separateDepthStencilLayouts =
807 separate_depth_stencil_layouts_features->separateDepthStencilLayouts;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700808 }
809
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700810 const auto *host_query_reset_features = LvlFindInChain<VkPhysicalDeviceHostQueryResetFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700811 if (host_query_reset_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700812 state_tracker->enabled_features.core12.hostQueryReset = host_query_reset_features->hostQueryReset;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700813 }
814
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700815 const auto *timeline_semaphore_features = LvlFindInChain<VkPhysicalDeviceTimelineSemaphoreFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700816 if (timeline_semaphore_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700817 state_tracker->enabled_features.core12.timelineSemaphore = timeline_semaphore_features->timelineSemaphore;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700818 }
819
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700820 const auto *buffer_device_address = LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700821 if (buffer_device_address) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700822 state_tracker->enabled_features.core12.bufferDeviceAddress = buffer_device_address->bufferDeviceAddress;
823 state_tracker->enabled_features.core12.bufferDeviceAddressCaptureReplay =
824 buffer_device_address->bufferDeviceAddressCaptureReplay;
825 state_tracker->enabled_features.core12.bufferDeviceAddressMultiDevice =
826 buffer_device_address->bufferDeviceAddressMultiDevice;
827 }
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800828
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700829 const auto *atomic_int64_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicInt64Features>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800830 if (atomic_int64_features) {
831 state_tracker->enabled_features.core12.shaderBufferInt64Atomics = atomic_int64_features->shaderBufferInt64Atomics;
832 state_tracker->enabled_features.core12.shaderSharedInt64Atomics = atomic_int64_features->shaderSharedInt64Atomics;
833 }
834
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700835 const auto *memory_model_features = LvlFindInChain<VkPhysicalDeviceVulkanMemoryModelFeatures>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800836 if (memory_model_features) {
837 state_tracker->enabled_features.core12.vulkanMemoryModel = memory_model_features->vulkanMemoryModel;
838 state_tracker->enabled_features.core12.vulkanMemoryModelDeviceScope =
839 memory_model_features->vulkanMemoryModelDeviceScope;
840 state_tracker->enabled_features.core12.vulkanMemoryModelAvailabilityVisibilityChains =
841 memory_model_features->vulkanMemoryModelAvailabilityVisibilityChains;
842 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700843 }
844
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700845 const auto *vulkan_11_features = LvlFindInChain<VkPhysicalDeviceVulkan11Features>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700846 if (vulkan_11_features) {
847 state_tracker->enabled_features.core11 = *vulkan_11_features;
848 } else {
sfricke-samsung828e59d2021-08-22 23:20:49 -0700849 // These structs are only allowed in pNext chain if there is no vkPhysicalDeviceVulkan11Features
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700850
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700851 const auto *sixteen_bit_storage_features = LvlFindInChain<VkPhysicalDevice16BitStorageFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700852 if (sixteen_bit_storage_features) {
853 state_tracker->enabled_features.core11.storageBuffer16BitAccess =
854 sixteen_bit_storage_features->storageBuffer16BitAccess;
855 state_tracker->enabled_features.core11.uniformAndStorageBuffer16BitAccess =
856 sixteen_bit_storage_features->uniformAndStorageBuffer16BitAccess;
857 state_tracker->enabled_features.core11.storagePushConstant16 = sixteen_bit_storage_features->storagePushConstant16;
858 state_tracker->enabled_features.core11.storageInputOutput16 = sixteen_bit_storage_features->storageInputOutput16;
859 }
860
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700861 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700862 if (multiview_features) {
863 state_tracker->enabled_features.core11.multiview = multiview_features->multiview;
864 state_tracker->enabled_features.core11.multiviewGeometryShader = multiview_features->multiviewGeometryShader;
865 state_tracker->enabled_features.core11.multiviewTessellationShader = multiview_features->multiviewTessellationShader;
866 }
867
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700868 const auto *variable_pointers_features = LvlFindInChain<VkPhysicalDeviceVariablePointersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700869 if (variable_pointers_features) {
870 state_tracker->enabled_features.core11.variablePointersStorageBuffer =
871 variable_pointers_features->variablePointersStorageBuffer;
872 state_tracker->enabled_features.core11.variablePointers = variable_pointers_features->variablePointers;
873 }
874
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700875 const auto *protected_memory_features = LvlFindInChain<VkPhysicalDeviceProtectedMemoryFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700876 if (protected_memory_features) {
877 state_tracker->enabled_features.core11.protectedMemory = protected_memory_features->protectedMemory;
878 }
879
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700880 const auto *ycbcr_conversion_features = LvlFindInChain<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700881 if (ycbcr_conversion_features) {
882 state_tracker->enabled_features.core11.samplerYcbcrConversion = ycbcr_conversion_features->samplerYcbcrConversion;
883 }
884
885 const auto *shader_draw_parameters_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700886 LvlFindInChain<VkPhysicalDeviceShaderDrawParametersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700887 if (shader_draw_parameters_features) {
888 state_tracker->enabled_features.core11.shaderDrawParameters = shader_draw_parameters_features->shaderDrawParameters;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700889 }
890 }
891
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700892 const auto *device_group_ci = LvlFindInChain<VkDeviceGroupDeviceCreateInfo>(pCreateInfo->pNext);
Tony-LunarGca4891a2020-08-10 15:46:46 -0600893 if (device_group_ci) {
894 state_tracker->physical_device_count = device_group_ci->physicalDeviceCount;
895 state_tracker->device_group_create_info = *device_group_ci;
896 } else {
897 state_tracker->physical_device_count = 1;
898 }
locke-lunargd556cc32019-09-17 01:21:23 -0600899
sfricke-samsung828e59d2021-08-22 23:20:49 -0700900 // Features from other extensions passesd in create info
901 {
902 const auto *exclusive_scissor_features = LvlFindInChain<VkPhysicalDeviceExclusiveScissorFeaturesNV>(pCreateInfo->pNext);
903 if (exclusive_scissor_features) {
904 state_tracker->enabled_features.exclusive_scissor_features = *exclusive_scissor_features;
905 }
locke-lunargd556cc32019-09-17 01:21:23 -0600906
sfricke-samsung828e59d2021-08-22 23:20:49 -0700907 const auto *shading_rate_image_features = LvlFindInChain<VkPhysicalDeviceShadingRateImageFeaturesNV>(pCreateInfo->pNext);
908 if (shading_rate_image_features) {
909 state_tracker->enabled_features.shading_rate_image_features = *shading_rate_image_features;
910 }
locke-lunargd556cc32019-09-17 01:21:23 -0600911
sfricke-samsung828e59d2021-08-22 23:20:49 -0700912 const auto *mesh_shader_features = LvlFindInChain<VkPhysicalDeviceMeshShaderFeaturesNV>(pCreateInfo->pNext);
913 if (mesh_shader_features) {
914 state_tracker->enabled_features.mesh_shader_features = *mesh_shader_features;
915 }
locke-lunargd556cc32019-09-17 01:21:23 -0600916
sfricke-samsung828e59d2021-08-22 23:20:49 -0700917 const auto *inline_uniform_block_features =
918 LvlFindInChain<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(pCreateInfo->pNext);
919 if (inline_uniform_block_features) {
920 state_tracker->enabled_features.inline_uniform_block_features = *inline_uniform_block_features;
921 }
locke-lunargd556cc32019-09-17 01:21:23 -0600922
sfricke-samsung828e59d2021-08-22 23:20:49 -0700923 const auto *transform_feedback_features = LvlFindInChain<VkPhysicalDeviceTransformFeedbackFeaturesEXT>(pCreateInfo->pNext);
924 if (transform_feedback_features) {
925 state_tracker->enabled_features.transform_feedback_features = *transform_feedback_features;
926 }
locke-lunargd556cc32019-09-17 01:21:23 -0600927
sfricke-samsung828e59d2021-08-22 23:20:49 -0700928 const auto *vtx_attrib_div_features = LvlFindInChain<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(pCreateInfo->pNext);
929 if (vtx_attrib_div_features) {
930 state_tracker->enabled_features.vtx_attrib_divisor_features = *vtx_attrib_div_features;
931 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700932
sfricke-samsung828e59d2021-08-22 23:20:49 -0700933 const auto *buffer_device_address_ext_features =
934 LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>(pCreateInfo->pNext);
935 if (buffer_device_address_ext_features) {
936 state_tracker->enabled_features.buffer_device_address_ext_features = *buffer_device_address_ext_features;
937 }
locke-lunargd556cc32019-09-17 01:21:23 -0600938
sfricke-samsung828e59d2021-08-22 23:20:49 -0700939 const auto *cooperative_matrix_features = LvlFindInChain<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(pCreateInfo->pNext);
940 if (cooperative_matrix_features) {
941 state_tracker->enabled_features.cooperative_matrix_features = *cooperative_matrix_features;
942 }
locke-lunargd556cc32019-09-17 01:21:23 -0600943
sfricke-samsung828e59d2021-08-22 23:20:49 -0700944 const auto *compute_shader_derivatives_features =
945 LvlFindInChain<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>(pCreateInfo->pNext);
946 if (compute_shader_derivatives_features) {
947 state_tracker->enabled_features.compute_shader_derivatives_features = *compute_shader_derivatives_features;
948 }
locke-lunargd556cc32019-09-17 01:21:23 -0600949
sfricke-samsung828e59d2021-08-22 23:20:49 -0700950 const auto *fragment_shader_barycentric_features =
951 LvlFindInChain<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>(pCreateInfo->pNext);
952 if (fragment_shader_barycentric_features) {
953 state_tracker->enabled_features.fragment_shader_barycentric_features = *fragment_shader_barycentric_features;
954 }
locke-lunargd556cc32019-09-17 01:21:23 -0600955
sfricke-samsung828e59d2021-08-22 23:20:49 -0700956 const auto *shader_image_footprint_features =
957 LvlFindInChain<VkPhysicalDeviceShaderImageFootprintFeaturesNV>(pCreateInfo->pNext);
958 if (shader_image_footprint_features) {
959 state_tracker->enabled_features.shader_image_footprint_features = *shader_image_footprint_features;
960 }
locke-lunargd556cc32019-09-17 01:21:23 -0600961
sfricke-samsung828e59d2021-08-22 23:20:49 -0700962 const auto *fragment_shader_interlock_features =
963 LvlFindInChain<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>(pCreateInfo->pNext);
964 if (fragment_shader_interlock_features) {
965 state_tracker->enabled_features.fragment_shader_interlock_features = *fragment_shader_interlock_features;
966 }
locke-lunargd556cc32019-09-17 01:21:23 -0600967
sfricke-samsung828e59d2021-08-22 23:20:49 -0700968 const auto *demote_to_helper_invocation_features =
969 LvlFindInChain<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>(pCreateInfo->pNext);
970 if (demote_to_helper_invocation_features) {
971 state_tracker->enabled_features.demote_to_helper_invocation_features = *demote_to_helper_invocation_features;
972 }
locke-lunargd556cc32019-09-17 01:21:23 -0600973
sfricke-samsung828e59d2021-08-22 23:20:49 -0700974 const auto *texel_buffer_alignment_features =
975 LvlFindInChain<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>(pCreateInfo->pNext);
976 if (texel_buffer_alignment_features) {
977 state_tracker->enabled_features.texel_buffer_alignment_features = *texel_buffer_alignment_features;
978 }
locke-lunargd556cc32019-09-17 01:21:23 -0600979
sfricke-samsung828e59d2021-08-22 23:20:49 -0700980 const auto *pipeline_exe_props_features =
981 LvlFindInChain<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>(pCreateInfo->pNext);
982 if (pipeline_exe_props_features) {
983 state_tracker->enabled_features.pipeline_exe_props_features = *pipeline_exe_props_features;
984 }
locke-lunargd556cc32019-09-17 01:21:23 -0600985
sfricke-samsung828e59d2021-08-22 23:20:49 -0700986 const auto *dedicated_allocation_image_aliasing_features =
987 LvlFindInChain<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>(pCreateInfo->pNext);
988 if (dedicated_allocation_image_aliasing_features) {
989 state_tracker->enabled_features.dedicated_allocation_image_aliasing_features =
990 *dedicated_allocation_image_aliasing_features;
991 }
Jeff Bolz82f854d2019-09-17 14:56:47 -0500992
sfricke-samsung828e59d2021-08-22 23:20:49 -0700993 const auto *performance_query_features = LvlFindInChain<VkPhysicalDevicePerformanceQueryFeaturesKHR>(pCreateInfo->pNext);
994 if (performance_query_features) {
995 state_tracker->enabled_features.performance_query_features = *performance_query_features;
996 }
Lionel Landwerlinc7420912019-05-23 00:33:42 +0100997
sfricke-samsung828e59d2021-08-22 23:20:49 -0700998 const auto *device_coherent_memory_features = LvlFindInChain<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(pCreateInfo->pNext);
999 if (device_coherent_memory_features) {
1000 state_tracker->enabled_features.device_coherent_memory_features = *device_coherent_memory_features;
1001 }
Tobias Hector782bcde2019-11-28 16:19:42 +00001002
sfricke-samsung828e59d2021-08-22 23:20:49 -07001003 const auto *ycbcr_image_array_features = LvlFindInChain<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>(pCreateInfo->pNext);
1004 if (ycbcr_image_array_features) {
1005 state_tracker->enabled_features.ycbcr_image_array_features = *ycbcr_image_array_features;
1006 }
sfricke-samsungcead0802020-01-30 22:20:10 -08001007
sfricke-samsung828e59d2021-08-22 23:20:49 -07001008 const auto *ray_query_features = LvlFindInChain<VkPhysicalDeviceRayQueryFeaturesKHR>(pCreateInfo->pNext);
1009 if (ray_query_features) {
1010 state_tracker->enabled_features.ray_query_features = *ray_query_features;
1011 }
sourav parmarcd5fb182020-07-17 12:58:44 -07001012
sfricke-samsung828e59d2021-08-22 23:20:49 -07001013 const auto *ray_tracing_pipeline_features =
1014 LvlFindInChain<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>(pCreateInfo->pNext);
1015 if (ray_tracing_pipeline_features) {
1016 state_tracker->enabled_features.ray_tracing_pipeline_features = *ray_tracing_pipeline_features;
1017 }
sourav parmarcd5fb182020-07-17 12:58:44 -07001018
sfricke-samsung828e59d2021-08-22 23:20:49 -07001019 const auto *ray_tracing_acceleration_structure_features =
1020 LvlFindInChain<VkPhysicalDeviceAccelerationStructureFeaturesKHR>(pCreateInfo->pNext);
1021 if (ray_tracing_acceleration_structure_features) {
1022 state_tracker->enabled_features.ray_tracing_acceleration_structure_features =
1023 *ray_tracing_acceleration_structure_features;
1024 }
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001025
sfricke-samsung828e59d2021-08-22 23:20:49 -07001026 const auto *robustness2_features = LvlFindInChain<VkPhysicalDeviceRobustness2FeaturesEXT>(pCreateInfo->pNext);
1027 if (robustness2_features) {
1028 state_tracker->enabled_features.robustness2_features = *robustness2_features;
1029 }
Jeff Bolz165818a2020-05-08 11:19:03 -05001030
sfricke-samsung828e59d2021-08-22 23:20:49 -07001031 const auto *fragment_density_map_features =
1032 LvlFindInChain<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(pCreateInfo->pNext);
1033 if (fragment_density_map_features) {
1034 state_tracker->enabled_features.fragment_density_map_features = *fragment_density_map_features;
1035 }
janharaldfredriksen-arm3b793772020-05-12 18:55:53 +02001036
sfricke-samsung828e59d2021-08-22 23:20:49 -07001037 const auto *fragment_density_map_features2 =
1038 LvlFindInChain<VkPhysicalDeviceFragmentDensityMap2FeaturesEXT>(pCreateInfo->pNext);
1039 if (fragment_density_map_features2) {
1040 state_tracker->enabled_features.fragment_density_map2_features = *fragment_density_map_features2;
1041 }
janharaldfredriksen-arm36e17572020-07-07 13:59:28 +02001042
sfricke-samsung828e59d2021-08-22 23:20:49 -07001043 const auto *astc_decode_features = LvlFindInChain<VkPhysicalDeviceASTCDecodeFeaturesEXT>(pCreateInfo->pNext);
1044 if (astc_decode_features) {
1045 state_tracker->enabled_features.astc_decode_features = *astc_decode_features;
1046 }
sfricke-samsung0c4a06f2020-06-27 01:24:32 -07001047
sfricke-samsung828e59d2021-08-22 23:20:49 -07001048 const auto *custom_border_color_features = LvlFindInChain<VkPhysicalDeviceCustomBorderColorFeaturesEXT>(pCreateInfo->pNext);
1049 if (custom_border_color_features) {
1050 state_tracker->enabled_features.custom_border_color_features = *custom_border_color_features;
1051 }
Tony-LunarG7337b312020-04-15 16:40:25 -06001052
sfricke-samsung828e59d2021-08-22 23:20:49 -07001053 const auto *pipeline_creation_cache_control_features =
1054 LvlFindInChain<VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT>(pCreateInfo->pNext);
1055 if (pipeline_creation_cache_control_features) {
1056 state_tracker->enabled_features.pipeline_creation_cache_control_features = *pipeline_creation_cache_control_features;
1057 }
sfricke-samsungfd661d62020-05-16 00:57:27 -07001058
sfricke-samsung828e59d2021-08-22 23:20:49 -07001059 const auto *fragment_shading_rate_features =
1060 LvlFindInChain<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>(pCreateInfo->pNext);
1061 if (fragment_shading_rate_features) {
1062 state_tracker->enabled_features.fragment_shading_rate_features = *fragment_shading_rate_features;
1063 }
Tobias Hector6663c9b2020-11-05 10:18:02 +00001064
sfricke-samsung828e59d2021-08-22 23:20:49 -07001065 const auto *extended_dynamic_state_features =
1066 LvlFindInChain<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>(pCreateInfo->pNext);
1067 if (extended_dynamic_state_features) {
1068 state_tracker->enabled_features.extended_dynamic_state_features = *extended_dynamic_state_features;
1069 }
Piers Daniell39842ee2020-07-10 16:42:33 -06001070
sfricke-samsung828e59d2021-08-22 23:20:49 -07001071 const auto *extended_dynamic_state2_features =
1072 LvlFindInChain<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>(pCreateInfo->pNext);
1073 if (extended_dynamic_state2_features) {
1074 state_tracker->enabled_features.extended_dynamic_state2_features = *extended_dynamic_state2_features;
1075 }
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07001076
sfricke-samsung828e59d2021-08-22 23:20:49 -07001077 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
1078 if (multiview_features) {
1079 state_tracker->enabled_features.multiview_features = *multiview_features;
1080 }
locke-lunarg3fa463a2020-10-23 16:39:04 -06001081
sfricke-samsung828e59d2021-08-22 23:20:49 -07001082 const auto *portability_features = LvlFindInChain<VkPhysicalDevicePortabilitySubsetFeaturesKHR>(pCreateInfo->pNext);
1083 if (portability_features) {
1084 state_tracker->enabled_features.portability_subset_features = *portability_features;
1085 }
Nathaniel Cesariob3f2d702020-11-09 09:20:49 -07001086
sfricke-samsung828e59d2021-08-22 23:20:49 -07001087 const auto *shader_integer_functions2_features =
1088 LvlFindInChain<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>(pCreateInfo->pNext);
1089 if (shader_integer_functions2_features) {
1090 state_tracker->enabled_features.shader_integer_functions2_features = *shader_integer_functions2_features;
1091 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001092
sfricke-samsung828e59d2021-08-22 23:20:49 -07001093 const auto *shader_sm_builtins_features = LvlFindInChain<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>(pCreateInfo->pNext);
1094 if (shader_sm_builtins_features) {
1095 state_tracker->enabled_features.shader_sm_builtins_features = *shader_sm_builtins_features;
1096 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001097
sfricke-samsung828e59d2021-08-22 23:20:49 -07001098 const auto *shader_atomic_float_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>(pCreateInfo->pNext);
1099 if (shader_atomic_float_features) {
1100 state_tracker->enabled_features.shader_atomic_float_features = *shader_atomic_float_features;
1101 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001102
sfricke-samsung828e59d2021-08-22 23:20:49 -07001103 const auto *shader_image_atomic_int64_features =
1104 LvlFindInChain<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>(pCreateInfo->pNext);
1105 if (shader_image_atomic_int64_features) {
1106 state_tracker->enabled_features.shader_image_atomic_int64_features = *shader_image_atomic_int64_features;
1107 }
sfricke-samsung0065ce02020-12-03 22:46:37 -08001108
sfricke-samsung828e59d2021-08-22 23:20:49 -07001109 const auto *shader_clock_features = LvlFindInChain<VkPhysicalDeviceShaderClockFeaturesKHR>(pCreateInfo->pNext);
1110 if (shader_clock_features) {
1111 state_tracker->enabled_features.shader_clock_features = *shader_clock_features;
1112 }
sfricke-samsung486a51e2021-01-02 00:10:15 -08001113
sfricke-samsung828e59d2021-08-22 23:20:49 -07001114 const auto *conditional_rendering_features =
1115 LvlFindInChain<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(pCreateInfo->pNext);
1116 if (conditional_rendering_features) {
1117 state_tracker->enabled_features.conditional_rendering_features = *conditional_rendering_features;
1118 }
Jeremy Gebben5f585ae2021-02-02 09:03:06 -07001119
sfricke-samsung828e59d2021-08-22 23:20:49 -07001120 const auto *workgroup_memory_explicit_layout_features =
1121 LvlFindInChain<VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>(pCreateInfo->pNext);
1122 if (workgroup_memory_explicit_layout_features) {
1123 state_tracker->enabled_features.workgroup_memory_explicit_layout_features = *workgroup_memory_explicit_layout_features;
1124 }
Shannon McPhersondb287d42021-02-02 15:27:32 -07001125
sfricke-samsung828e59d2021-08-22 23:20:49 -07001126 const auto *synchronization2_features = LvlFindInChain<VkPhysicalDeviceSynchronization2FeaturesKHR>(pCreateInfo->pNext);
1127 if (synchronization2_features) {
1128 state_tracker->enabled_features.synchronization2_features = *synchronization2_features;
1129 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001130
sfricke-samsung828e59d2021-08-22 23:20:49 -07001131 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(pCreateInfo->pNext);
1132 if (provoking_vertex_features) {
1133 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
1134 }
Locke Linf3873542021-04-26 11:25:10 -06001135
sfricke-samsung828e59d2021-08-22 23:20:49 -07001136 const auto *vertex_input_dynamic_state_features =
1137 LvlFindInChain<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>(pCreateInfo->pNext);
1138 if (vertex_input_dynamic_state_features) {
1139 state_tracker->enabled_features.vertex_input_dynamic_state_features = *vertex_input_dynamic_state_features;
1140 }
Piers Daniellcb6d8032021-04-19 18:51:26 -06001141
sfricke-samsung828e59d2021-08-22 23:20:49 -07001142 const auto *inherited_viewport_scissor_features =
1143 LvlFindInChain<VkPhysicalDeviceInheritedViewportScissorFeaturesNV>(pCreateInfo->pNext);
1144 if (inherited_viewport_scissor_features) {
1145 state_tracker->enabled_features.inherited_viewport_scissor_features = *inherited_viewport_scissor_features;
1146 }
David Zhao Akeley44139b12021-04-26 16:16:13 -07001147
sfricke-samsung828e59d2021-08-22 23:20:49 -07001148 const auto *multi_draw_features = LvlFindInChain<VkPhysicalDeviceMultiDrawFeaturesEXT>(pCreateInfo->pNext);
1149 if (multi_draw_features) {
1150 state_tracker->enabled_features.multi_draw_features = *multi_draw_features;
1151 }
Tony-LunarG4490de42021-06-21 15:49:19 -06001152
sfricke-samsung828e59d2021-08-22 23:20:49 -07001153 const auto *color_write_features = LvlFindInChain<VkPhysicalDeviceColorWriteEnableFeaturesEXT>(pCreateInfo->pNext);
1154 if (color_write_features) {
1155 state_tracker->enabled_features.color_write_features = *color_write_features;
1156 }
ziga-lunarg29ba2b92021-07-20 21:51:45 +02001157
sfricke-samsung828e59d2021-08-22 23:20:49 -07001158 const auto *shader_atomic_float2_features =
1159 LvlFindInChain<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>(pCreateInfo->pNext);
1160 if (shader_atomic_float2_features) {
1161 state_tracker->enabled_features.shader_atomic_float2_features = *shader_atomic_float2_features;
1162 }
Mike Schuchardtb3870ea2021-07-20 18:56:51 -07001163
sfricke-samsung828e59d2021-08-22 23:20:49 -07001164 const auto *present_id_features = LvlFindInChain<VkPhysicalDevicePresentIdFeaturesKHR>(pCreateInfo->pNext);
1165 if (present_id_features) {
1166 state_tracker->enabled_features.present_id_features = *present_id_features;
1167 }
Tony-LunarG6f887e52021-07-27 11:23:14 -06001168
sfricke-samsung828e59d2021-08-22 23:20:49 -07001169 const auto *present_wait_features = LvlFindInChain<VkPhysicalDevicePresentWaitFeaturesKHR>(pCreateInfo->pNext);
1170 if (present_wait_features) {
1171 state_tracker->enabled_features.present_wait_features = *present_wait_features;
1172 }
Mike Schuchardt9f65d3f2021-08-25 15:11:39 -07001173
1174 const auto *ray_tracing_motion_blur_features =
1175 LvlFindInChain<VkPhysicalDeviceRayTracingMotionBlurFeaturesNV>(pCreateInfo->pNext);
1176 if (ray_tracing_motion_blur_features) {
1177 state_tracker->enabled_features.ray_tracing_motion_blur_features = *ray_tracing_motion_blur_features;
1178 }
Mike Schuchardtb4d90452021-08-30 09:24:51 -07001179
1180 const auto *shader_integer_dot_product_features =
1181 LvlFindInChain<VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR>(pCreateInfo->pNext);
1182 if (shader_integer_dot_product_features) {
1183 state_tracker->enabled_features.shader_integer_dot_product_features = *shader_integer_dot_product_features;
1184 }
Tony-LunarG6f887e52021-07-27 11:23:14 -06001185 }
1186
locke-lunargd556cc32019-09-17 01:21:23 -06001187 // Store physical device properties and physical device mem limits into CoreChecks structs
1188 DispatchGetPhysicalDeviceMemoryProperties(gpu, &state_tracker->phys_dev_mem_props);
1189 DispatchGetPhysicalDeviceProperties(gpu, &state_tracker->phys_dev_props);
1190
1191 const auto &dev_ext = state_tracker->device_extensions;
1192 auto *phys_dev_props = &state_tracker->phys_dev_ext_props;
1193
sfricke-samsung828e59d2021-08-22 23:20:49 -07001194 // Vulkan 1.2 can get properties from single struct, otherwise need to add to it per extension
1195 if (state_tracker->device_extensions.vk_feature_version_1_2) {
1196 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1197 &state_tracker->phys_dev_props_core11);
1198 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1199 &state_tracker->phys_dev_props_core12);
1200 } else {
1201 // VkPhysicalDeviceVulkan11Properties
1202 //
1203 // Can ingnore VkPhysicalDeviceIDProperties as it has no validation purpose
1204
1205 if (dev_ext.vk_khr_multiview) {
1206 auto multiview_props = LvlInitStruct<VkPhysicalDeviceMultiviewProperties>();
1207 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_multiview, &multiview_props);
1208 state_tracker->phys_dev_props_core11.maxMultiviewViewCount = multiview_props.maxMultiviewViewCount;
1209 state_tracker->phys_dev_props_core11.maxMultiviewInstanceIndex = multiview_props.maxMultiviewInstanceIndex;
1210 }
1211
1212 if (dev_ext.vk_khr_maintenance3) {
1213 auto maintenance3_props = LvlInitStruct<VkPhysicalDeviceMaintenance3Properties>();
1214 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_maintenance3, &maintenance3_props);
1215 state_tracker->phys_dev_props_core11.maxPerSetDescriptors = maintenance3_props.maxPerSetDescriptors;
1216 state_tracker->phys_dev_props_core11.maxMemoryAllocationSize = maintenance3_props.maxMemoryAllocationSize;
1217 }
1218
1219 // Some 1.1 properties were added to core without previous extensions
1220 if (state_tracker->api_version >= VK_API_VERSION_1_1) {
1221 auto subgroup_prop = LvlInitStruct<VkPhysicalDeviceSubgroupProperties>();
1222 auto protected_memory_prop = LvlInitStruct<VkPhysicalDeviceProtectedMemoryProperties>(&subgroup_prop);
1223 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&protected_memory_prop);
1224 instance_dispatch_table.GetPhysicalDeviceProperties2(gpu, &prop2);
1225
1226 state_tracker->phys_dev_props_core11.subgroupSize = subgroup_prop.subgroupSize;
1227 state_tracker->phys_dev_props_core11.subgroupSupportedStages = subgroup_prop.supportedStages;
1228 state_tracker->phys_dev_props_core11.subgroupSupportedOperations = subgroup_prop.supportedOperations;
1229 state_tracker->phys_dev_props_core11.subgroupQuadOperationsInAllStages = subgroup_prop.quadOperationsInAllStages;
1230
1231 state_tracker->phys_dev_props_core11.protectedNoFault = protected_memory_prop.protectedNoFault;
1232 }
1233
1234 // VkPhysicalDeviceVulkan12Properties
1235 //
1236 // Can ingnore VkPhysicalDeviceDriverProperties as it has no validation purpose
1237
1238 if (dev_ext.vk_ext_descriptor_indexing) {
1239 auto descriptor_indexing_prop = LvlInitStruct<VkPhysicalDeviceDescriptorIndexingProperties>();
1240 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_descriptor_indexing, &descriptor_indexing_prop);
1241 state_tracker->phys_dev_props_core12.maxUpdateAfterBindDescriptorsInAllPools =
1242 descriptor_indexing_prop.maxUpdateAfterBindDescriptorsInAllPools;
1243 state_tracker->phys_dev_props_core12.shaderUniformBufferArrayNonUniformIndexingNative =
1244 descriptor_indexing_prop.shaderUniformBufferArrayNonUniformIndexingNative;
1245 state_tracker->phys_dev_props_core12.shaderSampledImageArrayNonUniformIndexingNative =
1246 descriptor_indexing_prop.shaderSampledImageArrayNonUniformIndexingNative;
1247 state_tracker->phys_dev_props_core12.shaderStorageBufferArrayNonUniformIndexingNative =
1248 descriptor_indexing_prop.shaderStorageBufferArrayNonUniformIndexingNative;
1249 state_tracker->phys_dev_props_core12.shaderStorageImageArrayNonUniformIndexingNative =
1250 descriptor_indexing_prop.shaderStorageImageArrayNonUniformIndexingNative;
1251 state_tracker->phys_dev_props_core12.shaderInputAttachmentArrayNonUniformIndexingNative =
1252 descriptor_indexing_prop.shaderInputAttachmentArrayNonUniformIndexingNative;
1253 state_tracker->phys_dev_props_core12.robustBufferAccessUpdateAfterBind =
1254 descriptor_indexing_prop.robustBufferAccessUpdateAfterBind;
1255 state_tracker->phys_dev_props_core12.quadDivergentImplicitLod = descriptor_indexing_prop.quadDivergentImplicitLod;
1256 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSamplers =
1257 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSamplers;
1258 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindUniformBuffers =
1259 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindUniformBuffers;
1260 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageBuffers =
1261 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageBuffers;
1262 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSampledImages =
1263 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSampledImages;
1264 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageImages =
1265 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageImages;
1266 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindInputAttachments =
1267 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindInputAttachments;
1268 state_tracker->phys_dev_props_core12.maxPerStageUpdateAfterBindResources =
1269 descriptor_indexing_prop.maxPerStageUpdateAfterBindResources;
1270 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSamplers =
1271 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSamplers;
1272 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffers =
1273 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffers;
1274 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
1275 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
1276 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffers =
1277 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffers;
1278 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
1279 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
1280 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSampledImages =
1281 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSampledImages;
1282 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageImages =
1283 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageImages;
1284 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindInputAttachments =
1285 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindInputAttachments;
1286 }
1287
1288 if (dev_ext.vk_khr_depth_stencil_resolve) {
1289 auto depth_stencil_resolve_props = LvlInitStruct<VkPhysicalDeviceDepthStencilResolveProperties>();
1290 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_depth_stencil_resolve, &depth_stencil_resolve_props);
1291 state_tracker->phys_dev_props_core12.supportedDepthResolveModes =
1292 depth_stencil_resolve_props.supportedDepthResolveModes;
1293 state_tracker->phys_dev_props_core12.supportedStencilResolveModes =
1294 depth_stencil_resolve_props.supportedStencilResolveModes;
1295 state_tracker->phys_dev_props_core12.independentResolveNone = depth_stencil_resolve_props.independentResolveNone;
1296 state_tracker->phys_dev_props_core12.independentResolve = depth_stencil_resolve_props.independentResolve;
1297 }
1298
1299 if (dev_ext.vk_khr_timeline_semaphore) {
1300 auto timeline_semaphore_props = LvlInitStruct<VkPhysicalDeviceTimelineSemaphoreProperties>();
1301 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_timeline_semaphore, &timeline_semaphore_props);
1302 state_tracker->phys_dev_props_core12.maxTimelineSemaphoreValueDifference =
1303 timeline_semaphore_props.maxTimelineSemaphoreValueDifference;
1304 }
1305
1306 if (dev_ext.vk_ext_sampler_filter_minmax) {
1307 auto sampler_filter_minmax_props = LvlInitStruct<VkPhysicalDeviceSamplerFilterMinmaxProperties>();
1308 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_sampler_filter_minmax, &sampler_filter_minmax_props);
1309 state_tracker->phys_dev_props_core12.filterMinmaxSingleComponentFormats =
1310 sampler_filter_minmax_props.filterMinmaxSingleComponentFormats;
1311 state_tracker->phys_dev_props_core12.filterMinmaxImageComponentMapping =
1312 sampler_filter_minmax_props.filterMinmaxImageComponentMapping;
1313 }
1314
1315 if (dev_ext.vk_khr_shader_float_controls) {
1316 auto float_controls_props = LvlInitStruct<VkPhysicalDeviceFloatControlsProperties>();
1317 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_shader_float_controls, &float_controls_props);
1318 state_tracker->phys_dev_props_core12.denormBehaviorIndependence = float_controls_props.denormBehaviorIndependence;
1319 state_tracker->phys_dev_props_core12.roundingModeIndependence = float_controls_props.roundingModeIndependence;
1320 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat16 =
1321 float_controls_props.shaderSignedZeroInfNanPreserveFloat16;
1322 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat32 =
1323 float_controls_props.shaderSignedZeroInfNanPreserveFloat32;
1324 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat64 =
1325 float_controls_props.shaderSignedZeroInfNanPreserveFloat64;
1326 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat16 = float_controls_props.shaderDenormPreserveFloat16;
1327 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat32 = float_controls_props.shaderDenormPreserveFloat32;
1328 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat64 = float_controls_props.shaderDenormPreserveFloat64;
1329 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat16 =
1330 float_controls_props.shaderDenormFlushToZeroFloat16;
1331 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat32 =
1332 float_controls_props.shaderDenormFlushToZeroFloat32;
1333 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat64 =
1334 float_controls_props.shaderDenormFlushToZeroFloat64;
1335 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat16 = float_controls_props.shaderRoundingModeRTEFloat16;
1336 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat32 = float_controls_props.shaderRoundingModeRTEFloat32;
1337 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat64 = float_controls_props.shaderRoundingModeRTEFloat64;
1338 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat16 = float_controls_props.shaderRoundingModeRTZFloat16;
1339 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat32 = float_controls_props.shaderRoundingModeRTZFloat32;
1340 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat64 = float_controls_props.shaderRoundingModeRTZFloat64;
1341 }
locke-lunargd556cc32019-09-17 01:21:23 -06001342 }
1343
sfricke-samsung828e59d2021-08-22 23:20:49 -07001344 // Extensions with properties to extract to DeviceExtensionProperties
1345 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_push_descriptor, &phys_dev_props->push_descriptor_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001346 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_shading_rate_image, &phys_dev_props->shading_rate_image_props);
1347 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_mesh_shader, &phys_dev_props->mesh_shader_props);
1348 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_inline_uniform_block, &phys_dev_props->inline_uniform_block_props);
1349 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_vertex_attribute_divisor, &phys_dev_props->vtx_attrib_divisor_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001350 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_transform_feedback, &phys_dev_props->transform_feedback_props);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001351 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_ray_tracing, &phys_dev_props->ray_tracing_propsNV);
sourav parmarcd5fb182020-07-17 12:58:44 -07001352 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_ray_tracing_pipeline, &phys_dev_props->ray_tracing_propsKHR);
1353 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_acceleration_structure, &phys_dev_props->acc_structure_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001354 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_texel_buffer_alignment, &phys_dev_props->texel_buffer_alignment_props);
1355 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map, &phys_dev_props->fragment_density_map_props);
Mike Schuchardtc57de4a2021-07-20 17:26:32 -07001356 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map2, &phys_dev_props->fragment_density_map2_props);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001357 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_performance_query, &phys_dev_props->performance_query_props);
sfricke-samsung8f658d42020-05-03 20:12:24 -07001358 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_sample_locations, &phys_dev_props->sample_locations_props);
Tony-LunarG7337b312020-04-15 16:40:25 -06001359 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_custom_border_color, &phys_dev_props->custom_border_color_props);
locke-lunarg3fa463a2020-10-23 16:39:04 -06001360 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_multiview, &phys_dev_props->multiview_props);
Nathaniel Cesario3291c912020-11-17 16:54:41 -07001361 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_portability_subset, &phys_dev_props->portability_props);
sfricke-samsung828e59d2021-08-22 23:20:49 -07001362 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_fragment_shading_rate, &phys_dev_props->fragment_shading_rate_props);
Locke Lin016d8482021-05-27 12:11:31 -06001363 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_provoking_vertex, &phys_dev_props->provoking_vertex_props);
Tony-LunarG4490de42021-06-21 15:49:19 -06001364 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_multi_draw, &phys_dev_props->multi_draw_props);
ziga-lunarg128904a2021-07-30 13:49:01 +02001365 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_discard_rectangles, &phys_dev_props->discard_rectangle_props);
ziga-lunarg86492812021-08-05 23:58:16 +02001366 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_blend_operation_advanced, &phys_dev_props->blend_operation_advanced_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001367
locke-lunargd556cc32019-09-17 01:21:23 -06001368 if (state_tracker->device_extensions.vk_nv_cooperative_matrix) {
1369 // Get the needed cooperative_matrix properties
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001370 auto cooperative_matrix_props = LvlInitStruct<VkPhysicalDeviceCooperativeMatrixPropertiesNV>();
1371 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&cooperative_matrix_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001372 instance_dispatch_table.GetPhysicalDeviceProperties2KHR(gpu, &prop2);
1373 state_tracker->phys_dev_ext_props.cooperative_matrix_props = cooperative_matrix_props;
1374
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001375 uint32_t num_cooperative_matrix_properties = 0;
1376 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties, NULL);
1377 state_tracker->cooperative_matrix_properties.resize(num_cooperative_matrix_properties,
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001378 LvlInitStruct<VkCooperativeMatrixPropertiesNV>());
locke-lunargd556cc32019-09-17 01:21:23 -06001379
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001380 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties,
locke-lunargd556cc32019-09-17 01:21:23 -06001381 state_tracker->cooperative_matrix_properties.data());
1382 }
Tobias Hector6663c9b2020-11-05 10:18:02 +00001383
locke-lunargd556cc32019-09-17 01:21:23 -06001384 // Store queue family data
1385 if (pCreateInfo->pQueueCreateInfos != nullptr) {
1386 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
sfricke-samsung590ae1e2020-04-25 01:18:05 -07001387 const VkDeviceQueueCreateInfo &queue_create_info = pCreateInfo->pQueueCreateInfos[i];
sfricke-samsungb585ec12021-05-06 03:10:13 -07001388 state_tracker->queue_family_index_set.insert(queue_create_info.queueFamilyIndex);
1389 state_tracker->device_queue_info_list.push_back(
1390 {i, queue_create_info.queueFamilyIndex, queue_create_info.flags, queue_create_info.queueCount});
locke-lunargd556cc32019-09-17 01:21:23 -06001391 }
1392 }
1393}
1394
1395void ValidationStateTracker::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
1396 if (!device) return;
1397
locke-lunargd556cc32019-09-17 01:21:23 -06001398 // Reset all command buffers before destroying them, to unlink object_bindings.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001399 for (auto &command_buffer : commandBufferMap) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001400 command_buffer.second->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06001401 }
Jeff Bolzadbfa852019-10-04 13:53:30 -05001402 pipelineMap.clear();
1403 renderPassMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001404 commandBufferMap.clear();
1405
1406 // This will also delete all sets in the pool & remove them from setMap
1407 DeleteDescriptorSetPools();
1408 // All sets should be removed
1409 assert(setMap.empty());
1410 descriptorSetLayoutMap.clear();
Jeremy Gebben5a542f52021-07-21 15:25:52 -06001411 // Because swapchains are associated with Surfaces, which are at instance level,
1412 // they need to be explicitly destroyed here to avoid continued references to
1413 // the device we're destroying.
1414 for (auto &entry : swapchainMap) {
1415 entry.second->Destroy();
1416 }
1417 swapchainMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001418 imageViewMap.clear();
1419 imageMap.clear();
1420 bufferViewMap.clear();
1421 bufferMap.clear();
1422 // Queues persist until device is destroyed
1423 queueMap.clear();
1424}
1425
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001426void ValidationStateTracker::RetireWorkOnQueue(QUEUE_STATE *pQueue, uint64_t seq) {
Jeremy Gebbencbf22862021-03-03 12:01:22 -07001427 layer_data::unordered_map<VkQueue, uint64_t> other_queue_seqs;
1428 layer_data::unordered_map<VkSemaphore, uint64_t> timeline_semaphore_counters;
locke-lunargd556cc32019-09-17 01:21:23 -06001429
1430 // Roll this queue forward, one submission at a time.
1431 while (pQueue->seq < seq) {
1432 auto &submission = pQueue->submissions.front();
1433
1434 for (auto &wait : submission.waitSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001435 auto semaphore_state = GetSemaphoreState(wait.semaphore);
1436 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001437 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001438 }
Mike Schuchardt2df08912020-12-15 16:28:09 -08001439 if (wait.type == VK_SEMAPHORE_TYPE_TIMELINE) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001440 auto &last_counter = timeline_semaphore_counters[wait.semaphore];
1441 last_counter = std::max(last_counter, wait.payload);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001442 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001443 auto &last_seq = other_queue_seqs[wait.queue];
1444 last_seq = std::max(last_seq, wait.seq);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001445 }
locke-lunargd556cc32019-09-17 01:21:23 -06001446 }
1447
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001448 for (auto &signal : submission.signalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001449 auto semaphore_state = GetSemaphoreState(signal.semaphore);
1450 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001451 semaphore_state->EndUse();
Mike Schuchardt2df08912020-12-15 16:28:09 -08001452 if (semaphore_state->type == VK_SEMAPHORE_TYPE_TIMELINE && semaphore_state->payload < signal.payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001453 semaphore_state->payload = signal.payload;
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001454 }
locke-lunargd556cc32019-09-17 01:21:23 -06001455 }
1456 }
1457
1458 for (auto &semaphore : submission.externalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001459 auto semaphore_state = GetSemaphoreState(semaphore);
1460 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001461 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001462 }
1463 }
1464
1465 for (auto cb : submission.cbs) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06001466 auto cb_node = Get<CMD_BUFFER_STATE>(cb);
locke-lunargd556cc32019-09-17 01:21:23 -06001467 if (!cb_node) {
1468 continue;
1469 }
1470 // First perform decrement on general case bound objects
locke-lunargd556cc32019-09-17 01:21:23 -06001471 for (auto event : cb_node->writeEventsBeforeWait) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001472 auto event_node = eventMap.find(event);
1473 if (event_node != eventMap.end()) {
John Zulauf48057322020-12-02 11:59:31 -07001474 event_node->second->write_in_use--;
locke-lunargd556cc32019-09-17 01:21:23 -06001475 }
1476 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001477 QueryMap local_query_to_state_map;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001478 VkQueryPool first_pool = VK_NULL_HANDLE;
Jeff Bolz310775c2019-10-09 00:46:33 -05001479 for (auto &function : cb_node->queryUpdates) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001480 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
Jeff Bolz310775c2019-10-09 00:46:33 -05001481 }
1482
John Zulauf79f06582021-02-27 18:38:39 -07001483 for (const auto &query_state_pair : local_query_to_state_map) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001484 if (query_state_pair.second == QUERYSTATE_ENDED) {
1485 queryToStateMap[query_state_pair.first] = QUERYSTATE_AVAILABLE;
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001486 }
locke-lunargd556cc32019-09-17 01:21:23 -06001487 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001488 if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
1489 cb_node->EndUse();
1490 }
locke-lunargd556cc32019-09-17 01:21:23 -06001491 }
1492
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001493 auto fence_state = GetFenceState(submission.fence);
1494 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1495 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001496 }
1497
1498 pQueue->submissions.pop_front();
1499 pQueue->seq++;
1500 }
1501
1502 // Roll other queues forward to the highest seq we saw a wait for
John Zulauf79f06582021-02-27 18:38:39 -07001503 for (const auto &qs : other_queue_seqs) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001504 RetireWorkOnQueue(GetQueueState(qs.first), qs.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001505 }
John Zulauf79f06582021-02-27 18:38:39 -07001506 for (const auto &sc : timeline_semaphore_counters) {
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001507 RetireTimelineSemaphore(sc.first, sc.second);
1508 }
locke-lunargd556cc32019-09-17 01:21:23 -06001509}
1510
1511// Submit a fence to a queue, delimiting previous fences and previous untracked
1512// work by it.
1513static void SubmitFence(QUEUE_STATE *pQueue, FENCE_STATE *pFence, uint64_t submitCount) {
1514 pFence->state = FENCE_INFLIGHT;
1515 pFence->signaler.first = pQueue->queue;
1516 pFence->signaler.second = pQueue->seq + pQueue->submissions.size() + submitCount;
1517}
1518
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001519uint64_t ValidationStateTracker::RecordSubmitFence(QUEUE_STATE *queue_state, VkFence fence, uint32_t submit_count) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001520 auto fence_state = GetFenceState(fence);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001521 uint64_t early_retire_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001522 if (fence_state) {
1523 if (fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06001524 // Mark fence in use
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001525 SubmitFence(queue_state, fence_state, std::max(1u, submit_count));
1526 if (!submit_count) {
locke-lunargd556cc32019-09-17 01:21:23 -06001527 // If no submissions, but just dropping a fence on the end of the queue,
1528 // record an empty submission with just the fence, so we can determine
1529 // its completion.
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001530 CB_SUBMISSION submission;
1531 submission.fence = fence;
1532 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001533 }
1534 } else {
1535 // 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 -07001536 early_retire_seq = queue_state->seq + queue_state->submissions.size();
locke-lunargd556cc32019-09-17 01:21:23 -06001537 }
1538 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001539 return early_retire_seq;
1540}
1541
1542void ValidationStateTracker::RecordSubmitCommandBuffer(CB_SUBMISSION &submission, VkCommandBuffer command_buffer) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06001543 auto cb_node = Get<CMD_BUFFER_STATE>(command_buffer);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001544 if (cb_node) {
1545 submission.cbs.push_back(command_buffer);
John Zulauf79f06582021-02-27 18:38:39 -07001546 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001547 submission.cbs.push_back(secondary_cmd_buffer->commandBuffer());
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001548 secondary_cmd_buffer->IncrementResources();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001549 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001550 cb_node->IncrementResources();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001551 // increment use count for all bound objects including secondary cbs
1552 cb_node->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001553
1554 VkQueryPool first_pool = VK_NULL_HANDLE;
1555 EventToStageMap local_event_to_stage_map;
1556 QueryMap local_query_to_state_map;
1557 for (auto &function : cb_node->queryUpdates) {
1558 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
1559 }
1560
John Zulauf79f06582021-02-27 18:38:39 -07001561 for (const auto &query_state_pair : local_query_to_state_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001562 queryToStateMap[query_state_pair.first] = query_state_pair.second;
1563 }
1564
John Zulauf79f06582021-02-27 18:38:39 -07001565 for (const auto &function : cb_node->eventUpdates) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001566 function(nullptr, /*do_validate*/ false, &local_event_to_stage_map);
1567 }
1568
John Zulauf79f06582021-02-27 18:38:39 -07001569 for (const auto &eventStagePair : local_event_to_stage_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001570 eventMap[eventStagePair.first]->stageMask = eventStagePair.second;
1571 }
1572 }
1573}
1574
1575void ValidationStateTracker::RecordSubmitWaitSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1576 uint64_t value, uint64_t next_seq) {
1577 auto semaphore_state = GetSemaphoreState(semaphore);
1578 if (semaphore_state) {
1579 if (semaphore_state->scope == kSyncScopeInternal) {
1580 SEMAPHORE_WAIT wait;
1581 wait.semaphore = semaphore;
1582 wait.type = semaphore_state->type;
1583 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1584 if (semaphore_state->signaler.first != VK_NULL_HANDLE) {
1585 wait.queue = semaphore_state->signaler.first;
1586 wait.seq = semaphore_state->signaler.second;
1587 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001588 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001589 }
1590 semaphore_state->signaler.first = VK_NULL_HANDLE;
1591 semaphore_state->signaled = false;
1592 } else if (semaphore_state->payload < value) {
1593 wait.queue = queue;
1594 wait.seq = next_seq;
1595 wait.payload = value;
1596 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001597 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001598 }
1599 } else {
1600 submission.externalSemaphores.push_back(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001601 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001602 if (semaphore_state->scope == kSyncScopeExternalTemporary) {
1603 semaphore_state->scope = kSyncScopeInternal;
1604 }
1605 }
1606 }
1607}
1608
1609bool ValidationStateTracker::RecordSubmitSignalSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1610 uint64_t value, uint64_t next_seq) {
1611 bool retire_early = false;
1612 auto semaphore_state = GetSemaphoreState(semaphore);
1613 if (semaphore_state) {
1614 if (semaphore_state->scope == kSyncScopeInternal) {
1615 SEMAPHORE_SIGNAL signal;
1616 signal.semaphore = semaphore;
1617 signal.seq = next_seq;
1618 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1619 semaphore_state->signaler.first = queue;
1620 semaphore_state->signaler.second = next_seq;
1621 semaphore_state->signaled = true;
1622 } else {
1623 signal.payload = value;
1624 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001625 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001626 submission.signalSemaphores.emplace_back(std::move(signal));
1627 } else {
1628 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1629 retire_early = true;
1630 }
1631 }
1632 return retire_early;
1633}
1634
1635void ValidationStateTracker::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
1636 VkFence fence, VkResult result) {
1637 if (result != VK_SUCCESS) return;
1638 auto queue_state = GetQueueState(queue);
1639
1640 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001641
1642 // Now process each individual submit
1643 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001644 CB_SUBMISSION submission;
locke-lunargd556cc32019-09-17 01:21:23 -06001645 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001646 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001647 auto *timeline_semaphore_submit = LvlFindInChain<VkTimelineSemaphoreSubmitInfo>(submit->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001648 for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001649 uint64_t value = 0;
1650 if (timeline_semaphore_submit && timeline_semaphore_submit->pWaitSemaphoreValues != nullptr &&
1651 (i < timeline_semaphore_submit->waitSemaphoreValueCount)) {
1652 value = timeline_semaphore_submit->pWaitSemaphoreValues[i];
1653 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001654 RecordSubmitWaitSemaphore(submission, queue, submit->pWaitSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001655 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001656
1657 bool retire_early = false;
locke-lunargd556cc32019-09-17 01:21:23 -06001658 for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001659 uint64_t value = 0;
1660 if (timeline_semaphore_submit && timeline_semaphore_submit->pSignalSemaphoreValues != nullptr &&
1661 (i < timeline_semaphore_submit->signalSemaphoreValueCount)) {
1662 value = timeline_semaphore_submit->pSignalSemaphoreValues[i];
1663 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001664 retire_early |= RecordSubmitSignalSemaphore(submission, queue, submit->pSignalSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001665 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001666 if (retire_early) {
1667 early_retire_seq = std::max(early_retire_seq, next_seq);
1668 }
1669
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001670 const auto perf_submit = LvlFindInChain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001671 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001672
locke-lunargd556cc32019-09-17 01:21:23 -06001673 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001674 RecordSubmitCommandBuffer(submission, submit->pCommandBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06001675 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001676 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1677 queue_state->submissions.emplace_back(std::move(submission));
1678 }
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001679
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001680 if (early_retire_seq) {
1681 RetireWorkOnQueue(queue_state, early_retire_seq);
1682 }
1683}
1684
1685void ValidationStateTracker::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1686 VkFence fence, VkResult result) {
1687 if (result != VK_SUCCESS) return;
1688 auto queue_state = GetQueueState(queue);
1689
1690 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
1691
1692 // Now process each individual submit
1693 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1694 CB_SUBMISSION submission;
1695 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1696 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
1697 for (uint32_t i = 0; i < submit->waitSemaphoreInfoCount; ++i) {
1698 const auto &sem_info = submit->pWaitSemaphoreInfos[i];
1699 RecordSubmitWaitSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1700 }
1701 bool retire_early = false;
1702 for (uint32_t i = 0; i < submit->signalSemaphoreInfoCount; ++i) {
1703 const auto &sem_info = submit->pSignalSemaphoreInfos[i];
1704 retire_early |= RecordSubmitSignalSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1705 }
1706 if (retire_early) {
1707 early_retire_seq = std::max(early_retire_seq, next_seq);
1708 }
1709 const auto perf_submit = lvl_find_in_chain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
1710 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
1711
1712 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1713 RecordSubmitCommandBuffer(submission, submit->pCommandBufferInfos[i].commandBuffer);
1714 }
1715 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1716 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001717 }
1718
1719 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001720 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001721 }
1722}
1723
1724void ValidationStateTracker::PostCallRecordAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
1725 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory,
1726 VkResult result) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001727 if (VK_SUCCESS != result) {
1728 return;
locke-lunargd556cc32019-09-17 01:21:23 -06001729 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001730 const auto &memory_type = phys_dev_mem_props.memoryTypes[pAllocateInfo->memoryTypeIndex];
1731 const auto &memory_heap = phys_dev_mem_props.memoryHeaps[memory_type.heapIndex];
1732 auto fake_address = fake_memory.Alloc(pAllocateInfo->allocationSize);
1733
1734 layer_data::optional<DedicatedBinding> dedicated_binding;
1735
1736 auto dedicated = LvlFindInChain<VkMemoryDedicatedAllocateInfo>(pAllocateInfo->pNext);
1737 if (dedicated) {
1738 if (dedicated->buffer) {
1739 const auto *buffer_state = GetBufferState(dedicated->buffer);
1740 assert(buffer_state);
1741 if (!buffer_state) {
1742 return;
1743 }
1744 dedicated_binding.emplace(dedicated->buffer, buffer_state->createInfo);
1745 } else if (dedicated->image) {
1746 const auto *image_state = GetImageState(dedicated->image);
1747 assert(image_state);
1748 if (!image_state) {
1749 return;
1750 }
1751 dedicated_binding.emplace(dedicated->image, image_state->createInfo);
1752 }
1753 }
1754 memObjMap[*pMemory] = std::make_shared<DEVICE_MEMORY_STATE>(*pMemory, pAllocateInfo, fake_address, memory_type, memory_heap,
1755 std::move(dedicated_binding));
locke-lunargd556cc32019-09-17 01:21:23 -06001756 return;
1757}
1758
1759void ValidationStateTracker::PreCallRecordFreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
1760 if (!mem) return;
1761 DEVICE_MEMORY_STATE *mem_info = GetDevMemState(mem);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001762 if (!mem_info) return;
locke-lunargd556cc32019-09-17 01:21:23 -06001763 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001764 mem_info->Destroy();
John Zulauf79952712020-04-07 11:25:54 -06001765 fake_memory.Free(mem_info->fake_base_address);
locke-lunargd556cc32019-09-17 01:21:23 -06001766 memObjMap.erase(mem);
1767}
1768
1769void ValidationStateTracker::PostCallRecordQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo,
1770 VkFence fence, VkResult result) {
1771 if (result != VK_SUCCESS) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001772 auto queue_state = GetQueueState(queue);
locke-lunargd556cc32019-09-17 01:21:23 -06001773
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001774 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, bindInfoCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001775
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001776 for (uint32_t bind_idx = 0; bind_idx < bindInfoCount; ++bind_idx) {
1777 const VkBindSparseInfo &bind_info = pBindInfo[bind_idx];
locke-lunargd556cc32019-09-17 01:21:23 -06001778 // Track objects tied to memory
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001779 for (uint32_t j = 0; j < bind_info.bufferBindCount; j++) {
1780 for (uint32_t k = 0; k < bind_info.pBufferBinds[j].bindCount; k++) {
1781 auto sparse_binding = bind_info.pBufferBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001782 auto buffer_state = GetBufferState(bind_info.pBufferBinds[j].buffer);
1783 auto mem_state = GetDevMemShared(sparse_binding.memory);
1784 if (buffer_state && mem_state) {
1785 buffer_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1786 }
locke-lunargd556cc32019-09-17 01:21:23 -06001787 }
1788 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001789 for (uint32_t j = 0; j < bind_info.imageOpaqueBindCount; j++) {
1790 for (uint32_t k = 0; k < bind_info.pImageOpaqueBinds[j].bindCount; k++) {
1791 auto sparse_binding = bind_info.pImageOpaqueBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001792 auto image_state = GetImageState(bind_info.pImageOpaqueBinds[j].image);
1793 auto mem_state = GetDevMemShared(sparse_binding.memory);
1794 if (image_state && mem_state) {
1795 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1796 }
locke-lunargd556cc32019-09-17 01:21:23 -06001797 }
1798 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001799 for (uint32_t j = 0; j < bind_info.imageBindCount; j++) {
1800 for (uint32_t k = 0; k < bind_info.pImageBinds[j].bindCount; k++) {
1801 auto sparse_binding = bind_info.pImageBinds[j].pBinds[k];
locke-lunargd556cc32019-09-17 01:21:23 -06001802 // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data
1803 VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001804 auto image_state = GetImageState(bind_info.pImageBinds[j].image);
1805 auto mem_state = GetDevMemShared(sparse_binding.memory);
1806 if (image_state && mem_state) {
1807 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, size);
1808 }
locke-lunargd556cc32019-09-17 01:21:23 -06001809 }
1810 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001811 CB_SUBMISSION submission;
1812 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001813 for (uint32_t i = 0; i < bind_info.waitSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001814 RecordSubmitWaitSemaphore(submission, queue, bind_info.pWaitSemaphores[i], 0, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001815 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001816 bool retire_early = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001817 for (uint32_t i = 0; i < bind_info.signalSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001818 retire_early |= RecordSubmitSignalSemaphore(submission, queue, bind_info.pSignalSemaphores[i], 0, next_seq);
1819 }
1820 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1821 if (retire_early) {
1822 early_retire_seq = std::max(early_retire_seq, queue_state->seq + queue_state->submissions.size() + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06001823 }
1824
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001825 submission.fence = bind_idx == (bindInfoCount - 1) ? fence : VK_NULL_HANDLE;
1826 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001827 }
1828
1829 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001830 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001831 }
1832}
1833
1834void ValidationStateTracker::PostCallRecordCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
1835 const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore,
1836 VkResult result) {
1837 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001838 semaphoreMap[*pSemaphore] = std::make_shared<SEMAPHORE_STATE>(*pSemaphore, LvlFindInChain<VkSemaphoreTypeCreateInfo>(pCreateInfo->pNext));
locke-lunargd556cc32019-09-17 01:21:23 -06001839}
1840
Mike Schuchardt2df08912020-12-15 16:28:09 -08001841void ValidationStateTracker::RecordImportSemaphoreState(VkSemaphore semaphore, VkExternalSemaphoreHandleTypeFlagBits handle_type,
1842 VkSemaphoreImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06001843 SEMAPHORE_STATE *sema_node = GetSemaphoreState(semaphore);
1844 if (sema_node && sema_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001845 if ((handle_type == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06001846 sema_node->scope == kSyncScopeInternal) {
1847 sema_node->scope = kSyncScopeExternalTemporary;
1848 } else {
1849 sema_node->scope = kSyncScopeExternalPermanent;
1850 }
1851 }
1852}
1853
Mike Schuchardt2df08912020-12-15 16:28:09 -08001854void ValidationStateTracker::PostCallRecordSignalSemaphoreKHR(VkDevice device, const VkSemaphoreSignalInfo *pSignalInfo,
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001855 VkResult result) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001856 auto *semaphore_state = GetSemaphoreState(pSignalInfo->semaphore);
1857 semaphore_state->payload = pSignalInfo->value;
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001858}
1859
locke-lunargd556cc32019-09-17 01:21:23 -06001860void ValidationStateTracker::RecordMappedMemory(VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, void **ppData) {
1861 auto mem_info = GetDevMemState(mem);
1862 if (mem_info) {
1863 mem_info->mapped_range.offset = offset;
1864 mem_info->mapped_range.size = size;
1865 mem_info->p_driver_data = *ppData;
1866 }
1867}
1868
1869void ValidationStateTracker::RetireFence(VkFence fence) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001870 auto fence_state = GetFenceState(fence);
1871 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1872 if (fence_state->signaler.first != VK_NULL_HANDLE) {
locke-lunargd556cc32019-09-17 01:21:23 -06001873 // Fence signaller is a queue -- use this as proof that prior operations on that queue have completed.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001874 RetireWorkOnQueue(GetQueueState(fence_state->signaler.first), fence_state->signaler.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001875 } else {
1876 // Fence signaller is the WSI. We're not tracking what the WSI op actually /was/ in CV yet, but we need to mark
1877 // the fence as retired.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001878 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001879 }
1880 }
1881}
1882
1883void ValidationStateTracker::PostCallRecordWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
1884 VkBool32 waitAll, uint64_t timeout, VkResult result) {
1885 if (VK_SUCCESS != result) return;
1886
1887 // When we know that all fences are complete we can clean/remove their CBs
1888 if ((VK_TRUE == waitAll) || (1 == fenceCount)) {
1889 for (uint32_t i = 0; i < fenceCount; i++) {
1890 RetireFence(pFences[i]);
1891 }
1892 }
1893 // NOTE : Alternate case not handled here is when some fences have completed. In
1894 // this case for app to guarantee which fences completed it will have to call
1895 // vkGetFenceStatus() at which point we'll clean/remove their CBs if complete.
1896}
1897
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001898void ValidationStateTracker::RetireTimelineSemaphore(VkSemaphore semaphore, uint64_t until_payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001899 auto semaphore_state = GetSemaphoreState(semaphore);
1900 if (semaphore_state) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001901 for (auto &pair : queueMap) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001902 QUEUE_STATE &queue_state = pair.second;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001903 uint64_t max_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001904 for (const auto &submission : queue_state.submissions) {
1905 for (const auto &signal_semaphore : submission.signalSemaphores) {
1906 if (signal_semaphore.semaphore == semaphore && signal_semaphore.payload <= until_payload) {
1907 if (signal_semaphore.seq > max_seq) {
1908 max_seq = signal_semaphore.seq;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001909 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001910 }
1911 }
1912 }
Tony-LunarG47d5e272020-04-07 15:35:55 -06001913 if (max_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001914 RetireWorkOnQueue(&queue_state, max_seq);
Tony-LunarG47d5e272020-04-07 15:35:55 -06001915 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001916 }
1917 }
1918}
1919
John Zulauff89de662020-04-13 18:57:34 -06001920void ValidationStateTracker::RecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1921 VkResult result) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001922 if (VK_SUCCESS != result) return;
1923
1924 for (uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++) {
1925 RetireTimelineSemaphore(pWaitInfo->pSemaphores[i], pWaitInfo->pValues[i]);
1926 }
1927}
1928
John Zulauff89de662020-04-13 18:57:34 -06001929void ValidationStateTracker::PostCallRecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1930 VkResult result) {
1931 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1932}
1933
1934void ValidationStateTracker::PostCallRecordWaitSemaphoresKHR(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo,
1935 uint64_t timeout, VkResult result) {
1936 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1937}
1938
Adrian Coca Lorentec7d76102020-09-28 13:58:16 +02001939void ValidationStateTracker::RecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1940 VkResult result) {
1941 if (VK_SUCCESS != result) return;
1942
1943 RetireTimelineSemaphore(semaphore, *pValue);
1944}
1945
1946void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1947 VkResult result) {
1948 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1949}
1950void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1951 VkResult result) {
1952 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1953}
1954
locke-lunargd556cc32019-09-17 01:21:23 -06001955void ValidationStateTracker::PostCallRecordGetFenceStatus(VkDevice device, VkFence fence, VkResult result) {
1956 if (VK_SUCCESS != result) return;
1957 RetireFence(fence);
1958}
1959
1960void ValidationStateTracker::RecordGetDeviceQueueState(uint32_t queue_family_index, VkQueue queue) {
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06001961 queueMap.emplace(queue, QUEUE_STATE(queue, queue_family_index));
locke-lunargd556cc32019-09-17 01:21:23 -06001962}
1963
1964void ValidationStateTracker::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
1965 VkQueue *pQueue) {
1966 RecordGetDeviceQueueState(queueFamilyIndex, *pQueue);
1967}
1968
1969void ValidationStateTracker::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
1970 RecordGetDeviceQueueState(pQueueInfo->queueFamilyIndex, *pQueue);
1971}
1972
1973void ValidationStateTracker::PostCallRecordQueueWaitIdle(VkQueue queue, VkResult result) {
1974 if (VK_SUCCESS != result) return;
1975 QUEUE_STATE *queue_state = GetQueueState(queue);
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001976 RetireWorkOnQueue(queue_state, queue_state->seq + queue_state->submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001977}
1978
1979void ValidationStateTracker::PostCallRecordDeviceWaitIdle(VkDevice device, VkResult result) {
1980 if (VK_SUCCESS != result) return;
1981 for (auto &queue : queueMap) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001982 RetireWorkOnQueue(&queue.second, queue.second.seq + queue.second.submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001983 }
1984}
1985
1986void ValidationStateTracker::PreCallRecordDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
1987 if (!fence) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001988 auto fence_state = GetFenceState(fence);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001989 fence_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06001990 fenceMap.erase(fence);
1991}
1992
1993void ValidationStateTracker::PreCallRecordDestroySemaphore(VkDevice device, VkSemaphore semaphore,
1994 const VkAllocationCallbacks *pAllocator) {
1995 if (!semaphore) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001996 auto semaphore_state = GetSemaphoreState(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001997 semaphore_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06001998 semaphoreMap.erase(semaphore);
1999}
2000
2001void ValidationStateTracker::PreCallRecordDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
2002 if (!event) return;
John Zulauf48057322020-12-02 11:59:31 -07002003 EVENT_STATE *event_state = Get<EVENT_STATE>(event);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002004 event_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002005 eventMap.erase(event);
2006}
2007
2008void ValidationStateTracker::PreCallRecordDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
2009 const VkAllocationCallbacks *pAllocator) {
2010 if (!queryPool) return;
2011 QUERY_POOL_STATE *qp_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002012 qp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002013 queryPoolMap.erase(queryPool);
2014}
2015
locke-lunargd556cc32019-09-17 01:21:23 -06002016void ValidationStateTracker::UpdateBindBufferMemoryState(VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memoryOffset) {
2017 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2018 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002019 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002020 auto mem_state = GetDevMemShared(mem);
2021 if (mem_state) {
2022 buffer_state->SetMemBinding(mem_state, memoryOffset);
2023 }
locke-lunargd556cc32019-09-17 01:21:23 -06002024 }
2025}
2026
2027void ValidationStateTracker::PostCallRecordBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
2028 VkDeviceSize memoryOffset, VkResult result) {
2029 if (VK_SUCCESS != result) return;
2030 UpdateBindBufferMemoryState(buffer, mem, memoryOffset);
2031}
2032
2033void ValidationStateTracker::PostCallRecordBindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002034 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002035 for (uint32_t i = 0; i < bindInfoCount; i++) {
2036 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2037 }
2038}
2039
2040void ValidationStateTracker::PostCallRecordBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002041 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002042 for (uint32_t i = 0; i < bindInfoCount; i++) {
2043 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2044 }
2045}
2046
Spencer Fricke6c127102020-04-16 06:25:20 -07002047void ValidationStateTracker::RecordGetBufferMemoryRequirementsState(VkBuffer buffer) {
locke-lunargd556cc32019-09-17 01:21:23 -06002048 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2049 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002050 buffer_state->memory_requirements_checked = true;
2051 }
2052}
2053
2054void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
2055 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002056 RecordGetBufferMemoryRequirementsState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002057}
2058
2059void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002060 const VkBufferMemoryRequirementsInfo2 *pInfo,
2061 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002062 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002063}
2064
2065void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2KHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002066 const VkBufferMemoryRequirementsInfo2 *pInfo,
2067 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002068 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002069}
2070
Spencer Fricke6c127102020-04-16 06:25:20 -07002071void ValidationStateTracker::RecordGetImageMemoryRequirementsState(VkImage image, const VkImageMemoryRequirementsInfo2 *pInfo) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002072 const VkImagePlaneMemoryRequirementsInfo *plane_info =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002073 (pInfo == nullptr) ? nullptr : LvlFindInChain<VkImagePlaneMemoryRequirementsInfo>(pInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06002074 IMAGE_STATE *image_state = GetImageState(image);
2075 if (image_state) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002076 if (plane_info != nullptr) {
2077 // Multi-plane image
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002078 if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_0_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002079 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002080 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_1_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002081 image_state->memory_requirements_checked[1] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002082 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_2_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002083 image_state->memory_requirements_checked[2] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002084 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002085 } else if (!image_state->disjoint) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002086 // Single Plane image
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002087 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002088 }
locke-lunargd556cc32019-09-17 01:21:23 -06002089 }
2090}
2091
2092void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements(VkDevice device, VkImage image,
2093 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002094 RecordGetImageMemoryRequirementsState(image, nullptr);
locke-lunargd556cc32019-09-17 01:21:23 -06002095}
2096
2097void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo,
2098 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002099 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002100}
2101
2102void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2KHR(VkDevice device,
2103 const VkImageMemoryRequirementsInfo2 *pInfo,
2104 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002105 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002106}
2107
2108static void RecordGetImageSparseMemoryRequirementsState(IMAGE_STATE *image_state,
2109 VkSparseImageMemoryRequirements *sparse_image_memory_requirements) {
2110 image_state->sparse_requirements.emplace_back(*sparse_image_memory_requirements);
2111 if (sparse_image_memory_requirements->formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) {
2112 image_state->sparse_metadata_required = true;
2113 }
2114}
2115
2116void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements(
2117 VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
2118 VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
2119 auto image_state = GetImageState(image);
2120 image_state->get_sparse_reqs_called = true;
2121 if (!pSparseMemoryRequirements) return;
2122 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2123 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i]);
2124 }
2125}
2126
2127void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002128 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2129 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002130 auto image_state = GetImageState(pInfo->image);
2131 image_state->get_sparse_reqs_called = true;
2132 if (!pSparseMemoryRequirements) return;
2133 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2134 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2135 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2136 }
2137}
2138
2139void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002140 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2141 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002142 auto image_state = GetImageState(pInfo->image);
2143 image_state->get_sparse_reqs_called = true;
2144 if (!pSparseMemoryRequirements) return;
2145 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2146 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2147 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2148 }
2149}
2150
2151void ValidationStateTracker::PreCallRecordDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
2152 const VkAllocationCallbacks *pAllocator) {
2153 if (!shaderModule) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002154 auto shader_module_state = GetShaderModuleState(shaderModule);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002155 shader_module_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002156 shaderModuleMap.erase(shaderModule);
2157}
2158
2159void ValidationStateTracker::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline,
2160 const VkAllocationCallbacks *pAllocator) {
2161 if (!pipeline) return;
2162 PIPELINE_STATE *pipeline_state = GetPipelineState(pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06002163 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002164 pipeline_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002165 pipelineMap.erase(pipeline);
2166}
2167
2168void ValidationStateTracker::PreCallRecordDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
2169 const VkAllocationCallbacks *pAllocator) {
2170 if (!pipelineLayout) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002171 auto pipeline_layout_state = GetPipelineLayout(pipelineLayout);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002172 pipeline_layout_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002173 pipelineLayoutMap.erase(pipelineLayout);
2174}
2175
2176void ValidationStateTracker::PreCallRecordDestroySampler(VkDevice device, VkSampler sampler,
2177 const VkAllocationCallbacks *pAllocator) {
2178 if (!sampler) return;
2179 SAMPLER_STATE *sampler_state = GetSamplerState(sampler);
locke-lunargd556cc32019-09-17 01:21:23 -06002180 // Any bound cmd buffers are now invalid
2181 if (sampler_state) {
Yuly Novikov424cdd52020-05-26 16:45:12 -04002182 if (sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2183 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
2184 custom_border_color_sampler_count--;
2185 }
2186
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002187 sampler_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002188 }
2189 samplerMap.erase(sampler);
2190}
2191
2192void ValidationStateTracker::PreCallRecordDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
2193 const VkAllocationCallbacks *pAllocator) {
2194 if (!descriptorSetLayout) return;
2195 auto layout_it = descriptorSetLayoutMap.find(descriptorSetLayout);
2196 if (layout_it != descriptorSetLayoutMap.end()) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002197 layout_it->second.get()->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002198 descriptorSetLayoutMap.erase(layout_it);
2199 }
2200}
2201
2202void ValidationStateTracker::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2203 const VkAllocationCallbacks *pAllocator) {
2204 if (!descriptorPool) return;
2205 DESCRIPTOR_POOL_STATE *desc_pool_state = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002206 if (desc_pool_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002207 // Free sets that were in this pool
John Zulauf79f06582021-02-27 18:38:39 -07002208 for (auto *ds : desc_pool_state->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002209 FreeDescriptorSet(ds);
2210 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002211 desc_pool_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002212 descriptorPoolMap.erase(descriptorPool);
2213 }
2214}
2215
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002216// 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 -06002217void ValidationStateTracker::FreeCommandBufferStates(COMMAND_POOL_STATE *pool_state, const uint32_t command_buffer_count,
2218 const VkCommandBuffer *command_buffers) {
2219 for (uint32_t i = 0; i < command_buffer_count; i++) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002220 auto cb_state = Get<CMD_BUFFER_STATE>(command_buffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002221 // Remove references to command buffer's state and delete
2222 if (cb_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002223 cb_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002224 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002225 // Remove CBState from CB map
2226 pool_state->commandBuffers.erase(command_buffers[i]);
2227 commandBufferMap.erase(command_buffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002228 }
2229}
2230
2231void ValidationStateTracker::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
2232 uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002233 auto pool = GetCommandPoolState(commandPool);
2234 FreeCommandBufferStates(pool, commandBufferCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06002235}
2236
2237void ValidationStateTracker::PostCallRecordCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
2238 const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool,
2239 VkResult result) {
2240 if (VK_SUCCESS != result) return;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06002241 auto queue_flags = GetPhysicalDeviceState()->queue_family_properties[pCreateInfo->queueFamilyIndex].queueFlags;
2242 commandPoolMap[*pCommandPool] = std::make_shared<COMMAND_POOL_STATE>(*pCommandPool, pCreateInfo, queue_flags);
locke-lunargd556cc32019-09-17 01:21:23 -06002243}
2244
2245void ValidationStateTracker::PostCallRecordCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
2246 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool,
2247 VkResult result) {
2248 if (VK_SUCCESS != result) return;
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002249
2250 uint32_t index_count = 0, n_perf_pass = 0;
2251 bool has_cb = false, has_rb = false;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002252 if (pCreateInfo->queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002253 const auto *perf = LvlFindInChain<VkQueryPoolPerformanceCreateInfoKHR>(pCreateInfo->pNext);
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002254 index_count = perf->counterIndexCount;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002255
Mark Lobodzinski7e948e42020-09-09 10:23:36 -06002256 const QUEUE_FAMILY_PERF_COUNTERS &counters = *physical_device_state->perf_counters[perf->queueFamilyIndex];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002257 for (uint32_t i = 0; i < perf->counterIndexCount; i++) {
2258 const auto &counter = counters.counters[perf->pCounterIndices[i]];
2259 switch (counter.scope) {
2260 case VK_QUERY_SCOPE_COMMAND_BUFFER_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002261 has_cb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002262 break;
2263 case VK_QUERY_SCOPE_RENDER_PASS_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002264 has_rb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002265 break;
2266 default:
2267 break;
2268 }
2269 }
2270
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002271 DispatchGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physical_device_state->phys_device, perf, &n_perf_pass);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002272 }
2273
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002274 queryPoolMap[*pQueryPool] =
2275 std::make_shared<QUERY_POOL_STATE>(*pQueryPool, pCreateInfo, index_count, n_perf_pass, has_cb, has_rb);
locke-lunargd556cc32019-09-17 01:21:23 -06002276
2277 QueryObject query_obj{*pQueryPool, 0u};
2278 for (uint32_t i = 0; i < pCreateInfo->queryCount; ++i) {
2279 query_obj.query = i;
2280 queryToStateMap[query_obj] = QUERYSTATE_UNKNOWN;
2281 }
2282}
2283
2284void ValidationStateTracker::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
2285 const VkAllocationCallbacks *pAllocator) {
2286 if (!commandPool) return;
2287 COMMAND_POOL_STATE *cp_state = GetCommandPoolState(commandPool);
2288 // Remove cmdpool from cmdpoolmap, after freeing layer data for the command buffers
2289 // "When a pool is destroyed, all command buffers allocated from the pool are freed."
2290 if (cp_state) {
2291 // Create a vector, as FreeCommandBufferStates deletes from cp_state->commandBuffers during iteration.
2292 std::vector<VkCommandBuffer> cb_vec{cp_state->commandBuffers.begin(), cp_state->commandBuffers.end()};
2293 FreeCommandBufferStates(cp_state, static_cast<uint32_t>(cb_vec.size()), cb_vec.data());
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002294 cp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002295 commandPoolMap.erase(commandPool);
2296 }
2297}
2298
2299void ValidationStateTracker::PostCallRecordResetCommandPool(VkDevice device, VkCommandPool commandPool,
2300 VkCommandPoolResetFlags flags, VkResult result) {
2301 if (VK_SUCCESS != result) return;
2302 // Reset all of the CBs allocated from this pool
2303 auto command_pool_state = GetCommandPoolState(commandPool);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002304 for (auto cmd_buffer : command_pool_state->commandBuffers) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002305 auto cb_state = Get<CMD_BUFFER_STATE>(cmd_buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002306 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002307 }
2308}
2309
2310void ValidationStateTracker::PostCallRecordResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
2311 VkResult result) {
2312 for (uint32_t i = 0; i < fenceCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002313 auto fence_state = GetFenceState(pFences[i]);
2314 if (fence_state) {
2315 if (fence_state->scope == kSyncScopeInternal) {
2316 fence_state->state = FENCE_UNSIGNALED;
2317 } else if (fence_state->scope == kSyncScopeExternalTemporary) {
2318 fence_state->scope = kSyncScopeInternal;
locke-lunargd556cc32019-09-17 01:21:23 -06002319 }
2320 }
2321 }
2322}
2323
locke-lunargd556cc32019-09-17 01:21:23 -06002324void ValidationStateTracker::PreCallRecordDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
2325 const VkAllocationCallbacks *pAllocator) {
2326 if (!framebuffer) return;
2327 FRAMEBUFFER_STATE *framebuffer_state = GetFramebufferState(framebuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002328 framebuffer_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002329 frameBufferMap.erase(framebuffer);
2330}
2331
2332void ValidationStateTracker::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
2333 const VkAllocationCallbacks *pAllocator) {
2334 if (!renderPass) return;
2335 RENDER_PASS_STATE *rp_state = GetRenderPassState(renderPass);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002336 rp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002337 renderPassMap.erase(renderPass);
2338}
2339
2340void ValidationStateTracker::PostCallRecordCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
2341 const VkAllocationCallbacks *pAllocator, VkFence *pFence, VkResult result) {
2342 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002343 fenceMap[*pFence] = std::make_shared<FENCE_STATE>(*pFence, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002344}
2345
2346bool ValidationStateTracker::PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2347 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2348 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002349 void *cgpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002350 // Set up the state that CoreChecks, gpu_validation and later StateTracker Record will use.
2351 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2352 cgpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2353 cgpl_state->pipe_state.reserve(count);
2354 for (uint32_t i = 0; i < count; i++) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002355 cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
Jeff Bolz6ae39612019-10-11 20:57:36 -05002356 (cgpl_state->pipe_state)[i]->initGraphicsPipeline(this, &pCreateInfos[i], GetRenderPassShared(pCreateInfos[i].renderPass));
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002357 (cgpl_state->pipe_state)[i]->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002358 }
2359 return false;
2360}
2361
2362void ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2363 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2364 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2365 VkResult result, void *cgpl_state_data) {
2366 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2367 // This API may create pipelines regardless of the return value
2368 for (uint32_t i = 0; i < count; i++) {
2369 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002370 (cgpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002371 pipelineMap[pPipelines[i]] = std::move((cgpl_state->pipe_state)[i]);
2372 }
2373 }
2374 cgpl_state->pipe_state.clear();
2375}
2376
2377bool ValidationStateTracker::PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2378 const VkComputePipelineCreateInfo *pCreateInfos,
2379 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002380 void *ccpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002381 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2382 ccpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2383 ccpl_state->pipe_state.reserve(count);
2384 for (uint32_t i = 0; i < count; i++) {
2385 // Create and initialize internal tracking data structure
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002386 ccpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
locke-lunargd556cc32019-09-17 01:21:23 -06002387 ccpl_state->pipe_state.back()->initComputePipeline(this, &pCreateInfos[i]);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002388 ccpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002389 }
2390 return false;
2391}
2392
2393void ValidationStateTracker::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2394 const VkComputePipelineCreateInfo *pCreateInfos,
2395 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2396 VkResult result, void *ccpl_state_data) {
2397 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2398
2399 // This API may create pipelines regardless of the return value
2400 for (uint32_t i = 0; i < count; i++) {
2401 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002402 (ccpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002403 pipelineMap[pPipelines[i]] = std::move((ccpl_state->pipe_state)[i]);
2404 }
2405 }
2406 ccpl_state->pipe_state.clear();
2407}
2408
2409bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache,
2410 uint32_t count,
2411 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2412 const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002413 VkPipeline *pPipelines, void *crtpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002414 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2415 crtpl_state->pipe_state.reserve(count);
2416 for (uint32_t i = 0; i < count; i++) {
2417 // Create and initialize internal tracking data structure
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002418 crtpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002419 crtpl_state->pipe_state.back()->initRayTracingPipeline(this, &pCreateInfos[i]);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002420 crtpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002421 }
2422 return false;
2423}
2424
2425void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(
2426 VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2427 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines, VkResult result, void *crtpl_state_data) {
2428 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2429 // This API may create pipelines regardless of the return value
2430 for (uint32_t i = 0; i < count; i++) {
2431 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002432 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002433 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2434 }
2435 }
2436 crtpl_state->pipe_state.clear();
2437}
2438
sourav parmarcd5fb182020-07-17 12:58:44 -07002439bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2440 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002441 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2442 const VkAllocationCallbacks *pAllocator,
2443 VkPipeline *pPipelines, void *crtpl_state_data) const {
2444 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2445 crtpl_state->pipe_state.reserve(count);
2446 for (uint32_t i = 0; i < count; i++) {
2447 // Create and initialize internal tracking data structure
2448 crtpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
2449 crtpl_state->pipe_state.back()->initRayTracingPipeline(this, &pCreateInfos[i]);
2450 crtpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
2451 }
2452 return false;
2453}
2454
sourav parmarcd5fb182020-07-17 12:58:44 -07002455void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2456 VkPipelineCache pipelineCache, uint32_t count,
2457 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2458 const VkAllocationCallbacks *pAllocator,
2459 VkPipeline *pPipelines, VkResult result,
2460 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002461 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2462 // This API may create pipelines regardless of the return value
2463 for (uint32_t i = 0; i < count; i++) {
2464 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002465 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002466 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2467 }
2468 }
2469 crtpl_state->pipe_state.clear();
2470}
2471
locke-lunargd556cc32019-09-17 01:21:23 -06002472void ValidationStateTracker::PostCallRecordCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
2473 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler,
2474 VkResult result) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002475 samplerMap[*pSampler] = std::make_shared<SAMPLER_STATE>(pSampler, pCreateInfo);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002476 if (pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2477 pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
Tony-LunarG7337b312020-04-15 16:40:25 -06002478 custom_border_color_sampler_count++;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002479 }
locke-lunargd556cc32019-09-17 01:21:23 -06002480}
2481
2482void ValidationStateTracker::PostCallRecordCreateDescriptorSetLayout(VkDevice device,
2483 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
2484 const VkAllocationCallbacks *pAllocator,
2485 VkDescriptorSetLayout *pSetLayout, VkResult result) {
2486 if (VK_SUCCESS != result) return;
2487 descriptorSetLayoutMap[*pSetLayout] = std::make_shared<cvdescriptorset::DescriptorSetLayout>(pCreateInfo, *pSetLayout);
2488}
2489
locke-lunargd556cc32019-09-17 01:21:23 -06002490void ValidationStateTracker::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
2491 const VkAllocationCallbacks *pAllocator,
2492 VkPipelineLayout *pPipelineLayout, VkResult result) {
2493 if (VK_SUCCESS != result) return;
2494
Jeremy Gebbene6e45542021-08-05 16:39:49 -06002495 pipelineLayoutMap[*pPipelineLayout] = std::make_shared<PIPELINE_LAYOUT_STATE>(this, *pPipelineLayout, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002496}
2497
2498void ValidationStateTracker::PostCallRecordCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
2499 const VkAllocationCallbacks *pAllocator,
2500 VkDescriptorPool *pDescriptorPool, VkResult result) {
2501 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002502 descriptorPoolMap[*pDescriptorPool] = std::make_shared<DESCRIPTOR_POOL_STATE>(*pDescriptorPool, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002503}
2504
2505void ValidationStateTracker::PostCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2506 VkDescriptorPoolResetFlags flags, VkResult result) {
2507 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002508 DESCRIPTOR_POOL_STATE *pool = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002509 // TODO: validate flags
2510 // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
John Zulauf79f06582021-02-27 18:38:39 -07002511 for (auto *ds : pool->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002512 FreeDescriptorSet(ds);
2513 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002514 pool->sets.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06002515 // Reset available count for each type and available sets for this pool
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002516 for (auto it = pool->availableDescriptorTypeCount.begin(); it != pool->availableDescriptorTypeCount.end(); ++it) {
2517 pool->availableDescriptorTypeCount[it->first] = pool->maxDescriptorTypeCount[it->first];
locke-lunargd556cc32019-09-17 01:21:23 -06002518 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002519 pool->availableSets = pool->maxSets;
locke-lunargd556cc32019-09-17 01:21:23 -06002520}
2521
2522bool ValidationStateTracker::PreCallValidateAllocateDescriptorSets(VkDevice device,
2523 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002524 VkDescriptorSet *pDescriptorSets, void *ads_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002525 // Always update common data
2526 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2527 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2528 UpdateAllocateDescriptorSetsData(pAllocateInfo, ads_state);
2529
2530 return false;
2531}
2532
2533// Allocation state was good and call down chain was made so update state based on allocating descriptor sets
2534void ValidationStateTracker::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
2535 VkDescriptorSet *pDescriptorSets, VkResult result,
2536 void *ads_state_data) {
2537 if (VK_SUCCESS != result) return;
2538 // All the updates are contained in a single cvdescriptorset function
2539 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2540 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2541 PerformAllocateDescriptorSets(pAllocateInfo, pDescriptorSets, ads_state);
2542}
2543
2544void ValidationStateTracker::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count,
2545 const VkDescriptorSet *pDescriptorSets) {
2546 DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(descriptorPool);
2547 // Update available descriptor sets in pool
2548 pool_state->availableSets += count;
2549
2550 // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
2551 for (uint32_t i = 0; i < count; ++i) {
2552 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
2553 auto descriptor_set = setMap[pDescriptorSets[i]].get();
2554 uint32_t type_index = 0, descriptor_count = 0;
2555 for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) {
2556 type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j));
2557 descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j);
2558 pool_state->availableDescriptorTypeCount[type_index] += descriptor_count;
2559 }
2560 FreeDescriptorSet(descriptor_set);
2561 pool_state->sets.erase(descriptor_set);
2562 }
2563 }
2564}
2565
2566void ValidationStateTracker::PreCallRecordUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
2567 const VkWriteDescriptorSet *pDescriptorWrites,
2568 uint32_t descriptorCopyCount,
2569 const VkCopyDescriptorSet *pDescriptorCopies) {
2570 cvdescriptorset::PerformUpdateDescriptorSets(this, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
2571 pDescriptorCopies);
2572}
2573
2574void ValidationStateTracker::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo,
2575 VkCommandBuffer *pCommandBuffer, VkResult result) {
2576 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002577 auto pool = GetCommandPoolShared(pCreateInfo->commandPool);
2578 if (pool) {
locke-lunargd556cc32019-09-17 01:21:23 -06002579 for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) {
2580 // Add command buffer to its commandPool map
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002581 pool->commandBuffers.insert(pCommandBuffer[i]);
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002582 commandBufferMap[pCommandBuffer[i]] = CreateCmdBufferState(pCommandBuffer[i], pCreateInfo, pool);
locke-lunargfc78e932020-11-19 17:06:24 -07002583 }
2584 }
2585}
2586
locke-lunargd556cc32019-09-17 01:21:23 -06002587void ValidationStateTracker::PreCallRecordBeginCommandBuffer(VkCommandBuffer commandBuffer,
2588 const VkCommandBufferBeginInfo *pBeginInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002589 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002590 if (!cb_state) return;
locke-lunargfc78e932020-11-19 17:06:24 -07002591
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002592 cb_state->Begin(pBeginInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002593}
2594
2595void ValidationStateTracker::PostCallRecordEndCommandBuffer(VkCommandBuffer commandBuffer, VkResult result) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002596 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002597 if (!cb_state) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002598
2599 cb_state->End(result);
locke-lunargd556cc32019-09-17 01:21:23 -06002600}
2601
2602void ValidationStateTracker::PostCallRecordResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags,
2603 VkResult result) {
2604 if (VK_SUCCESS == result) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002605 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002606 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002607 }
2608}
2609
2610CBStatusFlags MakeStaticStateMask(VkPipelineDynamicStateCreateInfo const *ds) {
2611 // initially assume everything is static state
2612 CBStatusFlags flags = CBSTATUS_ALL_STATE_SET;
2613
2614 if (ds) {
2615 for (uint32_t i = 0; i < ds->dynamicStateCount; i++) {
locke-lunarg4189aa22020-10-21 00:23:48 -06002616 flags &= ~ConvertToCBStatusFlagBits(ds->pDynamicStates[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002617 }
2618 }
locke-lunargd556cc32019-09-17 01:21:23 -06002619 return flags;
2620}
2621
2622// Validation cache:
2623// CV is the bottommost implementor of this extension. Don't pass calls down.
2624// utility function to set collective state for pipeline
2625void SetPipelineState(PIPELINE_STATE *pPipe) {
2626 // If any attachment used by this pipeline has blendEnable, set top-level blendEnable
2627 if (pPipe->graphicsPipelineCI.pColorBlendState) {
2628 for (size_t i = 0; i < pPipe->attachments.size(); ++i) {
2629 if (VK_TRUE == pPipe->attachments[i].blendEnable) {
2630 if (((pPipe->attachments[i].dstAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2631 (pPipe->attachments[i].dstAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2632 ((pPipe->attachments[i].dstColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2633 (pPipe->attachments[i].dstColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2634 ((pPipe->attachments[i].srcAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2635 (pPipe->attachments[i].srcAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2636 ((pPipe->attachments[i].srcColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2637 (pPipe->attachments[i].srcColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA))) {
2638 pPipe->blendConstantsEnabled = true;
2639 }
2640 }
2641 }
2642 }
sfricke-samsung8f658d42020-05-03 20:12:24 -07002643 // Check if sample location is enabled
2644 if (pPipe->graphicsPipelineCI.pMultisampleState) {
2645 const VkPipelineSampleLocationsStateCreateInfoEXT *sample_location_state =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002646 LvlFindInChain<VkPipelineSampleLocationsStateCreateInfoEXT>(pPipe->graphicsPipelineCI.pMultisampleState->pNext);
sfricke-samsung8f658d42020-05-03 20:12:24 -07002647 if (sample_location_state != nullptr) {
2648 pPipe->sample_location_enabled = sample_location_state->sampleLocationsEnable;
2649 }
2650 }
locke-lunargd556cc32019-09-17 01:21:23 -06002651}
2652
2653void ValidationStateTracker::PreCallRecordCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
2654 VkPipeline pipeline) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002655 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002656 assert(cb_state);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002657 cb_state->RecordCmd(CMD_BINDPIPELINE);
locke-lunargd556cc32019-09-17 01:21:23 -06002658
2659 auto pipe_state = GetPipelineState(pipeline);
2660 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002661 bool rasterization_enabled = VK_FALSE == pipe_state->graphicsPipelineCI.ptr()->pRasterizationState->rasterizerDiscardEnable;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002662 const auto* viewport_state = pipe_state->graphicsPipelineCI.ptr()->pViewportState;
2663 const auto* dynamic_state = pipe_state->graphicsPipelineCI.ptr()->pDynamicState;
locke-lunargd556cc32019-09-17 01:21:23 -06002664 cb_state->status &= ~cb_state->static_status;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002665 cb_state->static_status = MakeStaticStateMask(dynamic_state);
locke-lunargd556cc32019-09-17 01:21:23 -06002666 cb_state->status |= cb_state->static_status;
locke-lunarg4189aa22020-10-21 00:23:48 -06002667 cb_state->dynamic_status = CBSTATUS_ALL_STATE_SET & (~cb_state->static_status);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002668
2669 // Used to calculate CMD_BUFFER_STATE::usedViewportScissorCount upon draw command with this graphics pipeline.
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002670 // If rasterization disabled (no viewport/scissors used), or the actual number of viewports/scissors is dynamic (unknown at
2671 // this time), then these are set to 0 to disable this checking.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002672 auto has_dynamic_viewport_count = cb_state->dynamic_status & CBSTATUS_VIEWPORT_WITH_COUNT_SET;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002673 auto has_dynamic_scissor_count = cb_state->dynamic_status & CBSTATUS_SCISSOR_WITH_COUNT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002674 cb_state->pipelineStaticViewportCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002675 has_dynamic_viewport_count || !rasterization_enabled ? 0 : viewport_state->viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002676 cb_state->pipelineStaticScissorCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002677 has_dynamic_scissor_count || !rasterization_enabled ? 0 : viewport_state->scissorCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002678
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002679 // Trash dynamic viewport/scissor state if pipeline defines static state and enabled rasterization.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002680 // akeley98 NOTE: There's a bit of an ambiguity in the spec, whether binding such a pipeline overwrites
2681 // the entire viewport (scissor) array, or only the subsection defined by the viewport (scissor) count.
2682 // I am taking the latter interpretation based on the implementation details of NVIDIA's Vulkan driver.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002683 if (!has_dynamic_viewport_count) {
2684 cb_state->trashedViewportCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002685 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_VIEWPORT_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002686 cb_state->trashedViewportMask |= (uint32_t(1) << viewport_state->viewportCount) - 1u;
2687 // should become = ~uint32_t(0) if the other interpretation is correct.
2688 }
2689 }
2690 if (!has_dynamic_scissor_count) {
2691 cb_state->trashedScissorCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002692 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_SCISSOR_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002693 cb_state->trashedScissorMask |= (uint32_t(1) << viewport_state->scissorCount) - 1u;
2694 // should become = ~uint32_t(0) if the other interpretation is correct.
2695 }
2696 }
locke-lunargd556cc32019-09-17 01:21:23 -06002697 }
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002698 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
2699 cb_state->lastBound[lv_bind_point].pipeline_state = pipe_state;
locke-lunargd556cc32019-09-17 01:21:23 -06002700 SetPipelineState(pipe_state);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002701 if (!disabled[command_buffer_state]) {
2702 cb_state->AddChild(pipe_state);
2703 }
locke-lunargb8be8222020-10-20 00:34:37 -06002704 for (auto &slot : pipe_state->active_slots) {
2705 for (auto &req : slot.second) {
2706 for (auto &sampler : req.second.samplers_used_by_image) {
2707 for (auto &des : sampler) {
2708 des.second = nullptr;
2709 }
2710 }
2711 }
2712 }
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06002713 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
locke-lunargd556cc32019-09-17 01:21:23 -06002714}
2715
2716void ValidationStateTracker::PreCallRecordCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2717 uint32_t viewportCount, const VkViewport *pViewports) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002718 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002719 cb_state->RecordStateCmd(CMD_SETVIEWPORT, CBSTATUS_VIEWPORT_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002720 uint32_t bits = ((1u << viewportCount) - 1u) << firstViewport;
2721 cb_state->viewportMask |= bits;
2722 cb_state->trashedViewportMask &= ~bits;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002723
2724 cb_state->dynamicViewports.resize(std::max(size_t(firstViewport + viewportCount), cb_state->dynamicViewports.size()));
2725 for (size_t i = 0; i < viewportCount; ++i) {
2726 cb_state->dynamicViewports[firstViewport + i] = pViewports[i];
2727 }
locke-lunargd556cc32019-09-17 01:21:23 -06002728}
2729
2730void ValidationStateTracker::PreCallRecordCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
2731 uint32_t exclusiveScissorCount,
2732 const VkRect2D *pExclusiveScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002733 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002734 cb_state->RecordStateCmd(CMD_SETEXCLUSIVESCISSORNV, CBSTATUS_EXCLUSIVE_SCISSOR_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002735 // TODO: We don't have VUIDs for validating that all exclusive scissors have been set.
2736 // cb_state->exclusiveScissorMask |= ((1u << exclusiveScissorCount) - 1u) << firstExclusiveScissor;
locke-lunargd556cc32019-09-17 01:21:23 -06002737}
2738
2739void ValidationStateTracker::PreCallRecordCmdBindShadingRateImageNV(VkCommandBuffer commandBuffer, VkImageView imageView,
2740 VkImageLayout imageLayout) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002741 if (disabled[command_buffer_state]) return;
2742
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002743 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002744 cb_state->RecordCmd(CMD_BINDSHADINGRATEIMAGENV);
locke-lunargd556cc32019-09-17 01:21:23 -06002745
2746 if (imageView != VK_NULL_HANDLE) {
2747 auto view_state = GetImageViewState(imageView);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002748 cb_state->AddChild(view_state);
locke-lunargd556cc32019-09-17 01:21:23 -06002749 }
2750}
2751
2752void ValidationStateTracker::PreCallRecordCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2753 uint32_t viewportCount,
2754 const VkShadingRatePaletteNV *pShadingRatePalettes) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002755 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002756 cb_state->RecordStateCmd(CMD_SETVIEWPORTSHADINGRATEPALETTENV, CBSTATUS_SHADING_RATE_PALETTE_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002757 // TODO: We don't have VUIDs for validating that all shading rate palettes have been set.
2758 // cb_state->shadingRatePaletteMask |= ((1u << viewportCount) - 1u) << firstViewport;
locke-lunargd556cc32019-09-17 01:21:23 -06002759}
2760
2761void ValidationStateTracker::PostCallRecordCreateAccelerationStructureNV(VkDevice device,
2762 const VkAccelerationStructureCreateInfoNV *pCreateInfo,
2763 const VkAllocationCallbacks *pAllocator,
2764 VkAccelerationStructureNV *pAccelerationStructure,
2765 VkResult result) {
2766 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002767 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE>(*pAccelerationStructure, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002768
2769 // Query the requirements in case the application doesn't (to avoid bind/validation time query)
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002770 auto as_memory_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002771 as_memory_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002772 as_memory_requirements_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002773 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &as_memory_requirements_info, &as_state->memory_requirements);
2774
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002775 auto scratch_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002776 scratch_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002777 scratch_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002778 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &scratch_memory_req_info,
2779 &as_state->build_scratch_memory_requirements);
2780
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002781 auto update_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002782 update_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002783 update_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002784 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &update_memory_req_info,
2785 &as_state->update_scratch_memory_requirements);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002786 as_state->allocator = pAllocator;
locke-lunargd556cc32019-09-17 01:21:23 -06002787 accelerationStructureMap[*pAccelerationStructure] = std::move(as_state);
2788}
2789
Jeff Bolz95176d02020-04-01 00:36:16 -05002790void ValidationStateTracker::PostCallRecordCreateAccelerationStructureKHR(VkDevice device,
2791 const VkAccelerationStructureCreateInfoKHR *pCreateInfo,
2792 const VkAllocationCallbacks *pAllocator,
2793 VkAccelerationStructureKHR *pAccelerationStructure,
2794 VkResult result) {
2795 if (VK_SUCCESS != result) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07002796 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE_KHR>(*pAccelerationStructure, pCreateInfo);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002797 as_state->allocator = pAllocator;
sourav parmarcd5fb182020-07-17 12:58:44 -07002798 accelerationStructureMap_khr[*pAccelerationStructure] = std::move(as_state);
Jeff Bolz95176d02020-04-01 00:36:16 -05002799}
2800
sourav parmarcd5fb182020-07-17 12:58:44 -07002801void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresKHR(
2802 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2803 const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002804 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmarcd5fb182020-07-17 12:58:44 -07002805 if (cb_state == nullptr) {
2806 return;
2807 }
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002808 cb_state->RecordCmd(CMD_BUILDACCELERATIONSTRUCTURESKHR);
sourav parmarcd5fb182020-07-17 12:58:44 -07002809 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002810 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002811 if (dst_as_state != nullptr) {
2812 dst_as_state->built = true;
2813 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002814 if (!disabled[command_buffer_state]) {
2815 cb_state->AddChild(dst_as_state);
2816 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002817 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002818 if (!disabled[command_buffer_state]) {
2819 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2820 if (src_as_state != nullptr) {
2821 cb_state->AddChild(src_as_state);
2822 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002823 }
2824 }
2825 cb_state->hasBuildAccelerationStructureCmd = true;
2826}
2827
2828void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresIndirectKHR(
2829 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2830 const VkDeviceAddress *pIndirectDeviceAddresses, const uint32_t *pIndirectStrides,
2831 const uint32_t *const *ppMaxPrimitiveCounts) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002832 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmarcd5fb182020-07-17 12:58:44 -07002833 if (cb_state == nullptr) {
2834 return;
2835 }
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002836 cb_state->RecordCmd(CMD_BUILDACCELERATIONSTRUCTURESINDIRECTKHR);
sourav parmarcd5fb182020-07-17 12:58:44 -07002837 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002838 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002839 if (dst_as_state != nullptr) {
2840 dst_as_state->built = true;
2841 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002842 if (!disabled[command_buffer_state]) {
2843 cb_state->AddChild(dst_as_state);
2844 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002845 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002846 if (!disabled[command_buffer_state]) {
2847 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2848 if (src_as_state != nullptr) {
2849 cb_state->AddChild(src_as_state);
2850 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002851 }
2852 }
2853 cb_state->hasBuildAccelerationStructureCmd = true;
2854}
locke-lunargd556cc32019-09-17 01:21:23 -06002855void ValidationStateTracker::PostCallRecordGetAccelerationStructureMemoryRequirementsNV(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002856 VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV *pInfo, VkMemoryRequirements2 *pMemoryRequirements) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002857 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(pInfo->accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002858 if (as_state != nullptr) {
2859 if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV) {
2860 as_state->memory_requirements = *pMemoryRequirements;
2861 as_state->memory_requirements_checked = true;
2862 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV) {
2863 as_state->build_scratch_memory_requirements = *pMemoryRequirements;
2864 as_state->build_scratch_memory_requirements_checked = true;
2865 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV) {
2866 as_state->update_scratch_memory_requirements = *pMemoryRequirements;
2867 as_state->update_scratch_memory_requirements_checked = true;
2868 }
2869 }
2870}
2871
sourav parmarcd5fb182020-07-17 12:58:44 -07002872void ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(
2873 VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002874 if (VK_SUCCESS != result) return;
2875 for (uint32_t i = 0; i < bindInfoCount; i++) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002876 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
locke-lunargd556cc32019-09-17 01:21:23 -06002877
sourav parmarcd5fb182020-07-17 12:58:44 -07002878 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(info.accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002879 if (as_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002880 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002881 auto mem_state = GetDevMemShared(info.memory);
2882 if (mem_state) {
2883 as_state->SetMemBinding(mem_state, info.memoryOffset);
2884 }
locke-lunargd556cc32019-09-17 01:21:23 -06002885
2886 // GPU validation of top level acceleration structure building needs acceleration structure handles.
Jeff Bolz95176d02020-04-01 00:36:16 -05002887 // XXX TODO: Query device address for KHR extension
sourav parmarcd5fb182020-07-17 12:58:44 -07002888 if (enabled[gpu_validation]) {
locke-lunargd556cc32019-09-17 01:21:23 -06002889 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
2890 }
2891 }
2892 }
2893}
2894
2895void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructureNV(
2896 VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset,
2897 VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002898 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002899 if (cb_state == nullptr) {
2900 return;
2901 }
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002902 cb_state->RecordCmd(CMD_BUILDACCELERATIONSTRUCTURENV);
locke-lunargd556cc32019-09-17 01:21:23 -06002903
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002904 auto *dst_as_state = GetAccelerationStructureStateNV(dst);
locke-lunargd556cc32019-09-17 01:21:23 -06002905 if (dst_as_state != nullptr) {
2906 dst_as_state->built = true;
2907 dst_as_state->build_info.initialize(pInfo);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002908 if (!disabled[command_buffer_state]) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002909 cb_state->AddChild(dst_as_state);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002910 }
locke-lunargd556cc32019-09-17 01:21:23 -06002911 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002912 if (!disabled[command_buffer_state]) {
2913 auto *src_as_state = GetAccelerationStructureStateNV(src);
2914 if (src_as_state != nullptr) {
2915 cb_state->AddChild(src_as_state);
2916 }
locke-lunargd556cc32019-09-17 01:21:23 -06002917 }
2918 cb_state->hasBuildAccelerationStructureCmd = true;
2919}
2920
2921void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureNV(VkCommandBuffer commandBuffer,
2922 VkAccelerationStructureNV dst,
2923 VkAccelerationStructureNV src,
2924 VkCopyAccelerationStructureModeNV mode) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002925 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002926 if (cb_state) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002927 ACCELERATION_STRUCTURE_STATE *src_as_state = GetAccelerationStructureStateNV(src);
2928 ACCELERATION_STRUCTURE_STATE *dst_as_state = GetAccelerationStructureStateNV(dst);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002929 if (!disabled[command_buffer_state]) {
2930 cb_state->RecordTransferCmd(CMD_COPYACCELERATIONSTRUCTURENV, src_as_state, dst_as_state);
2931 }
locke-lunargd556cc32019-09-17 01:21:23 -06002932 if (dst_as_state != nullptr && src_as_state != nullptr) {
2933 dst_as_state->built = true;
2934 dst_as_state->build_info = src_as_state->build_info;
locke-lunargd556cc32019-09-17 01:21:23 -06002935 }
2936 }
2937}
2938
Jeff Bolz95176d02020-04-01 00:36:16 -05002939void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureKHR(VkDevice device,
2940 VkAccelerationStructureKHR accelerationStructure,
2941 const VkAllocationCallbacks *pAllocator) {
locke-lunargd556cc32019-09-17 01:21:23 -06002942 if (!accelerationStructure) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07002943 auto *as_state = GetAccelerationStructureStateKHR(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002944 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002945 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07002946 accelerationStructureMap_khr.erase(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002947 }
2948}
2949
Jeff Bolz95176d02020-04-01 00:36:16 -05002950void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureNV(VkDevice device,
2951 VkAccelerationStructureNV accelerationStructure,
2952 const VkAllocationCallbacks *pAllocator) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002953 if (!accelerationStructure) return;
2954 auto *as_state = GetAccelerationStructureStateNV(accelerationStructure);
2955 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002956 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07002957 accelerationStructureMap.erase(accelerationStructure);
2958 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002959}
2960
Chris Mayer9ded5eb2019-09-19 16:33:26 +02002961void ValidationStateTracker::PreCallRecordCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2962 uint32_t viewportCount,
2963 const VkViewportWScalingNV *pViewportWScalings) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002964 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002965 cb_state->RecordStateCmd(CMD_SETVIEWPORTWSCALINGNV, CBSTATUS_VIEWPORT_W_SCALING_SET);
Chris Mayer9ded5eb2019-09-19 16:33:26 +02002966}
2967
locke-lunargd556cc32019-09-17 01:21:23 -06002968void ValidationStateTracker::PreCallRecordCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002969 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002970 cb_state->RecordStateCmd(CMD_SETLINEWIDTH, CBSTATUS_LINE_WIDTH_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002971}
2972
2973void ValidationStateTracker::PreCallRecordCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
2974 uint16_t lineStipplePattern) {
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_SETLINESTIPPLEEXT, CBSTATUS_LINE_STIPPLE_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002977}
2978
2979void ValidationStateTracker::PreCallRecordCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
2980 float depthBiasClamp, float depthBiasSlopeFactor) {
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_SETDEPTHBIAS, CBSTATUS_DEPTH_BIAS_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002983}
2984
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002985void ValidationStateTracker::PreCallRecordCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
2986 const VkRect2D *pScissors) {
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_SETSCISSOR, CBSTATUS_SCISSOR_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002989 uint32_t bits = ((1u << scissorCount) - 1u) << firstScissor;
2990 cb_state->scissorMask |= bits;
2991 cb_state->trashedScissorMask &= ~bits;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002992}
2993
locke-lunargd556cc32019-09-17 01:21:23 -06002994void ValidationStateTracker::PreCallRecordCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06002995 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06002996 cb_state->RecordStateCmd(CMD_SETBLENDCONSTANTS, CBSTATUS_BLEND_CONSTANTS_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06002997}
2998
2999void ValidationStateTracker::PreCallRecordCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
3000 float maxDepthBounds) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003001 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003002 cb_state->RecordStateCmd(CMD_SETDEPTHBOUNDS, CBSTATUS_DEPTH_BOUNDS_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06003003}
3004
3005void ValidationStateTracker::PreCallRecordCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3006 uint32_t compareMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003007 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003008 cb_state->RecordStateCmd(CMD_SETSTENCILCOMPAREMASK, CBSTATUS_STENCIL_READ_MASK_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06003009}
3010
3011void ValidationStateTracker::PreCallRecordCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3012 uint32_t writeMask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003013 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003014 cb_state->RecordStateCmd(CMD_SETSTENCILWRITEMASK, CBSTATUS_STENCIL_WRITE_MASK_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06003015}
3016
3017void ValidationStateTracker::PreCallRecordCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3018 uint32_t reference) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003019 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003020 cb_state->RecordStateCmd(CMD_SETSTENCILREFERENCE, CBSTATUS_STENCIL_REFERENCE_SET);
locke-lunargd556cc32019-09-17 01:21:23 -06003021}
3022
locke-lunargd556cc32019-09-17 01:21:23 -06003023
3024// Update the bound state for the bind point, including the effects of incompatible pipeline layouts
3025void ValidationStateTracker::PreCallRecordCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
3026 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3027 uint32_t firstSet, uint32_t setCount,
3028 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
3029 const uint32_t *pDynamicOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003030 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003031 cb_state->RecordCmd(CMD_BINDDESCRIPTORSETS);
locke-lunargd556cc32019-09-17 01:21:23 -06003032 auto pipeline_layout = GetPipelineLayout(layout);
3033
3034 // Resize binding arrays
3035 uint32_t last_set_index = firstSet + setCount - 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003036 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
3037 if (last_set_index >= cb_state->lastBound[lv_bind_point].per_set.size()) {
3038 cb_state->lastBound[lv_bind_point].per_set.resize(last_set_index + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06003039 }
3040
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003041 cb_state->UpdateLastBoundDescriptorSets(pipelineBindPoint, pipeline_layout, firstSet, setCount, pDescriptorSets, nullptr,
3042 dynamicOffsetCount, pDynamicOffsets);
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003043 cb_state->lastBound[lv_bind_point].pipeline_layout = layout;
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06003044 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06003045}
3046
locke-lunargd556cc32019-09-17 01:21:23 -06003047void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
3048 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3049 uint32_t set, uint32_t descriptorWriteCount,
3050 const VkWriteDescriptorSet *pDescriptorWrites) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003051 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003052 auto pipeline_layout = GetPipelineLayout(layout);
3053 cb_state->PushDescriptorSetState(pipelineBindPoint, pipeline_layout, set, descriptorWriteCount, pDescriptorWrites);
locke-lunargd556cc32019-09-17 01:21:23 -06003054}
3055
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003056void ValidationStateTracker::PostCallRecordCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
3057 VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
3058 const void *pValues) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003059 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003060 if (cb_state != nullptr) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003061 cb_state->RecordCmd(CMD_PUSHCONSTANTS);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003062 cb_state->ResetPushConstantDataIfIncompatible(GetPipelineLayout(layout));
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003063
3064 auto &push_constant_data = cb_state->push_constant_data;
3065 assert((offset + size) <= static_cast<uint32_t>(push_constant_data.size()));
3066 std::memcpy(push_constant_data.data() + offset, pValues, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003067 cb_state->push_constant_pipeline_layout_set = layout;
3068
3069 auto flags = stageFlags;
3070 uint32_t bit_shift = 0;
3071 while (flags) {
3072 if (flags & 1) {
3073 VkShaderStageFlagBits flag = static_cast<VkShaderStageFlagBits>(1 << bit_shift);
3074 const auto it = cb_state->push_constant_data_update.find(flag);
3075
3076 if (it != cb_state->push_constant_data_update.end()) {
locke-lunarg3d8b8f32020-10-26 17:04:16 -06003077 std::memset(it->second.data() + offset, PC_Byte_Updated, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003078 }
3079 }
3080 flags = flags >> 1;
3081 ++bit_shift;
3082 }
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003083 }
3084}
3085
locke-lunargd556cc32019-09-17 01:21:23 -06003086void ValidationStateTracker::PreCallRecordCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
3087 VkIndexType indexType) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003088 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003089
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003090 cb_state->RecordStateCmd(CMD_BINDINDEXBUFFER, CBSTATUS_INDEX_BUFFER_BOUND);
locke-lunarg1ae57d62020-11-18 10:49:19 -07003091 cb_state->index_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(buffer);
3092 cb_state->index_buffer_binding.size = cb_state->index_buffer_binding.buffer_state->createInfo.size;
locke-lunargd556cc32019-09-17 01:21:23 -06003093 cb_state->index_buffer_binding.offset = offset;
3094 cb_state->index_buffer_binding.index_type = indexType;
3095 // Add binding for this index buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003096 if (!disabled[command_buffer_state]) {
3097 cb_state->AddChild(cb_state->index_buffer_binding.buffer_state.get());
3098 }
locke-lunargd556cc32019-09-17 01:21:23 -06003099}
3100
3101void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
3102 uint32_t bindingCount, const VkBuffer *pBuffers,
3103 const VkDeviceSize *pOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003104 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003105 cb_state->RecordCmd(CMD_BINDVERTEXBUFFERS);
locke-lunargd556cc32019-09-17 01:21:23 -06003106
3107 uint32_t end = firstBinding + bindingCount;
3108 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
3109 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
3110 }
3111
3112 for (uint32_t i = 0; i < bindingCount; ++i) {
3113 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07003114 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003115 vertex_buffer_binding.offset = pOffsets[i];
Piers Daniell39842ee2020-07-10 16:42:33 -06003116 vertex_buffer_binding.size = VK_WHOLE_SIZE;
3117 vertex_buffer_binding.stride = 0;
locke-lunargd556cc32019-09-17 01:21:23 -06003118 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003119 if (pBuffers[i] && !disabled[command_buffer_state]) {
3120 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Jeff Bolz165818a2020-05-08 11:19:03 -05003121 }
locke-lunargd556cc32019-09-17 01:21:23 -06003122 }
3123}
3124
3125void ValidationStateTracker::PostCallRecordCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
3126 VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003127 if (disabled[command_buffer_state]) return;
3128
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003129 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003130 cb_state->RecordTransferCmd(CMD_UPDATEBUFFER, GetBufferState(dstBuffer));
locke-lunargd556cc32019-09-17 01:21:23 -06003131}
3132
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003133void ValidationStateTracker::PreCallRecordCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3134 VkPipelineStageFlags stageMask) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003135 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3136 cb_state->RecordSetEvent(CMD_SETEVENT, event, stageMask);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003137}
3138
3139void ValidationStateTracker::PreCallRecordCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3140 const VkDependencyInfoKHR *pDependencyInfo) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003141 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003142 auto stage_masks = sync_utils::GetGlobalStageMasks(*pDependencyInfo);
3143
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003144 cb_state->RecordSetEvent(CMD_SETEVENT2KHR, event, stage_masks.src);
3145 cb_state->RecordBarriers(*pDependencyInfo);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003146}
3147
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003148void ValidationStateTracker::PreCallRecordCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3149 VkPipelineStageFlags stageMask) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003150 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3151 cb_state->RecordResetEvent(CMD_RESETEVENT, event, stageMask);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003152}
3153
3154void ValidationStateTracker::PreCallRecordCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3155 VkPipelineStageFlags2KHR stageMask) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003156 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3157 cb_state->RecordResetEvent(CMD_RESETEVENT2KHR, event, stageMask);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003158}
3159
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003160void ValidationStateTracker::PreCallRecordCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
3161 VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
3162 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3163 uint32_t bufferMemoryBarrierCount,
3164 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3165 uint32_t imageMemoryBarrierCount,
3166 const VkImageMemoryBarrier *pImageMemoryBarriers) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003167 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3168 cb_state->RecordWaitEvents(CMD_WAITEVENTS, eventCount, pEvents);
3169 cb_state->RecordBarriers(memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3170 imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003171}
3172
3173void ValidationStateTracker::PreCallRecordCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount,
3174 const VkEvent *pEvents, const VkDependencyInfoKHR *pDependencyInfos) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003175 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3176 cb_state->RecordWaitEvents(CMD_WAITEVENTS2KHR, eventCount, pEvents);
Jeremy Gebben79649152021-06-22 14:46:24 -06003177 for (uint32_t i = 0; i < eventCount; i++) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003178 cb_state->RecordBarriers(pDependencyInfos[i]);
Jeremy Gebben79649152021-06-22 14:46:24 -06003179 }
3180}
3181
3182void ValidationStateTracker::PostCallRecordCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
3183 VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
3184 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3185 uint32_t bufferMemoryBarrierCount,
3186 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3187 uint32_t imageMemoryBarrierCount,
3188 const VkImageMemoryBarrier *pImageMemoryBarriers) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003189 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3190 cb_state->RecordCmd(CMD_PIPELINEBARRIER);
3191 cb_state->RecordBarriers(memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3192 imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Gebben79649152021-06-22 14:46:24 -06003193}
3194
3195void ValidationStateTracker::PreCallRecordCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
3196 const VkDependencyInfoKHR *pDependencyInfo) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003197 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3198 cb_state->RecordCmd(CMD_PIPELINEBARRIER2KHR);
3199 cb_state->RecordBarriers(*pDependencyInfo);
Jeremy Gebben79649152021-06-22 14:46:24 -06003200}
3201
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003202QueryState ValidationStateTracker::GetQueryState(const QueryMap *localQueryToStateMap, VkQueryPool queryPool, uint32_t queryIndex,
3203 uint32_t perfPass) const {
3204 QueryObject query = QueryObject(QueryObject(queryPool, queryIndex), perfPass);
locke-lunargd556cc32019-09-17 01:21:23 -06003205
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003206 auto iter = localQueryToStateMap->find(query);
3207 if (iter != localQueryToStateMap->end()) return iter->second;
Jeff Bolz310775c2019-10-09 00:46:33 -05003208
Jeff Bolz310775c2019-10-09 00:46:33 -05003209 return QUERYSTATE_UNKNOWN;
locke-lunargd556cc32019-09-17 01:21:23 -06003210}
3211
locke-lunargd556cc32019-09-17 01:21:23 -06003212void ValidationStateTracker::PostCallRecordCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot,
3213 VkFlags flags) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003214 if (disabled[query_validation]) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003215
locke-lunargd556cc32019-09-17 01:21:23 -06003216 QueryObject query = {queryPool, slot};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003217 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003218 cb_state->RecordCmd(CMD_BEGINQUERY);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003219 if (!disabled[query_validation]) {
3220 cb_state->BeginQuery(query);
3221 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003222 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003223 auto pool_state = GetQueryPoolState(query.pool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003224 cb_state->AddChild(pool_state);
3225 }
locke-lunargd556cc32019-09-17 01:21:23 -06003226}
3227
3228void ValidationStateTracker::PostCallRecordCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003229 if (disabled[query_validation]) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003230 QueryObject query_obj = {queryPool, slot};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003231 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003232 cb_state->RecordCmd(CMD_ENDQUERY);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003233 if (!disabled[query_validation]) {
3234 cb_state->EndQuery(query_obj);
3235 }
3236 if (!disabled[command_buffer_state]) {
3237 auto pool_state = GetQueryPoolState(query_obj.pool);
3238 cb_state->AddChild(pool_state);
3239 }
locke-lunargd556cc32019-09-17 01:21:23 -06003240}
3241
3242void ValidationStateTracker::PostCallRecordCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3243 uint32_t firstQuery, uint32_t queryCount) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003244 if (disabled[query_validation]) return;
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003245 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003246
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003247 cb_state->RecordCmd(CMD_RESETQUERYPOOL);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003248 cb_state->ResetQueryPool(queryPool, firstQuery, queryCount);
Lionel Landwerlinb1e5a422020-02-18 16:49:09 +02003249
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003250 if (!disabled[command_buffer_state]) {
3251 auto pool_state = GetQueryPoolState(queryPool);
3252 cb_state->AddChild(pool_state);
3253 }
locke-lunargd556cc32019-09-17 01:21:23 -06003254}
3255
3256void ValidationStateTracker::PostCallRecordCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3257 uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer,
3258 VkDeviceSize dstOffset, VkDeviceSize stride,
3259 VkQueryResultFlags flags) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003260 if (disabled[query_validation] || disabled[command_buffer_state]) return;
3261
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003262 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003263 cb_state->RecordCmd(CMD_COPYQUERYPOOLRESULTS);
locke-lunargd556cc32019-09-17 01:21:23 -06003264 auto dst_buff_state = GetBufferState(dstBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003265 cb_state->AddChild(dst_buff_state);
Jeff Bolzadbfa852019-10-04 13:53:30 -05003266 auto pool_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003267 cb_state->AddChild(pool_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003268}
3269
3270void ValidationStateTracker::PostCallRecordCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
3271 VkQueryPool queryPool, uint32_t slot) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003272 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3273 cb_state->RecordWriteTimestamp(CMD_WRITETIMESTAMP, pipelineStage, queryPool, slot);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003274}
3275
3276void ValidationStateTracker::PostCallRecordCmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer,
3277 VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool,
3278 uint32_t slot) {
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -06003279 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3280 cb_state->RecordWriteTimestamp(CMD_WRITETIMESTAMP2KHR, pipelineStage, queryPool, slot);
locke-lunargd556cc32019-09-17 01:21:23 -06003281}
3282
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003283void ValidationStateTracker::PostCallRecordCmdWriteAccelerationStructuresPropertiesKHR(
3284 VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR *pAccelerationStructures,
3285 VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery) {
3286 if (disabled[query_validation]) return;
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003287 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003288 cb_state->RecordCmd(CMD_WRITEACCELERATIONSTRUCTURESPROPERTIESKHR);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003289 if (!disabled[command_buffer_state]) {
3290 auto pool_state = GetQueryPoolState(queryPool);
3291 cb_state->AddChild(pool_state);
3292 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003293 cb_state->EndQueries(queryPool, firstQuery, accelerationStructureCount);
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003294}
3295
locke-lunargd556cc32019-09-17 01:21:23 -06003296void ValidationStateTracker::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
3297 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
3298 VkResult result) {
3299 if (VK_SUCCESS != result) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003300
Jeremy Gebben88f58142021-06-01 10:07:52 -06003301 std::vector<std::shared_ptr<IMAGE_VIEW_STATE>> views;
Mike Schuchardt2df08912020-12-15 16:28:09 -08003302 if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) == 0) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003303 views.resize(pCreateInfo->attachmentCount);
locke-lunarg1ae57d62020-11-18 10:49:19 -07003304
locke-lunargd556cc32019-09-17 01:21:23 -06003305 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003306 views[i] = GetShared<IMAGE_VIEW_STATE>(pCreateInfo->pAttachments[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003307 }
3308 }
Jeremy Gebben88f58142021-06-01 10:07:52 -06003309
3310 frameBufferMap[*pFramebuffer] = std::make_shared<FRAMEBUFFER_STATE>(
3311 *pFramebuffer, pCreateInfo, GetRenderPassShared(pCreateInfo->renderPass), std::move(views));
locke-lunargd556cc32019-09-17 01:21:23 -06003312}
3313
locke-lunargd556cc32019-09-17 01:21:23 -06003314void ValidationStateTracker::PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
3315 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3316 VkResult result) {
3317 if (VK_SUCCESS != result) return;
Jeremy Gebben88f58142021-06-01 10:07:52 -06003318 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06003319}
3320
Mike Schuchardt2df08912020-12-15 16:28:09 -08003321void ValidationStateTracker::PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003322 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3323 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003324 if (VK_SUCCESS != result) return;
3325
3326 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003327}
3328
Mike Schuchardt2df08912020-12-15 16:28:09 -08003329void ValidationStateTracker::PostCallRecordCreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003330 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3331 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003332 if (VK_SUCCESS != result) return;
3333
3334 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003335}
3336
locke-lunargd556cc32019-09-17 01:21:23 -06003337void ValidationStateTracker::PreCallRecordCmdBeginRenderPass(VkCommandBuffer commandBuffer,
3338 const VkRenderPassBeginInfo *pRenderPassBegin,
3339 VkSubpassContents contents) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003340 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3341 cb_state->BeginRenderPass(CMD_BEGINRENDERPASS, pRenderPassBegin, contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003342}
3343
3344void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
3345 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003346 const VkSubpassBeginInfo *pSubpassBeginInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003347 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3348 cb_state->BeginRenderPass(CMD_BEGINRENDERPASS2, pRenderPassBegin, pSubpassBeginInfo->contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003349}
3350
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003351void ValidationStateTracker::PostCallRecordCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3352 uint32_t counterBufferCount,
3353 const VkBuffer *pCounterBuffers,
3354 const VkDeviceSize *pCounterBufferOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003355 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003356
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003357 cb_state->RecordCmd(CMD_BEGINTRANSFORMFEEDBACKEXT);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003358 cb_state->transform_feedback_active = true;
3359}
3360
3361void ValidationStateTracker::PostCallRecordCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3362 uint32_t counterBufferCount, const VkBuffer *pCounterBuffers,
3363 const VkDeviceSize *pCounterBufferOffsets) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003364 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003365
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003366 cb_state->RecordCmd(CMD_ENDTRANSFORMFEEDBACKEXT);
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003367 cb_state->transform_feedback_active = false;
3368}
3369
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003370void ValidationStateTracker::PostCallRecordCmdBeginConditionalRenderingEXT(
3371 VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin) {
Jeremy Gebbenc8b51a92021-08-16 15:19:00 -06003372 auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003373
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003374 cb_state->RecordCmd(CMD_BEGINCONDITIONALRENDERINGEXT);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003375 cb_state->conditional_rendering_active = true;
3376}
3377
3378void ValidationStateTracker::PostCallRecordCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer) {
Jeremy Gebbenc8b51a92021-08-16 15:19:00 -06003379 auto *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003380
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003381 cb_state->RecordCmd(CMD_ENDCONDITIONALRENDERINGEXT);
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003382 cb_state->conditional_rendering_active = false;
3383
3384}
3385
Tony-LunarG977448c2019-12-02 14:52:02 -07003386void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
3387 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003388 const VkSubpassBeginInfo *pSubpassBeginInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003389 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3390 cb_state->BeginRenderPass(CMD_BEGINRENDERPASS2, pRenderPassBegin, pSubpassBeginInfo->contents);
Tony-LunarG977448c2019-12-02 14:52:02 -07003391}
3392
locke-lunargd556cc32019-09-17 01:21:23 -06003393
3394void ValidationStateTracker::PostCallRecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003395 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3396 cb_state->NextSubpass(CMD_NEXTSUBPASS, contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003397}
3398
3399void ValidationStateTracker::PostCallRecordCmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003400 const VkSubpassBeginInfo *pSubpassBeginInfo,
3401 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003402 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3403 cb_state->NextSubpass(CMD_NEXTSUBPASS2, pSubpassBeginInfo->contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003404}
3405
Tony-LunarG977448c2019-12-02 14:52:02 -07003406void ValidationStateTracker::PostCallRecordCmdNextSubpass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003407 const VkSubpassBeginInfo *pSubpassBeginInfo,
3408 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003409 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003410 cb_state->NextSubpass(CMD_NEXTSUBPASS2, pSubpassBeginInfo->contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003411}
3412
3413void ValidationStateTracker::PostCallRecordCmdEndRenderPass(VkCommandBuffer commandBuffer) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003414 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3415 cb_state->EndRenderPass(CMD_ENDRENDERPASS);
locke-lunargd556cc32019-09-17 01:21:23 -06003416}
3417
3418void ValidationStateTracker::PostCallRecordCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003419 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003420 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3421 cb_state->EndRenderPass(CMD_ENDRENDERPASS2);
locke-lunargd556cc32019-09-17 01:21:23 -06003422}
3423
Tony-LunarG977448c2019-12-02 14:52:02 -07003424void ValidationStateTracker::PostCallRecordCmdEndRenderPass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003425 const VkSubpassEndInfo *pSubpassEndInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06003426 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
3427 cb_state->EndRenderPass(CMD_ENDRENDERPASS2);
Tony-LunarG977448c2019-12-02 14:52:02 -07003428}
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003429
locke-lunargd556cc32019-09-17 01:21:23 -06003430void ValidationStateTracker::PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
3431 const VkCommandBuffer *pCommandBuffers) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06003432 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06003433
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003434 cb_state->ExecuteCommands(commandBuffersCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06003435}
3436
3437void ValidationStateTracker::PostCallRecordMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size,
3438 VkFlags flags, void **ppData, VkResult result) {
3439 if (VK_SUCCESS != result) return;
3440 RecordMappedMemory(mem, offset, size, ppData);
3441}
3442
3443void ValidationStateTracker::PreCallRecordUnmapMemory(VkDevice device, VkDeviceMemory mem) {
3444 auto mem_info = GetDevMemState(mem);
3445 if (mem_info) {
3446 mem_info->mapped_range = MemRange();
3447 mem_info->p_driver_data = nullptr;
3448 }
3449}
3450
3451void ValidationStateTracker::UpdateBindImageMemoryState(const VkBindImageMemoryInfo &bindInfo) {
Jeremy Gebben8ee02af2021-07-16 10:15:55 -06003452 auto image_state = GetShared<IMAGE_STATE>(bindInfo.image);
locke-lunargd556cc32019-09-17 01:21:23 -06003453 if (image_state) {
locke-lunargae26eac2020-04-16 15:29:05 -06003454 // An Android sepcial image cannot get VkSubresourceLayout until the image binds a memory.
3455 // See: VUID-vkGetImageSubresourceLayout-image-01895
3456 image_state->fragment_encoder =
3457 std::unique_ptr<const subresource_adapter::ImageRangeEncoder>(new subresource_adapter::ImageRangeEncoder(*image_state));
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003458 const auto swapchain_info = LvlFindInChain<VkBindImageMemorySwapchainInfoKHR>(bindInfo.pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003459 if (swapchain_info) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003460 auto swapchain = GetShared<SWAPCHAIN_NODE>(swapchain_info->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003461 if (swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003462 SWAPCHAIN_IMAGE &swapchain_image = swapchain->images[swapchain_info->imageIndex];
John Zulaufd13b38e2021-03-05 08:17:38 -07003463
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003464 if (!swapchain_image.fake_base_address) {
3465 auto size = image_state->fragment_encoder->TotalSize();
3466 swapchain_image.fake_base_address = fake_memory.Alloc(size);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06003467 }
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003468 // All images bound to this swapchain and index are aliases
3469 image_state->SetSwapchain(swapchain, swapchain_info->imageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003470 }
3471 } else {
3472 // Track bound memory range information
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003473 auto mem_info = GetDevMemShared(bindInfo.memory);
locke-lunargd556cc32019-09-17 01:21:23 -06003474 if (mem_info) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003475 image_state->SetMemBinding(mem_info, bindInfo.memoryOffset);
locke-lunargd556cc32019-09-17 01:21:23 -06003476 }
locke-lunargd556cc32019-09-17 01:21:23 -06003477 }
locke-lunargd556cc32019-09-17 01:21:23 -06003478 }
3479}
3480
3481void ValidationStateTracker::PostCallRecordBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
3482 VkDeviceSize memoryOffset, VkResult result) {
3483 if (VK_SUCCESS != result) return;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003484 auto bind_info = LvlInitStruct<VkBindImageMemoryInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003485 bind_info.image = image;
3486 bind_info.memory = mem;
3487 bind_info.memoryOffset = memoryOffset;
3488 UpdateBindImageMemoryState(bind_info);
locke-lunargd556cc32019-09-17 01:21:23 -06003489}
3490
3491void ValidationStateTracker::PostCallRecordBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003492 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003493 if (VK_SUCCESS != result) return;
3494 for (uint32_t i = 0; i < bindInfoCount; i++) {
3495 UpdateBindImageMemoryState(pBindInfos[i]);
3496 }
3497}
3498
3499void ValidationStateTracker::PostCallRecordBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003500 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003501 if (VK_SUCCESS != result) return;
3502 for (uint32_t i = 0; i < bindInfoCount; i++) {
3503 UpdateBindImageMemoryState(pBindInfos[i]);
3504 }
3505}
3506
3507void ValidationStateTracker::PreCallRecordSetEvent(VkDevice device, VkEvent event) {
3508 auto event_state = GetEventState(event);
3509 if (event_state) {
3510 event_state->stageMask = VK_PIPELINE_STAGE_HOST_BIT;
3511 }
locke-lunargd556cc32019-09-17 01:21:23 -06003512}
3513
3514void ValidationStateTracker::PostCallRecordImportSemaphoreFdKHR(VkDevice device,
3515 const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo,
3516 VkResult result) {
3517 if (VK_SUCCESS != result) return;
3518 RecordImportSemaphoreState(pImportSemaphoreFdInfo->semaphore, pImportSemaphoreFdInfo->handleType,
3519 pImportSemaphoreFdInfo->flags);
3520}
3521
3522void ValidationStateTracker::RecordGetExternalSemaphoreState(VkSemaphore semaphore,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003523 VkExternalSemaphoreHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003524 SEMAPHORE_STATE *semaphore_state = GetSemaphoreState(semaphore);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003525 if (semaphore_state && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003526 // Cannot track semaphore state once it is exported, except for Sync FD handle types which have copy transference
3527 semaphore_state->scope = kSyncScopeExternalPermanent;
3528 }
3529}
3530
3531#ifdef VK_USE_PLATFORM_WIN32_KHR
3532void ValidationStateTracker::PostCallRecordImportSemaphoreWin32HandleKHR(
3533 VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR *pImportSemaphoreWin32HandleInfo, VkResult result) {
3534 if (VK_SUCCESS != result) return;
3535 RecordImportSemaphoreState(pImportSemaphoreWin32HandleInfo->semaphore, pImportSemaphoreWin32HandleInfo->handleType,
3536 pImportSemaphoreWin32HandleInfo->flags);
3537}
3538
3539void ValidationStateTracker::PostCallRecordGetSemaphoreWin32HandleKHR(VkDevice device,
3540 const VkSemaphoreGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3541 HANDLE *pHandle, VkResult result) {
3542 if (VK_SUCCESS != result) return;
3543 RecordGetExternalSemaphoreState(pGetWin32HandleInfo->semaphore, pGetWin32HandleInfo->handleType);
3544}
3545
3546void ValidationStateTracker::PostCallRecordImportFenceWin32HandleKHR(
3547 VkDevice device, const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo, VkResult result) {
3548 if (VK_SUCCESS != result) return;
3549 RecordImportFenceState(pImportFenceWin32HandleInfo->fence, pImportFenceWin32HandleInfo->handleType,
3550 pImportFenceWin32HandleInfo->flags);
3551}
3552
3553void ValidationStateTracker::PostCallRecordGetFenceWin32HandleKHR(VkDevice device,
3554 const VkFenceGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3555 HANDLE *pHandle, VkResult result) {
3556 if (VK_SUCCESS != result) return;
3557 RecordGetExternalFenceState(pGetWin32HandleInfo->fence, pGetWin32HandleInfo->handleType);
3558}
3559#endif
3560
3561void ValidationStateTracker::PostCallRecordGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *pGetFdInfo, int *pFd,
3562 VkResult result) {
3563 if (VK_SUCCESS != result) return;
3564 RecordGetExternalSemaphoreState(pGetFdInfo->semaphore, pGetFdInfo->handleType);
3565}
3566
Mike Schuchardt2df08912020-12-15 16:28:09 -08003567void ValidationStateTracker::RecordImportFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type,
3568 VkFenceImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06003569 FENCE_STATE *fence_node = GetFenceState(fence);
3570 if (fence_node && fence_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003571 if ((handle_type == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_FENCE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06003572 fence_node->scope == kSyncScopeInternal) {
3573 fence_node->scope = kSyncScopeExternalTemporary;
3574 } else {
3575 fence_node->scope = kSyncScopeExternalPermanent;
3576 }
3577 }
3578}
3579
3580void ValidationStateTracker::PostCallRecordImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo,
3581 VkResult result) {
3582 if (VK_SUCCESS != result) return;
3583 RecordImportFenceState(pImportFenceFdInfo->fence, pImportFenceFdInfo->handleType, pImportFenceFdInfo->flags);
3584}
3585
Mike Schuchardt2df08912020-12-15 16:28:09 -08003586void ValidationStateTracker::RecordGetExternalFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003587 FENCE_STATE *fence_state = GetFenceState(fence);
3588 if (fence_state) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003589 if (handle_type != VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003590 // Export with reference transference becomes external
3591 fence_state->scope = kSyncScopeExternalPermanent;
3592 } else if (fence_state->scope == kSyncScopeInternal) {
3593 // Export with copy transference has a side effect of resetting the fence
3594 fence_state->state = FENCE_UNSIGNALED;
3595 }
3596 }
3597}
3598
3599void ValidationStateTracker::PostCallRecordGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *pGetFdInfo, int *pFd,
3600 VkResult result) {
3601 if (VK_SUCCESS != result) return;
3602 RecordGetExternalFenceState(pGetFdInfo->fence, pGetFdInfo->handleType);
3603}
3604
3605void ValidationStateTracker::PostCallRecordCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
3606 const VkAllocationCallbacks *pAllocator, VkEvent *pEvent, VkResult result) {
3607 if (VK_SUCCESS != result) return;
John Zulaufd5115702021-01-18 12:34:33 -07003608 const auto event = *pEvent;
Jeremy Gebbencbf22862021-03-03 12:01:22 -07003609 eventMap.emplace(event, std::make_shared<EVENT_STATE>(event, pCreateInfo->flags));
locke-lunargd556cc32019-09-17 01:21:23 -06003610}
3611
3612void ValidationStateTracker::RecordCreateSwapchainState(VkResult result, const VkSwapchainCreateInfoKHR *pCreateInfo,
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003613 VkSwapchainKHR *pSwapchain, std::shared_ptr<SURFACE_STATE> &&surface_state,
locke-lunargd556cc32019-09-17 01:21:23 -06003614 SWAPCHAIN_NODE *old_swapchain_state) {
3615 if (VK_SUCCESS == result) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003616 if (surface_state->swapchain) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003617 surface_state->RemoveParent(surface_state->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003618 }
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003619 auto swapchain = CreateSwapchainState(pCreateInfo, *pSwapchain);
3620 surface_state->AddParent(swapchain.get());
3621 surface_state->swapchain = swapchain.get();
3622 swapchain->surface = std::move(surface_state);
3623 swapchainMap[*pSwapchain] = std::move(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003624 } else {
3625 surface_state->swapchain = nullptr;
3626 }
3627 // Spec requires that even if CreateSwapchainKHR fails, oldSwapchain is retired
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003628 // Retired swapchains remain associated with the surface until they are destroyed.
locke-lunargd556cc32019-09-17 01:21:23 -06003629 if (old_swapchain_state) {
3630 old_swapchain_state->retired = true;
3631 }
3632 return;
3633}
3634
3635void ValidationStateTracker::PostCallRecordCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
3636 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain,
3637 VkResult result) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003638 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfo->surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003639 auto old_swapchain_state = GetSwapchainState(pCreateInfo->oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003640 RecordCreateSwapchainState(result, pCreateInfo, pSwapchain, std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003641}
3642
3643void ValidationStateTracker::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
3644 const VkAllocationCallbacks *pAllocator) {
3645 if (!swapchain) return;
3646 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003647 if (!swapchain_data) return;
John Zulauffaa7a522021-03-05 12:22:45 -07003648
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003649 swapchain_data->Destroy();
3650 swapchainMap.erase(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003651}
3652
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003653void ValidationStateTracker::PostCallRecordCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
3654 const VkDisplayModeCreateInfoKHR *pCreateInfo,
3655 const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode,
3656 VkResult result) {
3657 if (VK_SUCCESS != result) return;
3658 if (!pMode) return;
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06003659 display_mode_map[*pMode] = std::make_shared<DISPLAY_MODE_STATE>(*pMode, physicalDevice);
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003660}
3661
locke-lunargd556cc32019-09-17 01:21:23 -06003662void ValidationStateTracker::PostCallRecordQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo, VkResult result) {
3663 // Semaphore waits occur before error generation, if the call reached the ICD. (Confirm?)
3664 for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003665 auto semaphore_state = GetSemaphoreState(pPresentInfo->pWaitSemaphores[i]);
3666 if (semaphore_state) {
3667 semaphore_state->signaler.first = VK_NULL_HANDLE;
3668 semaphore_state->signaled = false;
locke-lunargd556cc32019-09-17 01:21:23 -06003669 }
3670 }
3671
Tony-LunarG6f887e52021-07-27 11:23:14 -06003672 const auto *present_id_info = LvlFindInChain<VkPresentIdKHR>(pPresentInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003673 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
3674 // 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
3675 // confused itself just as much.
3676 auto local_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result;
3677 if (local_result != VK_SUCCESS && local_result != VK_SUBOPTIMAL_KHR) continue; // this present didn't actually happen.
3678 // Mark the image as having been released to the WSI
3679 auto swapchain_data = GetSwapchainState(pPresentInfo->pSwapchains[i]);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003680 if (swapchain_data) {
3681 swapchain_data->PresentImage(pPresentInfo->pImageIndices[i]);
Tony-LunarG6f887e52021-07-27 11:23:14 -06003682 if (present_id_info) {
3683 if (i < present_id_info->swapchainCount && present_id_info->pPresentIds[i] > swapchain_data->max_present_id) {
3684 swapchain_data->max_present_id = present_id_info->pPresentIds[i];
3685 }
3686 }
locke-lunargd556cc32019-09-17 01:21:23 -06003687 }
3688 }
3689 // Note: even though presentation is directed to a queue, there is no direct ordering between QP and subsequent work, so QP (and
3690 // its semaphore waits) /never/ participate in any completion proof.
3691}
3692
3693void ValidationStateTracker::PostCallRecordCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
3694 const VkSwapchainCreateInfoKHR *pCreateInfos,
3695 const VkAllocationCallbacks *pAllocator,
3696 VkSwapchainKHR *pSwapchains, VkResult result) {
3697 if (pCreateInfos) {
3698 for (uint32_t i = 0; i < swapchainCount; i++) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003699 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfos[i].surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003700 auto old_swapchain_state = GetSwapchainState(pCreateInfos[i].oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003701 RecordCreateSwapchainState(result, &pCreateInfos[i], &pSwapchains[i], std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003702 }
3703 }
3704}
3705
3706void ValidationStateTracker::RecordAcquireNextImageState(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3707 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003708 auto fence_state = GetFenceState(fence);
3709 if (fence_state && fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003710 // Treat as inflight since it is valid to wait on this fence, even in cases where it is technically a temporary
3711 // import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003712 fence_state->state = FENCE_INFLIGHT;
3713 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 -06003714 }
3715
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003716 auto semaphore_state = GetSemaphoreState(semaphore);
3717 if (semaphore_state && semaphore_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003718 // Treat as signaled since it is valid to wait on this semaphore, even in cases where it is technically a
3719 // temporary import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003720 semaphore_state->signaled = true;
3721 semaphore_state->signaler.first = VK_NULL_HANDLE;
locke-lunargd556cc32019-09-17 01:21:23 -06003722 }
3723
3724 // Mark the image as acquired.
3725 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003726 if (swapchain_data) {
3727 swapchain_data->AcquireImage(*pImageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003728 }
3729}
3730
3731void ValidationStateTracker::PostCallRecordAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3732 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex,
3733 VkResult result) {
3734 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3735 RecordAcquireNextImageState(device, swapchain, timeout, semaphore, fence, pImageIndex);
3736}
3737
3738void ValidationStateTracker::PostCallRecordAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
3739 uint32_t *pImageIndex, VkResult result) {
3740 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3741 RecordAcquireNextImageState(device, pAcquireInfo->swapchain, pAcquireInfo->timeout, pAcquireInfo->semaphore,
3742 pAcquireInfo->fence, pImageIndex);
3743}
3744
3745void ValidationStateTracker::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
3746 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
3747 if ((NULL != pPhysicalDevices) && ((result == VK_SUCCESS || result == VK_INCOMPLETE))) {
3748 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
3749 auto &phys_device_state = physical_device_map[pPhysicalDevices[i]];
3750 phys_device_state.phys_device = pPhysicalDevices[i];
3751 // Init actual features for each physical device
3752 DispatchGetPhysicalDeviceFeatures(pPhysicalDevices[i], &phys_device_state.features2.features);
3753 }
3754 }
3755}
3756
3757// Common function to update state for GetPhysicalDeviceQueueFamilyProperties & 2KHR version
3758static void StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003759 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003760 pd_state->queue_family_known_count = std::max(pd_state->queue_family_known_count, count);
3761
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003762 if (pQueueFamilyProperties) { // Save queue family properties
locke-lunargd556cc32019-09-17 01:21:23 -06003763 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
3764 for (uint32_t i = 0; i < count; ++i) {
3765 pd_state->queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
3766 }
3767 }
3768}
3769
3770void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
3771 uint32_t *pQueueFamilyPropertyCount,
3772 VkQueueFamilyProperties *pQueueFamilyProperties) {
3773 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3774 assert(physical_device_state);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003775 VkQueueFamilyProperties2 *pqfp = nullptr;
3776 std::vector<VkQueueFamilyProperties2> qfp;
locke-lunargd556cc32019-09-17 01:21:23 -06003777 qfp.resize(*pQueueFamilyPropertyCount);
3778 if (pQueueFamilyProperties) {
3779 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003780 qfp[i] = LvlInitStruct<VkQueueFamilyProperties2>();
locke-lunargd556cc32019-09-17 01:21:23 -06003781 qfp[i].queueFamilyProperties = pQueueFamilyProperties[i];
3782 }
3783 pqfp = qfp.data();
3784 }
3785 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount, pqfp);
3786}
3787
3788void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003789 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003790 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3791 assert(physical_device_state);
3792 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3793 pQueueFamilyProperties);
3794}
3795
3796void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003797 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003798 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3799 assert(physical_device_state);
3800 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3801 pQueueFamilyProperties);
3802}
3803void ValidationStateTracker::PreCallRecordDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
3804 const VkAllocationCallbacks *pAllocator) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003805 if (!surface) return;
3806 auto surface_state = GetSurfaceState(surface);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003807 surface_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06003808 surface_map.erase(surface);
3809}
3810
3811void ValidationStateTracker::RecordVulkanSurface(VkSurfaceKHR *pSurface) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003812 surface_map[*pSurface] = std::make_shared<SURFACE_STATE>(*pSurface);
locke-lunargd556cc32019-09-17 01:21:23 -06003813}
3814
3815void ValidationStateTracker::PostCallRecordCreateDisplayPlaneSurfaceKHR(VkInstance instance,
3816 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
3817 const VkAllocationCallbacks *pAllocator,
3818 VkSurfaceKHR *pSurface, VkResult result) {
3819 if (VK_SUCCESS != result) return;
3820 RecordVulkanSurface(pSurface);
3821}
3822
3823#ifdef VK_USE_PLATFORM_ANDROID_KHR
3824void ValidationStateTracker::PostCallRecordCreateAndroidSurfaceKHR(VkInstance instance,
3825 const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
3826 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3827 VkResult result) {
3828 if (VK_SUCCESS != result) return;
3829 RecordVulkanSurface(pSurface);
3830}
3831#endif // VK_USE_PLATFORM_ANDROID_KHR
3832
3833#ifdef VK_USE_PLATFORM_IOS_MVK
3834void ValidationStateTracker::PostCallRecordCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *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_IOS_MVK
3841
3842#ifdef VK_USE_PLATFORM_MACOS_MVK
3843void ValidationStateTracker::PostCallRecordCreateMacOSSurfaceMVK(VkInstance instance,
3844 const VkMacOSSurfaceCreateInfoMVK *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_MACOS_MVK
3851
Jeremy Kniagerf33a67c2019-12-09 09:44:39 -07003852#ifdef VK_USE_PLATFORM_METAL_EXT
3853void ValidationStateTracker::PostCallRecordCreateMetalSurfaceEXT(VkInstance instance,
3854 const VkMetalSurfaceCreateInfoEXT *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_METAL_EXT
3861
locke-lunargd556cc32019-09-17 01:21:23 -06003862#ifdef VK_USE_PLATFORM_WAYLAND_KHR
3863void ValidationStateTracker::PostCallRecordCreateWaylandSurfaceKHR(VkInstance instance,
3864 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
3865 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3866 VkResult result) {
3867 if (VK_SUCCESS != result) return;
3868 RecordVulkanSurface(pSurface);
3869}
3870#endif // VK_USE_PLATFORM_WAYLAND_KHR
3871
3872#ifdef VK_USE_PLATFORM_WIN32_KHR
3873void ValidationStateTracker::PostCallRecordCreateWin32SurfaceKHR(VkInstance instance,
3874 const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
3875 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3876 VkResult result) {
3877 if (VK_SUCCESS != result) return;
3878 RecordVulkanSurface(pSurface);
3879}
3880#endif // VK_USE_PLATFORM_WIN32_KHR
3881
3882#ifdef VK_USE_PLATFORM_XCB_KHR
3883void ValidationStateTracker::PostCallRecordCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
3884 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3885 VkResult result) {
3886 if (VK_SUCCESS != result) return;
3887 RecordVulkanSurface(pSurface);
3888}
3889#endif // VK_USE_PLATFORM_XCB_KHR
3890
3891#ifdef VK_USE_PLATFORM_XLIB_KHR
3892void ValidationStateTracker::PostCallRecordCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
3893 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3894 VkResult result) {
3895 if (VK_SUCCESS != result) return;
3896 RecordVulkanSurface(pSurface);
3897}
3898#endif // VK_USE_PLATFORM_XLIB_KHR
3899
Niklas Haas8b84af12020-04-19 22:20:11 +02003900void ValidationStateTracker::PostCallRecordCreateHeadlessSurfaceEXT(VkInstance instance,
3901 const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
3902 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3903 VkResult result) {
3904 if (VK_SUCCESS != result) return;
3905 RecordVulkanSurface(pSurface);
3906}
3907
Cort23cf2282019-09-20 18:58:18 +02003908void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02003909 VkPhysicalDeviceFeatures *pFeatures) {
3910 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Yilong Li358152a2020-07-08 02:16:45 -07003911 // Reset the features2 safe struct before setting up the features field.
3912 physical_device_state->features2 = safe_VkPhysicalDeviceFeatures2();
Cortffba2642019-09-20 22:09:41 +02003913 physical_device_state->features2.features = *pFeatures;
Cort23cf2282019-09-20 18:58:18 +02003914}
3915
3916void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02003917 VkPhysicalDeviceFeatures2 *pFeatures) {
3918 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02003919 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02003920}
3921
3922void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02003923 VkPhysicalDeviceFeatures2 *pFeatures) {
3924 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02003925 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02003926}
3927
locke-lunargd556cc32019-09-17 01:21:23 -06003928void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
3929 VkSurfaceKHR surface,
3930 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities,
3931 VkResult result) {
3932 if (VK_SUCCESS != result) return;
3933 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003934 physical_device_state->surfaceCapabilities = *pSurfaceCapabilities;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003935
3936 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
3937 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06003938}
3939
3940void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(
3941 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
3942 VkSurfaceCapabilities2KHR *pSurfaceCapabilities, VkResult result) {
3943 if (VK_SUCCESS != result) return;
3944 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003945 physical_device_state->surfaceCapabilities = pSurfaceCapabilities->surfaceCapabilities;
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::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,
3952 VkSurfaceKHR surface,
3953 VkSurfaceCapabilities2EXT *pSurfaceCapabilities,
3954 VkResult result) {
3955 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003956 physical_device_state->surfaceCapabilities.minImageCount = pSurfaceCapabilities->minImageCount;
3957 physical_device_state->surfaceCapabilities.maxImageCount = pSurfaceCapabilities->maxImageCount;
3958 physical_device_state->surfaceCapabilities.currentExtent = pSurfaceCapabilities->currentExtent;
3959 physical_device_state->surfaceCapabilities.minImageExtent = pSurfaceCapabilities->minImageExtent;
3960 physical_device_state->surfaceCapabilities.maxImageExtent = pSurfaceCapabilities->maxImageExtent;
3961 physical_device_state->surfaceCapabilities.maxImageArrayLayers = pSurfaceCapabilities->maxImageArrayLayers;
3962 physical_device_state->surfaceCapabilities.supportedTransforms = pSurfaceCapabilities->supportedTransforms;
3963 physical_device_state->surfaceCapabilities.currentTransform = pSurfaceCapabilities->currentTransform;
3964 physical_device_state->surfaceCapabilities.supportedCompositeAlpha = pSurfaceCapabilities->supportedCompositeAlpha;
3965 physical_device_state->surfaceCapabilities.supportedUsageFlags = pSurfaceCapabilities->supportedUsageFlags;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003966
3967 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
3968 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06003969}
3970
3971void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
3972 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
3973 VkBool32 *pSupported, VkResult result) {
3974 if (VK_SUCCESS != result) return;
3975 auto surface_state = GetSurfaceState(surface);
3976 surface_state->gpu_queue_support[{physicalDevice, queueFamilyIndex}] = (*pSupported == VK_TRUE);
3977}
3978
3979void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
3980 VkSurfaceKHR surface,
3981 uint32_t *pPresentModeCount,
3982 VkPresentModeKHR *pPresentModes,
3983 VkResult result) {
3984 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
3985
3986 // TODO: This isn't quite right -- available modes may differ by surface AND physical device.
3987 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06003988
3989 if (*pPresentModeCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003990 if (*pPresentModeCount > physical_device_state->present_modes.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06003991 physical_device_state->present_modes.resize(*pPresentModeCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003992 }
locke-lunargd556cc32019-09-17 01:21:23 -06003993 }
3994 if (pPresentModes) {
locke-lunargd556cc32019-09-17 01:21:23 -06003995 for (uint32_t i = 0; i < *pPresentModeCount; i++) {
3996 physical_device_state->present_modes[i] = pPresentModes[i];
3997 }
3998 }
3999}
4000
4001void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
4002 uint32_t *pSurfaceFormatCount,
4003 VkSurfaceFormatKHR *pSurfaceFormats,
4004 VkResult result) {
4005 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4006
4007 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004008
4009 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004010 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06004011 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004012 }
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++) {
4016 physical_device_state->surface_formats[i] = pSurfaceFormats[i];
4017 }
4018 }
4019}
4020
4021void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
4022 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
4023 uint32_t *pSurfaceFormatCount,
4024 VkSurfaceFormat2KHR *pSurfaceFormats,
4025 VkResult result) {
4026 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4027
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004028 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004029 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004030 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
4031 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
4032 }
locke-lunargd556cc32019-09-17 01:21:23 -06004033 }
4034 if (pSurfaceFormats) {
locke-lunargd556cc32019-09-17 01:21:23 -06004035 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004036 physical_device_state->surface_formats[i] = pSurfaceFormats[i].surfaceFormat;
locke-lunargd556cc32019-09-17 01:21:23 -06004037 }
4038 }
4039}
4040
4041void ValidationStateTracker::PreCallRecordCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4042 const VkDebugUtilsLabelEXT *pLabelInfo) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004043 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
4044 cb_state->RecordCmd(CMD_BEGINDEBUGUTILSLABELEXT);
locke-lunargd556cc32019-09-17 01:21:23 -06004045 BeginCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4046}
4047
4048void ValidationStateTracker::PostCallRecordCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004049 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
4050 cb_state->RecordCmd(CMD_ENDDEBUGUTILSLABELEXT);
locke-lunargd556cc32019-09-17 01:21:23 -06004051 EndCmdDebugUtilsLabel(report_data, commandBuffer);
4052}
4053
4054void ValidationStateTracker::PreCallRecordCmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4055 const VkDebugUtilsLabelEXT *pLabelInfo) {
4056 InsertCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4057
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004058 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004059 cb_state->RecordCmd(CMD_INSERTDEBUGUTILSLABELEXT);
4060 // Squirrel away an easily accessible copy.
locke-lunargd556cc32019-09-17 01:21:23 -06004061 cb_state->debug_label = LoggingLabel(pLabelInfo);
4062}
4063
4064void ValidationStateTracker::RecordEnumeratePhysicalDeviceGroupsState(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004065 uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06004066 if (NULL != pPhysicalDeviceGroupProperties) {
4067 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
4068 for (uint32_t j = 0; j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount; j++) {
4069 VkPhysicalDevice cur_phys_dev = pPhysicalDeviceGroupProperties[i].physicalDevices[j];
4070 auto &phys_device_state = physical_device_map[cur_phys_dev];
4071 phys_device_state.phys_device = cur_phys_dev;
4072 // Init actual features for each physical device
4073 DispatchGetPhysicalDeviceFeatures(cur_phys_dev, &phys_device_state.features2.features);
4074 }
4075 }
4076 }
4077}
4078
4079void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroups(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004080 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004081 VkResult result) {
4082 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4083 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4084}
4085
4086void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroupsKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004087 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004088 VkResult result) {
4089 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4090 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4091}
4092
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004093void ValidationStateTracker::RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(VkPhysicalDevice physicalDevice,
4094 uint32_t queueFamilyIndex,
4095 uint32_t *pCounterCount,
4096 VkPerformanceCounterKHR *pCounters) {
4097 if (NULL == pCounters) return;
4098
4099 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4100 assert(physical_device_state);
4101
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004102 std::unique_ptr<QUEUE_FAMILY_PERF_COUNTERS> queue_family_counters(new QUEUE_FAMILY_PERF_COUNTERS());
4103 queue_family_counters->counters.resize(*pCounterCount);
4104 for (uint32_t i = 0; i < *pCounterCount; i++) queue_family_counters->counters[i] = pCounters[i];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004105
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004106 physical_device_state->perf_counters[queueFamilyIndex] = std::move(queue_family_counters);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004107}
4108
4109void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
4110 VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t *pCounterCount, VkPerformanceCounterKHR *pCounters,
4111 VkPerformanceCounterDescriptionKHR *pCounterDescriptions, VkResult result) {
4112 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4113 RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(physicalDevice, queueFamilyIndex, pCounterCount, pCounters);
4114}
4115
4116void ValidationStateTracker::PostCallRecordAcquireProfilingLockKHR(VkDevice device, const VkAcquireProfilingLockInfoKHR *pInfo,
4117 VkResult result) {
4118 if (result == VK_SUCCESS) performance_lock_acquired = true;
4119}
4120
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004121void ValidationStateTracker::PostCallRecordReleaseProfilingLockKHR(VkDevice device) {
4122 performance_lock_acquired = false;
4123 for (auto &cmd_buffer : commandBufferMap) {
4124 cmd_buffer.second->performance_lock_released = true;
4125 }
4126}
4127
locke-lunargd556cc32019-09-17 01:21:23 -06004128void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplate(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004129 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004130 const VkAllocationCallbacks *pAllocator) {
4131 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004132 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4133 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004134 desc_template_map.erase(descriptorUpdateTemplate);
4135}
4136
4137void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplateKHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004138 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004139 const VkAllocationCallbacks *pAllocator) {
4140 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004141 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4142 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004143 desc_template_map.erase(descriptorUpdateTemplate);
4144}
4145
Mike Schuchardt2df08912020-12-15 16:28:09 -08004146void ValidationStateTracker::RecordCreateDescriptorUpdateTemplateState(const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4147 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
locke-lunargd556cc32019-09-17 01:21:23 -06004148 safe_VkDescriptorUpdateTemplateCreateInfo local_create_info(pCreateInfo);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004149 auto template_state = std::make_shared<TEMPLATE_STATE>(*pDescriptorUpdateTemplate, &local_create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004150 desc_template_map[*pDescriptorUpdateTemplate] = std::move(template_state);
4151}
4152
Mike Schuchardt2df08912020-12-15 16:28:09 -08004153void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplate(VkDevice device,
4154 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4155 const VkAllocationCallbacks *pAllocator,
4156 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate,
4157 VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004158 if (VK_SUCCESS != result) return;
4159 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4160}
4161
4162void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplateKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004163 VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
4164 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004165 if (VK_SUCCESS != result) return;
4166 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4167}
4168
4169void ValidationStateTracker::RecordUpdateDescriptorSetWithTemplateState(VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004170 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004171 const void *pData) {
4172 auto const template_map_entry = desc_template_map.find(descriptorUpdateTemplate);
4173 if ((template_map_entry == desc_template_map.end()) || (template_map_entry->second.get() == nullptr)) {
4174 assert(0);
4175 } else {
4176 const TEMPLATE_STATE *template_state = template_map_entry->second.get();
4177 // TODO: Record template push descriptor updates
4178 if (template_state->create_info.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET) {
4179 PerformUpdateDescriptorSetsWithTemplateKHR(descriptorSet, template_state, pData);
4180 }
4181 }
4182}
4183
4184void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
4185 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4186 const void *pData) {
4187 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4188}
4189
4190void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004191 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004192 const void *pData) {
4193 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4194}
4195
Mike Schuchardt2df08912020-12-15 16:28:09 -08004196void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
4197 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4198 VkPipelineLayout layout, uint32_t set,
4199 const void *pData) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004200 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004201
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004202 cb_state->RecordCmd(CMD_PUSHDESCRIPTORSETWITHTEMPLATEKHR);
locke-lunargd556cc32019-09-17 01:21:23 -06004203 const auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4204 if (template_state) {
4205 auto layout_data = GetPipelineLayout(layout);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06004206 auto dsl = layout_data ? layout_data->GetDsl(set) : nullptr;
locke-lunargd556cc32019-09-17 01:21:23 -06004207 const auto &template_ci = template_state->create_info;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004208 // Decode the template into a set of write updates
4209 cvdescriptorset::DecodedTemplateUpdate decoded_template(this, VK_NULL_HANDLE, template_state, pData,
4210 dsl->GetDescriptorSetLayout());
4211 cb_state->PushDescriptorSetState(template_ci.pipelineBindPoint, layout_data, set,
4212 static_cast<uint32_t>(decoded_template.desc_writes.size()),
4213 decoded_template.desc_writes.data());
locke-lunargd556cc32019-09-17 01:21:23 -06004214 }
4215}
4216
4217void ValidationStateTracker::RecordGetPhysicalDeviceDisplayPlanePropertiesState(VkPhysicalDevice physicalDevice,
4218 uint32_t *pPropertyCount, void *pProperties) {
4219 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4220 if (*pPropertyCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004221 physical_device_state->display_plane_property_count = *pPropertyCount;
4222 }
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004223 if (*pPropertyCount || pProperties) {
4224 physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004225 }
4226}
4227
4228void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
4229 uint32_t *pPropertyCount,
4230 VkDisplayPlanePropertiesKHR *pProperties,
4231 VkResult result) {
4232 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4233 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4234}
4235
4236void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
4237 uint32_t *pPropertyCount,
4238 VkDisplayPlaneProperties2KHR *pProperties,
4239 VkResult result) {
4240 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4241 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4242}
4243
4244void ValidationStateTracker::PostCallRecordCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4245 uint32_t query, VkQueryControlFlags flags, uint32_t index) {
4246 QueryObject query_obj = {queryPool, query, index};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004247 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004248 cb_state->RecordCmd(CMD_BEGINQUERYINDEXEDEXT);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004249 cb_state->BeginQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004250}
4251
4252void ValidationStateTracker::PostCallRecordCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4253 uint32_t query, uint32_t index) {
4254 QueryObject query_obj = {queryPool, query, index};
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004255 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004256 cb_state->RecordCmd(CMD_ENDQUERYINDEXEDEXT);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004257 cb_state->EndQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004258}
4259
4260void ValidationStateTracker::RecordCreateSamplerYcbcrConversionState(const VkSamplerYcbcrConversionCreateInfo *create_info,
4261 VkSamplerYcbcrConversion ycbcr_conversion) {
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004262 VkFormatFeatureFlags format_features = 0;
4263
4264 if (create_info->format != VK_FORMAT_UNDEFINED) {
4265 format_features = GetPotentialFormatFeatures(create_info->format);
4266 } else if (device_extensions.vk_android_external_memory_android_hardware_buffer) {
4267 // If format is VK_FORMAT_UNDEFINED, format_features will be set by external AHB features
4268 format_features = GetExternalFormatFeaturesANDROID(create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004269 }
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004270
4271 samplerYcbcrConversionMap[ycbcr_conversion] =
4272 std::make_shared<SAMPLER_YCBCR_CONVERSION_STATE>(ycbcr_conversion, create_info, format_features);
locke-lunargd556cc32019-09-17 01:21:23 -06004273}
4274
4275void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversion(VkDevice device,
4276 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4277 const VkAllocationCallbacks *pAllocator,
4278 VkSamplerYcbcrConversion *pYcbcrConversion,
4279 VkResult result) {
4280 if (VK_SUCCESS != result) return;
4281 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4282}
4283
4284void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversionKHR(VkDevice device,
4285 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4286 const VkAllocationCallbacks *pAllocator,
4287 VkSamplerYcbcrConversion *pYcbcrConversion,
4288 VkResult result) {
4289 if (VK_SUCCESS != result) return;
4290 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4291}
4292
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004293void ValidationStateTracker::RecordDestroySamplerYcbcrConversionState(VkSamplerYcbcrConversion ycbcr_conversion) {
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004294 auto ycbcr_state = GetSamplerYcbcrConversionState(ycbcr_conversion);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004295 ycbcr_state->Destroy();
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004296 samplerYcbcrConversionMap.erase(ycbcr_conversion);
4297}
4298
locke-lunargd556cc32019-09-17 01:21:23 -06004299void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
4300 const VkAllocationCallbacks *pAllocator) {
4301 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004302 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004303}
4304
4305void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversionKHR(VkDevice device,
4306 VkSamplerYcbcrConversion ycbcrConversion,
4307 const VkAllocationCallbacks *pAllocator) {
4308 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004309 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004310}
4311
Tony-LunarG977448c2019-12-02 14:52:02 -07004312void ValidationStateTracker::RecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4313 uint32_t queryCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004314 // Do nothing if the feature is not enabled.
Piers Daniell41b8c5d2020-01-10 15:42:00 -07004315 if (!enabled_features.core12.hostQueryReset) return;
locke-lunargd556cc32019-09-17 01:21:23 -06004316
4317 // Do nothing if the query pool has been destroyed.
4318 auto query_pool_state = GetQueryPoolState(queryPool);
4319 if (!query_pool_state) return;
4320
4321 // Reset the state of existing entries.
4322 QueryObject query_obj{queryPool, 0};
4323 const uint32_t max_query_count = std::min(queryCount, query_pool_state->createInfo.queryCount - firstQuery);
4324 for (uint32_t i = 0; i < max_query_count; ++i) {
4325 query_obj.query = firstQuery + i;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004326 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004327 if (query_pool_state->createInfo.queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004328 for (uint32_t pass_index = 0; pass_index < query_pool_state->n_performance_passes; pass_index++) {
4329 query_obj.perf_pass = pass_index;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004330 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004331 }
4332 }
locke-lunargd556cc32019-09-17 01:21:23 -06004333 }
4334}
4335
Tony-LunarG977448c2019-12-02 14:52:02 -07004336void ValidationStateTracker::PostCallRecordResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4337 uint32_t queryCount) {
4338 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4339}
4340
4341void ValidationStateTracker::PostCallRecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4342 uint32_t queryCount) {
4343 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4344}
4345
locke-lunargd556cc32019-09-17 01:21:23 -06004346void ValidationStateTracker::PerformUpdateDescriptorSetsWithTemplateKHR(VkDescriptorSet descriptorSet,
4347 const TEMPLATE_STATE *template_state, const void *pData) {
4348 // Translate the templated update into a normal update for validation...
4349 cvdescriptorset::DecodedTemplateUpdate decoded_update(this, descriptorSet, template_state, pData);
4350 cvdescriptorset::PerformUpdateDescriptorSets(this, static_cast<uint32_t>(decoded_update.desc_writes.size()),
4351 decoded_update.desc_writes.data(), 0, NULL);
4352}
4353
4354// Update the common AllocateDescriptorSetsData
4355void ValidationStateTracker::UpdateAllocateDescriptorSetsData(const VkDescriptorSetAllocateInfo *p_alloc_info,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05004356 cvdescriptorset::AllocateDescriptorSetsData *ds_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004357 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05004358 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06004359 if (layout) {
4360 ds_data->layout_nodes[i] = layout;
4361 // Count total descriptors required per type
4362 for (uint32_t j = 0; j < layout->GetBindingCount(); ++j) {
4363 const auto &binding_layout = layout->GetDescriptorSetLayoutBindingPtrFromIndex(j);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004364 uint32_t type_index = static_cast<uint32_t>(binding_layout->descriptorType);
4365 ds_data->required_descriptors_by_type[type_index] += binding_layout->descriptorCount;
locke-lunargd556cc32019-09-17 01:21:23 -06004366 }
4367 }
4368 // Any unknown layouts will be flagged as errors during ValidateAllocateDescriptorSets() call
4369 }
4370}
4371
4372// Decrement allocated sets from the pool and insert new sets into set_map
4373void ValidationStateTracker::PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
4374 const VkDescriptorSet *descriptor_sets,
4375 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) {
4376 auto pool_state = descriptorPoolMap[p_alloc_info->descriptorPool].get();
4377 // Account for sets and individual descriptors allocated from pool
4378 pool_state->availableSets -= p_alloc_info->descriptorSetCount;
4379 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
4380 pool_state->availableDescriptorTypeCount[it->first] -= ds_data->required_descriptors_by_type.at(it->first);
4381 }
4382
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07004383 const auto *variable_count_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(p_alloc_info->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06004384 bool variable_count_valid = variable_count_info && variable_count_info->descriptorSetCount == p_alloc_info->descriptorSetCount;
4385
4386 // Create tracking object for each descriptor set; insert into global map and the pool's set.
4387 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
4388 uint32_t variable_count = variable_count_valid ? variable_count_info->pDescriptorCounts[i] : 0;
4389
Jeff Bolz41a1ced2019-10-11 11:40:49 -05004390 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 -07004391 variable_count, this);
locke-lunargd556cc32019-09-17 01:21:23 -06004392 pool_state->sets.insert(new_ds.get());
locke-lunargd556cc32019-09-17 01:21:23 -06004393 setMap[descriptor_sets[i]] = std::move(new_ds);
4394 }
4395}
4396
locke-lunargd556cc32019-09-17 01:21:23 -06004397void ValidationStateTracker::PostCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
4398 uint32_t firstVertex, uint32_t firstInstance) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004399 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004400 cb_state->UpdateStateCmdDrawType(CMD_DRAW, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDraw()");
locke-lunargd556cc32019-09-17 01:21:23 -06004401}
4402
Tony-LunarG745150c2021-07-02 15:07:31 -06004403void ValidationStateTracker::PostCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4404 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
4405 uint32_t firstInstance, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004406 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004407 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004408}
4409
locke-lunargd556cc32019-09-17 01:21:23 -06004410void ValidationStateTracker::PostCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
4411 uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
4412 uint32_t firstInstance) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004413 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004414 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXED, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexed()");
locke-lunargd556cc32019-09-17 01:21:23 -06004415}
4416
Tony-LunarG745150c2021-07-02 15:07:31 -06004417void ValidationStateTracker::PostCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4418 const VkMultiDrawIndexedInfoEXT *pIndexInfo,
4419 uint32_t instanceCount, uint32_t firstInstance, uint32_t stride,
4420 const int32_t *pVertexOffset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004421 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004422 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIINDEXEDEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiIndexedEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004423}
4424
locke-lunargd556cc32019-09-17 01:21:23 -06004425void ValidationStateTracker::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4426 uint32_t count, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004427 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004428 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004429 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004430 if (!disabled[command_buffer_state]) {
4431 cb_state->AddChild(buffer_state);
4432 }
locke-lunargd556cc32019-09-17 01:21:23 -06004433}
4434
4435void ValidationStateTracker::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4436 VkDeviceSize offset, uint32_t count, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004437 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
locke-lunargd556cc32019-09-17 01:21:23 -06004438 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004439 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexedIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004440 if (!disabled[command_buffer_state]) {
4441 cb_state->AddChild(buffer_state);
4442 }
locke-lunargd556cc32019-09-17 01:21:23 -06004443}
4444
4445void ValidationStateTracker::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004446 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004447 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCH, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatch()");
locke-lunargd556cc32019-09-17 01:21:23 -06004448}
4449
4450void ValidationStateTracker::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4451 VkDeviceSize offset) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004452 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004453 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCHINDIRECT, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatchIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004454 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004455 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004456 cb_state->AddChild(buffer_state);
4457 }
locke-lunargd556cc32019-09-17 01:21:23 -06004458}
4459
Tony-LunarG977448c2019-12-02 14:52:02 -07004460void ValidationStateTracker::RecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4461 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
locke-lunarg540b2252020-08-03 13:23:36 -06004462 uint32_t stride, const char *function) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004463 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004464 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004465 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004466 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4467 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004468 cb_state->AddChild(buffer_state);
4469 cb_state->AddChild(count_buffer_state);
4470 }
Tony-LunarG977448c2019-12-02 14:52:02 -07004471}
4472
locke-lunargd556cc32019-09-17 01:21:23 -06004473void ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4474 VkDeviceSize offset, VkBuffer countBuffer,
4475 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4476 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004477 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4478 "vkCmdDrawIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004479}
4480
4481void ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4482 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
4483 uint32_t maxDrawCount, uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004484 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4485 "vkCmdDrawIndirectCount()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004486}
4487
4488void ValidationStateTracker::RecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4489 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
locke-lunarg540b2252020-08-03 13:23:36 -06004490 uint32_t maxDrawCount, uint32_t stride, const char *function) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004491 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004492 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004493 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004494 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4495 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004496 cb_state->AddChild(buffer_state);
4497 cb_state->AddChild(count_buffer_state);
4498 }
locke-lunargd556cc32019-09-17 01:21:23 -06004499}
4500
4501void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4502 VkDeviceSize offset, VkBuffer countBuffer,
4503 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4504 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004505 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4506 "vkCmdDrawIndexedIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004507}
4508
4509void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
4510 VkDeviceSize offset, VkBuffer countBuffer,
4511 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4512 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004513 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4514 "vkCmdDrawIndexedIndirectCount()");
locke-lunargd556cc32019-09-17 01:21:23 -06004515}
4516
4517void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount,
4518 uint32_t firstTask) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004519 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004520 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSNV, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMeshTasksNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004521}
4522
4523void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4524 VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004525 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004526 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4527 "vkCmdDrawMeshTasksIndirectNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004528 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004529 if (!disabled[command_buffer_state] && buffer_state) {
4530 cb_state->AddChild(buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -06004531 }
4532}
4533
4534void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4535 VkDeviceSize offset, VkBuffer countBuffer,
4536 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4537 uint32_t stride) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004538 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004539 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTCOUNTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4540 "vkCmdDrawMeshTasksIndirectCountNV()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004541 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004542 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4543 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004544 if (buffer_state) {
4545 cb_state->AddChild(buffer_state);
4546 }
4547 if (count_buffer_state) {
4548 cb_state->AddChild(count_buffer_state);
4549 }
locke-lunargd556cc32019-09-17 01:21:23 -06004550 }
4551}
4552
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004553void ValidationStateTracker::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
4554 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
4555 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
4556 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
4557 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
4558 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
4559 uint32_t width, uint32_t height, uint32_t depth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004560 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004561 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSNV, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, "vkCmdTraceRaysNV()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004562 cb_state->hasTraceRaysCmd = true;
4563}
4564
4565
4566void ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
4567 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4568 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4569 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4570 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
4571 uint32_t height, uint32_t depth) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004572 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004573 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, "vkCmdTraceRaysKHR()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004574 cb_state->hasTraceRaysCmd = true;
4575}
4576
4577void ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
4578 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4579 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4580 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4581 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
4582 VkDeviceAddress indirectDeviceAddress) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004583 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004584 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSINDIRECTKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004585 "vkCmdTraceRaysIndirectKHR()");
4586 cb_state->hasTraceRaysCmd = true;
4587}
4588
locke-lunargd556cc32019-09-17 01:21:23 -06004589void ValidationStateTracker::PostCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
4590 const VkAllocationCallbacks *pAllocator,
4591 VkShaderModule *pShaderModule, VkResult result,
4592 void *csm_state_data) {
4593 if (VK_SUCCESS != result) return;
4594 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
4595
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06004596 spv_target_env spirv_environment = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
locke-lunargd556cc32019-09-17 01:21:23 -06004597 bool is_spirv = (pCreateInfo->pCode[0] == spv::MagicNumber);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004598 auto new_shader_module = is_spirv ? std::make_shared<SHADER_MODULE_STATE>(pCreateInfo, *pShaderModule, spirv_environment,
4599 csm_state->unique_shader_id)
4600 : std::make_shared<SHADER_MODULE_STATE>();
sfricke-samsung962cad92021-04-13 00:46:29 -07004601 new_shader_module->SetPushConstantUsedInShader();
locke-lunargd556cc32019-09-17 01:21:23 -06004602 shaderModuleMap[*pShaderModule] = std::move(new_shader_module);
4603}
4604
4605void ValidationStateTracker::RecordPipelineShaderStage(VkPipelineShaderStageCreateInfo const *pStage, PIPELINE_STATE *pipeline,
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06004606 PipelineStageState *stage_state) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004607 // Validation shouldn't rely on anything in stage state being valid if the spirv isn't
locke-lunargde3f0fa2020-09-10 11:55:31 -06004608 stage_state->entry_point_name = pStage->pName;
4609 stage_state->shader_state = GetShared<SHADER_MODULE_STATE>(pStage->module);
4610 auto module = stage_state->shader_state.get();
locke-lunargd556cc32019-09-17 01:21:23 -06004611 if (!module->has_valid_spirv) return;
4612
4613 // Validation shouldn't rely on anything in stage state being valid if the entrypoint isn't present
sfricke-samsung962cad92021-04-13 00:46:29 -07004614 auto entrypoint = module->FindEntrypoint(pStage->pName, pStage->stage);
locke-lunargd556cc32019-09-17 01:21:23 -06004615 if (entrypoint == module->end()) return;
4616
locke-lunarg654e3692020-06-04 17:19:15 -06004617 stage_state->stage_flag = pStage->stage;
4618
locke-lunargd556cc32019-09-17 01:21:23 -06004619 // Mark accessible ids
sfricke-samsung962cad92021-04-13 00:46:29 -07004620 stage_state->accessible_ids = module->MarkAccessibleIds(entrypoint);
4621 module->ProcessExecutionModes(entrypoint, pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06004622
sfricke-samsung962cad92021-04-13 00:46:29 -07004623 stage_state->descriptor_uses = module->CollectInterfaceByDescriptorSlot(
4624 stage_state->accessible_ids, &stage_state->has_writable_descriptor, &stage_state->has_atomic_descriptor);
locke-lunargd556cc32019-09-17 01:21:23 -06004625 // Capture descriptor uses for the pipeline
locke-lunarg36045992020-08-20 16:54:37 -06004626 for (const auto &use : stage_state->descriptor_uses) {
locke-lunargd556cc32019-09-17 01:21:23 -06004627 // While validating shaders capture which slots are used by the pipeline
John Zulauf649edd52019-10-02 14:39:41 -06004628 const uint32_t slot = use.first.first;
locke-lunarg351c9d82020-10-23 14:43:21 -06004629 pipeline->active_slots[slot][use.first.second].is_writable |= use.second.is_writable;
locke-lunarg36045992020-08-20 16:54:37 -06004630 auto &reqs = pipeline->active_slots[slot][use.first.second].reqs;
sfricke-samsung962cad92021-04-13 00:46:29 -07004631 reqs = descriptor_req(reqs | module->DescriptorTypeToReqs(use.second.type_id));
locke-lunarg25b6c352020-08-06 17:44:18 -06004632 if (use.second.is_atomic_operation) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION);
locke-lunarg12d20992020-09-21 12:46:49 -06004633 if (use.second.is_sampler_implicitLod_dref_proj) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ);
locke-lunargae2a43c2020-09-22 17:21:57 -06004634 if (use.second.is_sampler_bias_offset) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET);
locke-lunarg12d20992020-09-21 12:46:49 -06004635
John Zulauf649edd52019-10-02 14:39:41 -06004636 pipeline->max_active_slot = std::max(pipeline->max_active_slot, slot);
locke-lunarg36045992020-08-20 16:54:37 -06004637 if (use.second.samplers_used_by_image.size()) {
locke-lunarg654a9052020-10-13 16:28:42 -06004638 auto &samplers_used_by_image = pipeline->active_slots[slot][use.first.second].samplers_used_by_image;
4639 if (use.second.samplers_used_by_image.size() > samplers_used_by_image.size()) {
4640 samplers_used_by_image.resize(use.second.samplers_used_by_image.size());
4641 }
locke-lunarg654a9052020-10-13 16:28:42 -06004642 uint32_t image_index = 0;
4643 for (const auto &samplers : use.second.samplers_used_by_image) {
4644 for (const auto &sampler : samplers) {
locke-lunargb8be8222020-10-20 00:34:37 -06004645 samplers_used_by_image[image_index].emplace(sampler, nullptr);
locke-lunarg654a9052020-10-13 16:28:42 -06004646 }
4647 ++image_index;
4648 }
locke-lunarg36045992020-08-20 16:54:37 -06004649 }
locke-lunargd556cc32019-09-17 01:21:23 -06004650 }
locke-lunarg78486832020-09-09 19:39:42 -06004651
locke-lunarg96dc9632020-06-10 17:22:18 -06004652 if (pStage->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
sfricke-samsung962cad92021-04-13 00:46:29 -07004653 pipeline->fragmentShader_writable_output_location_list = module->CollectWritableOutputLocationinFS(*pStage);
locke-lunarg96dc9632020-06-10 17:22:18 -06004654 }
locke-lunargd556cc32019-09-17 01:21:23 -06004655}
4656
John Zulauf22b0fbe2019-10-15 06:26:16 -06004657void ValidationStateTracker::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
4658 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages,
4659 VkResult result) {
4660 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004661 auto swapchain_state = GetShared<SWAPCHAIN_NODE>(swapchain);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004662
4663 if (*pSwapchainImageCount > swapchain_state->images.size()) swapchain_state->images.resize(*pSwapchainImageCount);
4664
4665 if (pSwapchainImages) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004666 for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
John Zulauf29d00532021-03-04 13:28:54 -07004667 SWAPCHAIN_IMAGE &swapchain_image = swapchain_state->images[i];
John Zulauffaa7a522021-03-05 12:22:45 -07004668 if (swapchain_image.image_state) continue; // Already retrieved this.
John Zulauf22b0fbe2019-10-15 06:26:16 -06004669
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004670 auto format_features =
4671 GetImageFormatFeatures(physical_device, device, pSwapchainImages[i], swapchain_state->image_create_info.format,
4672 swapchain_state->image_create_info.tiling);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004673
Jeremy Gebbenbcba6d32021-07-16 11:41:41 -06004674 auto image_state = std::make_shared<IMAGE_STATE>(device, pSwapchainImages[i], swapchain_state->image_create_info.ptr(),
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004675 swapchain, i, format_features);
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004676 if (!swapchain_image.fake_base_address) {
4677 auto size = image_state->fragment_encoder->TotalSize();
4678 swapchain_image.fake_base_address = fake_memory.Alloc(size);
John Zulauf29d00532021-03-04 13:28:54 -07004679 }
4680
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004681 image_state->SetSwapchain(swapchain_state, i);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004682 swapchain_image.image_state = image_state.get();
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004683 imageMap[pSwapchainImages[i]] = std::move(image_state);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004684 }
4685 }
4686
4687 if (*pSwapchainImageCount) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004688 swapchain_state->get_swapchain_image_count = *pSwapchainImageCount;
4689 }
4690}
sourav parmar35e7a002020-06-09 17:58:44 -07004691
sourav parmar35e7a002020-06-09 17:58:44 -07004692void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer,
4693 const VkCopyAccelerationStructureInfoKHR *pInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004694 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
sourav parmar35e7a002020-06-09 17:58:44 -07004695 if (cb_state) {
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004696 cb_state->RecordCmd(CMD_COPYACCELERATIONSTRUCTUREKHR);
sourav parmarcd5fb182020-07-17 12:58:44 -07004697 ACCELERATION_STRUCTURE_STATE_KHR *src_as_state = GetAccelerationStructureStateKHR(pInfo->src);
4698 ACCELERATION_STRUCTURE_STATE_KHR *dst_as_state = GetAccelerationStructureStateKHR(pInfo->dst);
sourav parmar35e7a002020-06-09 17:58:44 -07004699 if (dst_as_state != nullptr && src_as_state != nullptr) {
4700 dst_as_state->built = true;
4701 dst_as_state->build_info_khr = src_as_state->build_info_khr;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004702 if (!disabled[command_buffer_state]) {
4703 cb_state->AddChild(dst_as_state);
4704 cb_state->AddChild(src_as_state);
4705 }
sourav parmar35e7a002020-06-09 17:58:44 -07004706 }
4707 }
4708}
Piers Daniell39842ee2020-07-10 16:42:33 -06004709
4710void ValidationStateTracker::PreCallRecordCmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004711 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004712 cb_state->RecordStateCmd(CMD_SETCULLMODEEXT, CBSTATUS_CULL_MODE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004713}
4714
4715void ValidationStateTracker::PreCallRecordCmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004716 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004717 cb_state->RecordStateCmd(CMD_SETFRONTFACEEXT, CBSTATUS_FRONT_FACE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004718}
4719
4720void ValidationStateTracker::PreCallRecordCmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
4721 VkPrimitiveTopology primitiveTopology) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004722 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004723 cb_state->RecordStateCmd(CMD_SETPRIMITIVETOPOLOGYEXT, CBSTATUS_PRIMITIVE_TOPOLOGY_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004724 cb_state->primitiveTopology = primitiveTopology;
Piers Daniell39842ee2020-07-10 16:42:33 -06004725}
4726
4727void ValidationStateTracker::PreCallRecordCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer, uint32_t viewportCount,
4728 const VkViewport *pViewports) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004729 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004730 cb_state->RecordStateCmd(CMD_SETVIEWPORTWITHCOUNTEXT, CBSTATUS_VIEWPORT_WITH_COUNT_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004731 uint32_t bits = (1u << viewportCount) - 1u;
4732 cb_state->viewportWithCountMask |= bits;
4733 cb_state->trashedViewportMask &= ~bits;
Tobias Hector6663c9b2020-11-05 10:18:02 +00004734 cb_state->viewportWithCountCount = viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004735 cb_state->trashedViewportCount = false;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004736
4737 cb_state->dynamicViewports.resize(std::max(size_t(viewportCount), cb_state->dynamicViewports.size()));
4738 for (size_t i = 0; i < viewportCount; ++i) {
4739 cb_state->dynamicViewports[i] = pViewports[i];
4740 }
Piers Daniell39842ee2020-07-10 16:42:33 -06004741}
4742
4743void ValidationStateTracker::PreCallRecordCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount,
4744 const VkRect2D *pScissors) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004745 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004746 cb_state->RecordStateCmd(CMD_SETSCISSORWITHCOUNTEXT, CBSTATUS_SCISSOR_WITH_COUNT_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004747 uint32_t bits = (1u << scissorCount) - 1u;
4748 cb_state->scissorWithCountMask |= bits;
4749 cb_state->trashedScissorMask &= ~bits;
4750 cb_state->scissorWithCountCount = scissorCount;
4751 cb_state->trashedScissorCount = false;
Piers Daniell39842ee2020-07-10 16:42:33 -06004752}
4753
4754void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
4755 uint32_t bindingCount, const VkBuffer *pBuffers,
4756 const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes,
4757 const VkDeviceSize *pStrides) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004758 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004759 cb_state->RecordStateCmd(CMD_BINDVERTEXBUFFERS2EXT, pStrides ? CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET : CBSTATUS_NONE);
Piers Daniell39842ee2020-07-10 16:42:33 -06004760
4761 uint32_t end = firstBinding + bindingCount;
4762 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
4763 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
4764 }
4765
4766 for (uint32_t i = 0; i < bindingCount; ++i) {
4767 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07004768 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
Piers Daniell39842ee2020-07-10 16:42:33 -06004769 vertex_buffer_binding.offset = pOffsets[i];
4770 vertex_buffer_binding.size = (pSizes) ? pSizes[i] : VK_WHOLE_SIZE;
4771 vertex_buffer_binding.stride = (pStrides) ? pStrides[i] : 0;
4772 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004773 if (!disabled[command_buffer_state] && pBuffers[i]) {
4774 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Piers Daniell39842ee2020-07-10 16:42:33 -06004775 }
4776 }
4777}
4778
4779void ValidationStateTracker::PreCallRecordCmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
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_SETDEPTHTESTENABLEEXT, CBSTATUS_DEPTH_TEST_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004782}
4783
4784void ValidationStateTracker::PreCallRecordCmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004785 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004786 cb_state->RecordStateCmd(CMD_SETDEPTHWRITEENABLEEXT, CBSTATUS_DEPTH_WRITE_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004787}
4788
4789void ValidationStateTracker::PreCallRecordCmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004790 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004791 cb_state->RecordStateCmd(CMD_SETDEPTHCOMPAREOPEXT, CBSTATUS_DEPTH_COMPARE_OP_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004792}
4793
4794void ValidationStateTracker::PreCallRecordCmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,
4795 VkBool32 depthBoundsTestEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004796 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004797 cb_state->RecordStateCmd(CMD_SETDEPTHBOUNDSTESTENABLEEXT, CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004798}
4799void ValidationStateTracker::PreCallRecordCmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
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_SETSTENCILTESTENABLEEXT, CBSTATUS_STENCIL_TEST_ENABLE_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004802}
4803
4804void ValidationStateTracker::PreCallRecordCmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
4805 VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
4806 VkCompareOp compareOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004807 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004808 cb_state->RecordStateCmd(CMD_SETSTENCILOPEXT, CBSTATUS_STENCIL_OP_SET);
Piers Daniell39842ee2020-07-10 16:42:33 -06004809}
locke-lunarg4189aa22020-10-21 00:23:48 -06004810
4811void ValidationStateTracker::PreCallRecordCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle,
4812 uint32_t discardRectangleCount,
4813 const VkRect2D *pDiscardRectangles) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004814 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004815 cb_state->RecordStateCmd(CMD_SETDISCARDRECTANGLEEXT, CBSTATUS_DISCARD_RECTANGLE_SET);
locke-lunarg4189aa22020-10-21 00:23:48 -06004816}
4817
4818void ValidationStateTracker::PreCallRecordCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
4819 const VkSampleLocationsInfoEXT *pSampleLocationsInfo) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004820 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004821 cb_state->RecordStateCmd(CMD_SETSAMPLELOCATIONSEXT, CBSTATUS_SAMPLE_LOCATIONS_SET);
locke-lunarg4189aa22020-10-21 00:23:48 -06004822}
4823
4824void ValidationStateTracker::PreCallRecordCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer,
4825 VkCoarseSampleOrderTypeNV sampleOrderType,
4826 uint32_t customSampleOrderCount,
4827 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004828 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004829 cb_state->RecordStateCmd(CMD_SETCOARSESAMPLEORDERNV, CBSTATUS_COARSE_SAMPLE_ORDER_SET);
locke-lunarg4189aa22020-10-21 00:23:48 -06004830}
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004831
4832void ValidationStateTracker::PreCallRecordCmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, uint32_t patchControlPoints) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004833 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004834 cb_state->RecordStateCmd(CMD_SETPATCHCONTROLPOINTSEXT, CBSTATUS_PATCH_CONTROL_POINTS_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004835}
4836
4837void ValidationStateTracker::PreCallRecordCmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004838 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004839 cb_state->RecordStateCmd(CMD_SETLOGICOPEXT, CBSTATUS_LOGIC_OP_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004840}
4841
4842void ValidationStateTracker::PreCallRecordCmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
4843 VkBool32 rasterizerDiscardEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004844 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004845 cb_state->RecordStateCmd(CMD_SETRASTERIZERDISCARDENABLEEXT, CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004846}
4847
4848void ValidationStateTracker::PreCallRecordCmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004849 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004850 cb_state->RecordStateCmd(CMD_SETDEPTHBIASENABLEEXT, CBSTATUS_DEPTH_BIAS_ENABLE_SET);
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07004851}
4852
4853void ValidationStateTracker::PreCallRecordCmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,
4854 VkBool32 primitiveRestartEnable) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004855 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -06004856 cb_state->RecordStateCmd(CMD_SETPRIMITIVERESTARTENABLEEXT, CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004857}
Piers Daniell924cd832021-05-18 13:48:47 -06004858
4859void ValidationStateTracker::PreCallRecordCmdSetVertexInputEXT(
4860 VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount,
4861 const VkVertexInputBindingDescription2EXT *pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount,
4862 const VkVertexInputAttributeDescription2EXT *pVertexAttributeDescriptions) {
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004863 CMD_BUFFER_STATE *cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
ziga-lunarg4af0a8c2021-08-27 15:53:20 +02004864 CBStatusFlags status_flags = CBSTATUS_VERTEX_INPUT_SET;
4865
4866 const auto lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS);
4867 const auto pipeline_state = cb_state->lastBound[lv_bind_point].pipeline_state;
4868 if (pipeline_state) {
4869 if (pipeline_state->graphicsPipelineCI.pDynamicState) {
4870 for (uint32_t i = 0; i < pipeline_state->graphicsPipelineCI.pDynamicState->dynamicStateCount; ++i) {
4871 if (pipeline_state->graphicsPipelineCI.pDynamicState->pDynamicStates[i] ==
4872 VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT) {
4873 status_flags |= CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET;
4874 break;
4875 }
4876 }
4877 }
4878 }
4879 cb_state->RecordStateCmd(CMD_SETVERTEXINPUTEXT, status_flags);
Piers Daniell924cd832021-05-18 13:48:47 -06004880}
Nathaniel Cesario42ac6ca2021-06-15 17:23:05 -06004881
4882void ValidationStateTracker::RecordGetBufferDeviceAddress(const VkBufferDeviceAddressInfo *pInfo, VkDeviceAddress address) {
4883 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
4884 if (buffer_state) {
4885 // address is used for GPU-AV and ray tracing buffer validation
4886 buffer_state->deviceAddress = address;
4887 buffer_address_map_.emplace(address, buffer_state);
4888 }
4889}
4890
4891void ValidationStateTracker::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
4892 VkDeviceAddress address) {
4893 RecordGetBufferDeviceAddress(pInfo, address);
4894}
4895
4896void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
4897 VkDeviceAddress address) {
4898 RecordGetBufferDeviceAddress(pInfo, address);
4899}
4900
4901void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
4902 VkDeviceAddress address) {
4903 RecordGetBufferDeviceAddress(pInfo, address);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06004904}
4905
4906std::shared_ptr<SWAPCHAIN_NODE> ValidationStateTracker::CreateSwapchainState(const VkSwapchainCreateInfoKHR *create_info,
4907 VkSwapchainKHR swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004908 return std::make_shared<SWAPCHAIN_NODE>(this, create_info, swapchain);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06004909}
Jeremy Gebben3d22d582021-08-11 15:37:58 -06004910
4911std::shared_ptr<CMD_BUFFER_STATE> ValidationStateTracker::CreateCmdBufferState(VkCommandBuffer cb,
4912 const VkCommandBufferAllocateInfo *create_info,
4913 std::shared_ptr<COMMAND_POOL_STATE> &pool) {
4914 return std::make_shared<CMD_BUFFER_STATE>(this, cb, create_info, pool);
4915}