blob: e8b8306f7d8689353db6800b67192743ede94ddf [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];
190
191 if (device_extensions.vk_khr_get_memory_requirements2) {
192 DispatchGetImageMemoryRequirements2KHR(device, &mem_req_info2, &mem_reqs2);
193 } else {
194 DispatchGetImageMemoryRequirements2(device, &mem_req_info2, &mem_reqs2);
195 }
196 is_node->requirements[i] = mem_reqs2.memoryRequirements;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -0700197 }
198 }
locke-lunargd556cc32019-09-17 01:21:23 -0600199 }
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700200
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600201 imageMap[*pImage] = std::move(is_node);
locke-lunargd556cc32019-09-17 01:21:23 -0600202}
203
204void ValidationStateTracker::PreCallRecordDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
205 if (!image) return;
206 IMAGE_STATE *image_state = GetImageState(image);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600207 if (!image_state) return;
208
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600209 image_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600210 imageMap.erase(image);
211}
212
213void ValidationStateTracker::PreCallRecordCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
214 VkImageLayout imageLayout, const VkClearColorValue *pColor,
215 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600216
217 if (disabled[command_buffer_state]) return;
218
locke-lunargd556cc32019-09-17 01:21:23 -0600219 auto cb_node = GetCBState(commandBuffer);
220 auto image_state = GetImageState(image);
221 if (cb_node && image_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600222 cb_node->AddChild(image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600223 }
224}
225
226void ValidationStateTracker::PreCallRecordCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
227 VkImageLayout imageLayout,
228 const VkClearDepthStencilValue *pDepthStencil,
229 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600230 if (disabled[command_buffer_state]) return;
231
locke-lunargd556cc32019-09-17 01:21:23 -0600232 auto cb_node = GetCBState(commandBuffer);
233 auto image_state = GetImageState(image);
234 if (cb_node && image_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600235 cb_node->AddChild(image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600236 }
237}
238
239void ValidationStateTracker::PreCallRecordCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
240 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
241 uint32_t regionCount, const VkImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600242 if (disabled[command_buffer_state]) return;
243
locke-lunargd556cc32019-09-17 01:21:23 -0600244 auto cb_node = GetCBState(commandBuffer);
245 auto src_image_state = GetImageState(srcImage);
246 auto dst_image_state = GetImageState(dstImage);
247
248 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600249 cb_node->AddChild(src_image_state);
250 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600251}
252
Jeff Leger178b1e52020-10-05 12:22:23 -0400253void ValidationStateTracker::PreCallRecordCmdCopyImage2KHR(VkCommandBuffer commandBuffer,
254 const VkCopyImageInfo2KHR *pCopyImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600255 if (disabled[command_buffer_state]) return;
256
Jeff Leger178b1e52020-10-05 12:22:23 -0400257 auto cb_node = GetCBState(commandBuffer);
258 auto src_image_state = GetImageState(pCopyImageInfo->srcImage);
259 auto dst_image_state = GetImageState(pCopyImageInfo->dstImage);
260
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600261 cb_node->AddChild(src_image_state);
262 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400263}
264
locke-lunargd556cc32019-09-17 01:21:23 -0600265void ValidationStateTracker::PreCallRecordCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
266 VkImageLayout srcImageLayout, VkImage dstImage,
267 VkImageLayout dstImageLayout, uint32_t regionCount,
268 const VkImageResolve *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600269 if (disabled[command_buffer_state]) return;
270
locke-lunargd556cc32019-09-17 01:21:23 -0600271 auto cb_node = GetCBState(commandBuffer);
272 auto src_image_state = GetImageState(srcImage);
273 auto dst_image_state = GetImageState(dstImage);
274
275 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600276 cb_node->AddChild(src_image_state);
277 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600278}
279
Jeff Leger178b1e52020-10-05 12:22:23 -0400280void ValidationStateTracker::PreCallRecordCmdResolveImage2KHR(VkCommandBuffer commandBuffer,
281 const VkResolveImageInfo2KHR *pResolveImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600282 if (disabled[command_buffer_state]) return;
283
Jeff Leger178b1e52020-10-05 12:22:23 -0400284 auto cb_node = GetCBState(commandBuffer);
285 auto src_image_state = GetImageState(pResolveImageInfo->srcImage);
286 auto dst_image_state = GetImageState(pResolveImageInfo->dstImage);
287
288 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600289 cb_node->AddChild(src_image_state);
290 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400291}
292
locke-lunargd556cc32019-09-17 01:21:23 -0600293void ValidationStateTracker::PreCallRecordCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
294 VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
295 uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600296 if (disabled[command_buffer_state]) return;
297
locke-lunargd556cc32019-09-17 01:21:23 -0600298 auto cb_node = GetCBState(commandBuffer);
299 auto src_image_state = GetImageState(srcImage);
300 auto dst_image_state = GetImageState(dstImage);
301
302 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600303 cb_node->AddChild(src_image_state);
304 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600305}
306
Jeff Leger178b1e52020-10-05 12:22:23 -0400307void ValidationStateTracker::PreCallRecordCmdBlitImage2KHR(VkCommandBuffer commandBuffer,
308 const VkBlitImageInfo2KHR *pBlitImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600309 if (disabled[command_buffer_state]) return;
310
Jeff Leger178b1e52020-10-05 12:22:23 -0400311 auto cb_node = GetCBState(commandBuffer);
312 auto src_image_state = GetImageState(pBlitImageInfo->srcImage);
313 auto dst_image_state = GetImageState(pBlitImageInfo->dstImage);
314
315 // Update bindings between images and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600316 cb_node->AddChild(src_image_state);
317 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400318}
319
locke-lunargd556cc32019-09-17 01:21:23 -0600320void ValidationStateTracker::PostCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
321 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer,
322 VkResult result) {
323 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600324
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500325 auto buffer_state = std::make_shared<BUFFER_STATE>(*pBuffer, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -0600326
James Rumble2f6e7bb2021-07-13 15:21:20 +0100327 if (pCreateInfo) {
328 const auto *opaque_capture_address = LvlFindInChain<VkBufferOpaqueCaptureAddressCreateInfo>(pCreateInfo->pNext);
329 if (opaque_capture_address) {
330 // address is used for GPU-AV and ray tracing buffer validation
331 buffer_state->deviceAddress = opaque_capture_address->opaqueCaptureAddress;
332 buffer_address_map_.emplace(opaque_capture_address->opaqueCaptureAddress, buffer_state.get());
333 }
334 }
335
locke-lunargd556cc32019-09-17 01:21:23 -0600336 // Get a set of requirements in the case the app does not
sfricke-samsungad90e722020-07-08 20:54:24 -0700337 DispatchGetBufferMemoryRequirements(device, *pBuffer, &buffer_state->requirements);
locke-lunargd556cc32019-09-17 01:21:23 -0600338
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700339 bufferMap.emplace(*pBuffer, std::move(buffer_state));
locke-lunargd556cc32019-09-17 01:21:23 -0600340}
341
342void ValidationStateTracker::PostCallRecordCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
343 const VkAllocationCallbacks *pAllocator, VkBufferView *pView,
344 VkResult result) {
345 if (result != VK_SUCCESS) return;
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600346
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500347 auto buffer_state = GetBufferShared(pCreateInfo->buffer);
locke-lunarg25b6c352020-08-06 17:44:18 -0600348
349 VkFormatProperties format_properties;
350 DispatchGetPhysicalDeviceFormatProperties(physical_device, pCreateInfo->format, &format_properties);
locke-lunarg25b6c352020-08-06 17:44:18 -0600351
Jeremy Gebbenf2912cd2021-07-07 07:57:39 -0600352 bufferViewMap[*pView] =
353 std::make_shared<BUFFER_VIEW_STATE>(buffer_state, *pView, pCreateInfo, format_properties.bufferFeatures);
locke-lunargd556cc32019-09-17 01:21:23 -0600354}
355
356void ValidationStateTracker::PostCallRecordCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
357 const VkAllocationCallbacks *pAllocator, VkImageView *pView,
358 VkResult result) {
359 if (result != VK_SUCCESS) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500360 auto image_state = GetImageShared(pCreateInfo->image);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700361
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600362 VkFormatFeatureFlags format_features = 0;
363 if (image_state->HasAHBFormat() == true) {
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700364 // The ImageView uses same Image's format feature since they share same AHB
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600365 format_features = image_state->format_features;
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700366 } else {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600367 format_features = GetImageFormatFeatures(physical_device, device, image_state->image(), pCreateInfo->format,
368 image_state->createInfo.tiling);
Spencer Fricke6bba8c72020-04-06 07:41:21 -0700369 }
370
locke-lunarg9939d4b2020-10-26 20:11:08 -0600371 // 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 -0600372 auto filter_cubic_props = LvlInitStruct<VkFilterCubicImageViewImageFormatPropertiesEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600373 if (IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700374 auto imageview_format_info = LvlInitStruct<VkPhysicalDeviceImageViewImageFormatInfoEXT>();
locke-lunarg9939d4b2020-10-26 20:11:08 -0600375 imageview_format_info.imageViewType = pCreateInfo->viewType;
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -0700376 auto image_format_info = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>(&imageview_format_info);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600377 image_format_info.type = image_state->createInfo.imageType;
378 image_format_info.format = image_state->createInfo.format;
379 image_format_info.tiling = image_state->createInfo.tiling;
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600380 auto usage_create_info = LvlFindInChain<VkImageViewUsageCreateInfo>(pCreateInfo->pNext);
381 image_format_info.usage = usage_create_info ? usage_create_info->usage : image_state->createInfo.usage;
locke-lunarg9939d4b2020-10-26 20:11:08 -0600382 image_format_info.flags = image_state->createInfo.flags;
383
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600384 auto image_format_properties = LvlInitStruct<VkImageFormatProperties2>(&filter_cubic_props);
locke-lunarg9939d4b2020-10-26 20:11:08 -0600385
386 DispatchGetPhysicalDeviceImageFormatProperties2(physical_device, &image_format_info, &image_format_properties);
387 }
Jeremy Gebbenb4d17012021-07-08 13:18:15 -0600388
389 imageViewMap[*pView] =
390 std::make_shared<IMAGE_VIEW_STATE>(image_state, *pView, pCreateInfo, format_features, filter_cubic_props);
locke-lunargd556cc32019-09-17 01:21:23 -0600391}
392
393void ValidationStateTracker::PreCallRecordCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
394 uint32_t regionCount, const VkBufferCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600395 if (disabled[command_buffer_state]) return;
396
locke-lunargd556cc32019-09-17 01:21:23 -0600397 auto cb_node = GetCBState(commandBuffer);
398 auto src_buffer_state = GetBufferState(srcBuffer);
399 auto dst_buffer_state = GetBufferState(dstBuffer);
400
401 // Update bindings between buffers and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600402 cb_node->AddChild(src_buffer_state);
403 cb_node->AddChild(dst_buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600404}
405
Jeff Leger178b1e52020-10-05 12:22:23 -0400406void ValidationStateTracker::PreCallRecordCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
407 const VkCopyBufferInfo2KHR *pCopyBufferInfos) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600408 if (disabled[command_buffer_state]) return;
409
Jeff Leger178b1e52020-10-05 12:22:23 -0400410 auto cb_node = GetCBState(commandBuffer);
411 auto src_buffer_state = GetBufferState(pCopyBufferInfos->srcBuffer);
412 auto dst_buffer_state = GetBufferState(pCopyBufferInfos->dstBuffer);
413
414 // Update bindings between buffers and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600415 cb_node->AddChild(src_buffer_state);
416 cb_node->AddChild(dst_buffer_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400417}
418
locke-lunargd556cc32019-09-17 01:21:23 -0600419void ValidationStateTracker::PreCallRecordDestroyImageView(VkDevice device, VkImageView imageView,
420 const VkAllocationCallbacks *pAllocator) {
421 IMAGE_VIEW_STATE *image_view_state = GetImageViewState(imageView);
422 if (!image_view_state) return;
locke-lunargd556cc32019-09-17 01:21:23 -0600423
424 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600425 image_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600426 imageViewMap.erase(imageView);
427}
428
429void ValidationStateTracker::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
430 if (!buffer) return;
431 auto buffer_state = GetBufferState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -0600432
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600433 buffer_state->Destroy();
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600434 bufferMap.erase(buffer_state->buffer());
locke-lunargd556cc32019-09-17 01:21:23 -0600435}
436
437void ValidationStateTracker::PreCallRecordDestroyBufferView(VkDevice device, VkBufferView bufferView,
438 const VkAllocationCallbacks *pAllocator) {
439 if (!bufferView) return;
440 auto buffer_view_state = GetBufferViewState(bufferView);
locke-lunargd556cc32019-09-17 01:21:23 -0600441
442 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600443 buffer_view_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -0600444 bufferViewMap.erase(bufferView);
445}
446
447void ValidationStateTracker::PreCallRecordCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
448 VkDeviceSize size, uint32_t data) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600449 if (disabled[command_buffer_state]) return;
450
locke-lunargd556cc32019-09-17 01:21:23 -0600451 auto cb_node = GetCBState(commandBuffer);
452 auto buffer_state = GetBufferState(dstBuffer);
453 // Update bindings between buffer and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600454 cb_node->AddChild(buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600455}
456
457void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
458 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
459 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600460 if (disabled[command_buffer_state]) return;
461
locke-lunargd556cc32019-09-17 01:21:23 -0600462 auto cb_node = GetCBState(commandBuffer);
463 auto src_image_state = GetImageState(srcImage);
464 auto dst_buffer_state = GetBufferState(dstBuffer);
465
466 // Update bindings between buffer/image and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600467 cb_node->AddChild(src_image_state);
468 cb_node->AddChild(dst_buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600469}
470
Jeff Leger178b1e52020-10-05 12:22:23 -0400471void ValidationStateTracker::PreCallRecordCmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
472 const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600473 if (disabled[command_buffer_state]) return;
474
Jeff Leger178b1e52020-10-05 12:22:23 -0400475 auto cb_node = GetCBState(commandBuffer);
476 auto src_image_state = GetImageState(pCopyImageToBufferInfo->srcImage);
477 auto dst_buffer_state = GetBufferState(pCopyImageToBufferInfo->dstBuffer);
478
479 // Update bindings between buffer/image and cmd buffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600480 cb_node->AddChild(src_image_state);
481 cb_node->AddChild(dst_buffer_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400482}
483
locke-lunargd556cc32019-09-17 01:21:23 -0600484void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
485 VkImageLayout dstImageLayout, uint32_t regionCount,
486 const VkBufferImageCopy *pRegions) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600487 if (disabled[command_buffer_state]) return;
488
locke-lunargd556cc32019-09-17 01:21:23 -0600489 auto cb_node = GetCBState(commandBuffer);
490 auto src_buffer_state = GetBufferState(srcBuffer);
491 auto dst_image_state = GetImageState(dstImage);
492
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600493 cb_node->AddChild(src_buffer_state);
494 cb_node->AddChild(dst_image_state);
locke-lunargd556cc32019-09-17 01:21:23 -0600495}
496
Jeff Leger178b1e52020-10-05 12:22:23 -0400497void ValidationStateTracker::PreCallRecordCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
498 const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600499
500 if (disabled[command_buffer_state]) return;
501
Jeff Leger178b1e52020-10-05 12:22:23 -0400502 auto cb_node = GetCBState(commandBuffer);
503 auto src_buffer_state = GetBufferState(pCopyBufferToImageInfo->srcBuffer);
504 auto dst_image_state = GetImageState(pCopyBufferToImageInfo->dstImage);
505
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600506 cb_node->AddChild(src_buffer_state);
507 cb_node->AddChild(dst_image_state);
Jeff Leger178b1e52020-10-05 12:22:23 -0400508}
509
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600510QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) {
511 auto it = queueMap.find(queue);
512 if (it == queueMap.end()) {
513 return nullptr;
514 }
515 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600516}
517
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600518const QUEUE_STATE *ValidationStateTracker::GetQueueState(VkQueue queue) const {
519 auto it = queueMap.find(queue);
520 if (it == queueMap.cend()) {
521 return nullptr;
522 }
523 return &it->second;
locke-lunargd556cc32019-09-17 01:21:23 -0600524}
525
locke-lunargd556cc32019-09-17 01:21:23 -0600526const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) const {
527 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
528 auto it = phys_dev_map->find(phys);
529 if (it == phys_dev_map->end()) {
530 return nullptr;
531 }
532 return &it->second;
533}
534
535PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState(VkPhysicalDevice phys) {
536 auto *phys_dev_map = ((physical_device_map.size() > 0) ? &physical_device_map : &instance_state->physical_device_map);
537 auto it = phys_dev_map->find(phys);
538 if (it == phys_dev_map->end()) {
539 return nullptr;
540 }
541 return &it->second;
542}
543
544PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() { return physical_device_state; }
545const PHYSICAL_DEVICE_STATE *ValidationStateTracker::GetPhysicalDeviceState() const { return physical_device_state; }
546
547// Return ptr to memory binding for given handle of specified type
548template <typename State, typename Result>
549static Result GetObjectMemBindingImpl(State state, const VulkanTypedHandle &typed_handle) {
550 switch (typed_handle.type) {
551 case kVulkanObjectTypeImage:
552 return state->GetImageState(typed_handle.Cast<VkImage>());
553 case kVulkanObjectTypeBuffer:
554 return state->GetBufferState(typed_handle.Cast<VkBuffer>());
555 case kVulkanObjectTypeAccelerationStructureNV:
sourav parmarcd5fb182020-07-17 12:58:44 -0700556 return state->GetAccelerationStructureStateNV(typed_handle.Cast<VkAccelerationStructureNV>());
locke-lunargd556cc32019-09-17 01:21:23 -0600557 default:
558 break;
559 }
560 return nullptr;
561}
562
563const BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) const {
564 return GetObjectMemBindingImpl<const ValidationStateTracker *, const BINDABLE *>(this, typed_handle);
565}
566
567BINDABLE *ValidationStateTracker::GetObjectMemBinding(const VulkanTypedHandle &typed_handle) {
568 return GetObjectMemBindingImpl<ValidationStateTracker *, BINDABLE *>(this, typed_handle);
569}
570
locke-lunargd556cc32019-09-17 01:21:23 -0600571// Remove set from setMap and delete the set
572void ValidationStateTracker::FreeDescriptorSet(cvdescriptorset::DescriptorSet *descriptor_set) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500573 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600574 descriptor_set->Destroy();
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500575
locke-lunargd556cc32019-09-17 01:21:23 -0600576 setMap.erase(descriptor_set->GetSet());
577}
578
579// Free all DS Pools including their Sets & related sub-structs
580// NOTE : Calls to this function should be wrapped in mutex
581void ValidationStateTracker::DeleteDescriptorSetPools() {
582 for (auto ii = descriptorPoolMap.begin(); ii != descriptorPoolMap.end();) {
583 // Remove this pools' sets from setMap and delete them
John Zulauf79f06582021-02-27 18:38:39 -0700584 for (auto *ds : ii->second->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -0600585 FreeDescriptorSet(ds);
586 }
587 ii->second->sets.clear();
588 ii = descriptorPoolMap.erase(ii);
589 }
590}
591
592// For given object struct return a ptr of BASE_NODE type for its wrapping struct
593BASE_NODE *ValidationStateTracker::GetStateStructPtrFromObject(const VulkanTypedHandle &object_struct) {
Jeff Bolzadbfa852019-10-04 13:53:30 -0500594 if (object_struct.node) {
595#ifdef _DEBUG
596 // assert that lookup would find the same object
597 VulkanTypedHandle other = object_struct;
598 other.node = nullptr;
599 assert(object_struct.node == GetStateStructPtrFromObject(other));
600#endif
601 return object_struct.node;
602 }
locke-lunargd556cc32019-09-17 01:21:23 -0600603 BASE_NODE *base_ptr = nullptr;
604 switch (object_struct.type) {
605 case kVulkanObjectTypeDescriptorSet: {
606 base_ptr = GetSetNode(object_struct.Cast<VkDescriptorSet>());
607 break;
608 }
609 case kVulkanObjectTypeSampler: {
610 base_ptr = GetSamplerState(object_struct.Cast<VkSampler>());
611 break;
612 }
613 case kVulkanObjectTypeQueryPool: {
614 base_ptr = GetQueryPoolState(object_struct.Cast<VkQueryPool>());
615 break;
616 }
617 case kVulkanObjectTypePipeline: {
618 base_ptr = GetPipelineState(object_struct.Cast<VkPipeline>());
619 break;
620 }
621 case kVulkanObjectTypeBuffer: {
622 base_ptr = GetBufferState(object_struct.Cast<VkBuffer>());
623 break;
624 }
625 case kVulkanObjectTypeBufferView: {
626 base_ptr = GetBufferViewState(object_struct.Cast<VkBufferView>());
627 break;
628 }
629 case kVulkanObjectTypeImage: {
630 base_ptr = GetImageState(object_struct.Cast<VkImage>());
631 break;
632 }
633 case kVulkanObjectTypeImageView: {
634 base_ptr = GetImageViewState(object_struct.Cast<VkImageView>());
635 break;
636 }
637 case kVulkanObjectTypeEvent: {
638 base_ptr = GetEventState(object_struct.Cast<VkEvent>());
639 break;
640 }
641 case kVulkanObjectTypeDescriptorPool: {
642 base_ptr = GetDescriptorPoolState(object_struct.Cast<VkDescriptorPool>());
643 break;
644 }
645 case kVulkanObjectTypeCommandPool: {
646 base_ptr = GetCommandPoolState(object_struct.Cast<VkCommandPool>());
647 break;
648 }
649 case kVulkanObjectTypeFramebuffer: {
650 base_ptr = GetFramebufferState(object_struct.Cast<VkFramebuffer>());
651 break;
652 }
653 case kVulkanObjectTypeRenderPass: {
654 base_ptr = GetRenderPassState(object_struct.Cast<VkRenderPass>());
655 break;
656 }
657 case kVulkanObjectTypeDeviceMemory: {
658 base_ptr = GetDevMemState(object_struct.Cast<VkDeviceMemory>());
659 break;
660 }
661 case kVulkanObjectTypeAccelerationStructureNV: {
sourav parmarcd5fb182020-07-17 12:58:44 -0700662 base_ptr = GetAccelerationStructureStateNV(object_struct.Cast<VkAccelerationStructureNV>());
663 break;
664 }
665 case kVulkanObjectTypeAccelerationStructureKHR: {
666 base_ptr = GetAccelerationStructureStateKHR(object_struct.Cast<VkAccelerationStructureKHR>());
locke-lunargd556cc32019-09-17 01:21:23 -0600667 break;
668 }
Jeff Bolzadbfa852019-10-04 13:53:30 -0500669 case kVulkanObjectTypeUnknown:
670 // This can happen if an element of the object_bindings vector has been
671 // zeroed out, after an object is destroyed.
672 break;
locke-lunargd556cc32019-09-17 01:21:23 -0600673 default:
674 // TODO : Any other objects to be handled here?
675 assert(0);
676 break;
677 }
678 return base_ptr;
679}
680
sfricke-samsungbf1a2ed2020-06-14 23:31:00 -0700681// Gets union of all features defined by Potential Format Features
682// 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 -0700683VkFormatFeatureFlags ValidationStateTracker::GetPotentialFormatFeatures(VkFormat format) const {
684 VkFormatFeatureFlags format_features = 0;
685
686 if (format != VK_FORMAT_UNDEFINED) {
687 VkFormatProperties format_properties;
688 DispatchGetPhysicalDeviceFormatProperties(physical_device, format, &format_properties);
689 format_features |= format_properties.linearTilingFeatures;
690 format_features |= format_properties.optimalTilingFeatures;
691 if (device_extensions.vk_ext_image_drm_format_modifier) {
692 // VK_KHR_get_physical_device_properties2 is required in this case
693 VkFormatProperties2 format_properties_2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
694 VkDrmFormatModifierPropertiesListEXT drm_properties_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
695 nullptr};
696 format_properties_2.pNext = (void *)&drm_properties_list;
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100697
698 // First call is to get the number of modifiers compatible with the queried format
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700699 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
Marc Alcala Prieto773871c2021-02-04 19:24:43 +0100700
701 std::vector<VkDrmFormatModifierPropertiesEXT> drm_properties;
702 drm_properties.resize(drm_properties_list.drmFormatModifierCount);
703 drm_properties_list.pDrmFormatModifierProperties = drm_properties.data();
704
705 // Second call, now with an allocated array in pDrmFormatModifierProperties, is to get the modifiers
706 // compatible with the queried format
707 DispatchGetPhysicalDeviceFormatProperties2(physical_device, format, &format_properties_2);
708
sfricke-samsungbe3584f2020-04-22 14:58:06 -0700709 for (uint32_t i = 0; i < drm_properties_list.drmFormatModifierCount; i++) {
710 format_features |= drm_properties_list.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
711 }
712 }
713 }
714
715 return format_features;
716}
717
locke-lunargd556cc32019-09-17 01:21:23 -0600718void ValidationStateTracker::PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
719 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
720 VkResult result) {
721 if (VK_SUCCESS != result) return;
722
Locke Linf3873542021-04-26 11:25:10 -0600723 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
724 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
725 ValidationStateTracker *state_tracker = static_cast<ValidationStateTracker *>(validation_data);
726
locke-lunargd556cc32019-09-17 01:21:23 -0600727 const VkPhysicalDeviceFeatures *enabled_features_found = pCreateInfo->pEnabledFeatures;
728 if (nullptr == enabled_features_found) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700729 const auto *features2 = LvlFindInChain<VkPhysicalDeviceFeatures2>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600730 if (features2) {
731 enabled_features_found = &(features2->features);
Locke Linf3873542021-04-26 11:25:10 -0600732
733 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(features2->pNext);
734 if (provoking_vertex_features) {
735 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
736 }
locke-lunargd556cc32019-09-17 01:21:23 -0600737 }
738 }
739
locke-lunargd556cc32019-09-17 01:21:23 -0600740 if (nullptr == enabled_features_found) {
741 state_tracker->enabled_features.core = {};
742 } else {
743 state_tracker->enabled_features.core = *enabled_features_found;
744 }
745
746 // Make sure that queue_family_properties are obtained for this device's physical_device, even if the app has not
747 // previously set them through an explicit API call.
748 uint32_t count;
749 auto pd_state = GetPhysicalDeviceState(gpu);
750 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
751 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
752 DispatchGetPhysicalDeviceQueueFamilyProperties(gpu, &count, &pd_state->queue_family_properties[0]);
753 // Save local link to this device's physical device state
754 state_tracker->physical_device_state = pd_state;
755
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700756 const auto *vulkan_12_features = LvlFindInChain<VkPhysicalDeviceVulkan12Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700757 if (vulkan_12_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700758 state_tracker->enabled_features.core12 = *vulkan_12_features;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700759 } else {
sfricke-samsung27c70722020-05-02 08:42:39 -0700760 // Set Extension Feature Aliases to false as there is no struct to check
761 state_tracker->enabled_features.core12.drawIndirectCount = VK_FALSE;
762 state_tracker->enabled_features.core12.samplerMirrorClampToEdge = VK_FALSE;
763 state_tracker->enabled_features.core12.descriptorIndexing = VK_FALSE;
764 state_tracker->enabled_features.core12.samplerFilterMinmax = VK_FALSE;
765 state_tracker->enabled_features.core12.shaderOutputLayer = VK_FALSE;
766 state_tracker->enabled_features.core12.shaderOutputViewportIndex = VK_FALSE;
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800767 state_tracker->enabled_features.core12.subgroupBroadcastDynamicId = VK_FALSE;
sfricke-samsung27c70722020-05-02 08:42:39 -0700768
769 // These structs are only allowed in pNext chain if there is no VkPhysicalDeviceVulkan12Features
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700770
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700771 const auto *eight_bit_storage_features = LvlFindInChain<VkPhysicalDevice8BitStorageFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700772 if (eight_bit_storage_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700773 state_tracker->enabled_features.core12.storageBuffer8BitAccess = eight_bit_storage_features->storageBuffer8BitAccess;
774 state_tracker->enabled_features.core12.uniformAndStorageBuffer8BitAccess =
775 eight_bit_storage_features->uniformAndStorageBuffer8BitAccess;
776 state_tracker->enabled_features.core12.storagePushConstant8 = eight_bit_storage_features->storagePushConstant8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700777 }
778
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700779 const auto *float16_int8_features = LvlFindInChain<VkPhysicalDeviceShaderFloat16Int8Features>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700780 if (float16_int8_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700781 state_tracker->enabled_features.core12.shaderFloat16 = float16_int8_features->shaderFloat16;
782 state_tracker->enabled_features.core12.shaderInt8 = float16_int8_features->shaderInt8;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700783 }
784
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700785 const auto *descriptor_indexing_features = LvlFindInChain<VkPhysicalDeviceDescriptorIndexingFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700786 if (descriptor_indexing_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700787 state_tracker->enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing =
788 descriptor_indexing_features->shaderInputAttachmentArrayDynamicIndexing;
789 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing =
790 descriptor_indexing_features->shaderUniformTexelBufferArrayDynamicIndexing;
791 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing =
792 descriptor_indexing_features->shaderStorageTexelBufferArrayDynamicIndexing;
793 state_tracker->enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing =
794 descriptor_indexing_features->shaderUniformBufferArrayNonUniformIndexing;
795 state_tracker->enabled_features.core12.shaderSampledImageArrayNonUniformIndexing =
796 descriptor_indexing_features->shaderSampledImageArrayNonUniformIndexing;
797 state_tracker->enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing =
798 descriptor_indexing_features->shaderStorageBufferArrayNonUniformIndexing;
799 state_tracker->enabled_features.core12.shaderStorageImageArrayNonUniformIndexing =
800 descriptor_indexing_features->shaderStorageImageArrayNonUniformIndexing;
801 state_tracker->enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing =
802 descriptor_indexing_features->shaderInputAttachmentArrayNonUniformIndexing;
803 state_tracker->enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing =
804 descriptor_indexing_features->shaderUniformTexelBufferArrayNonUniformIndexing;
805 state_tracker->enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing =
806 descriptor_indexing_features->shaderStorageTexelBufferArrayNonUniformIndexing;
807 state_tracker->enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind =
808 descriptor_indexing_features->descriptorBindingUniformBufferUpdateAfterBind;
809 state_tracker->enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind =
810 descriptor_indexing_features->descriptorBindingSampledImageUpdateAfterBind;
811 state_tracker->enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind =
812 descriptor_indexing_features->descriptorBindingStorageImageUpdateAfterBind;
813 state_tracker->enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind =
814 descriptor_indexing_features->descriptorBindingStorageBufferUpdateAfterBind;
815 state_tracker->enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind =
816 descriptor_indexing_features->descriptorBindingUniformTexelBufferUpdateAfterBind;
817 state_tracker->enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind =
818 descriptor_indexing_features->descriptorBindingStorageTexelBufferUpdateAfterBind;
819 state_tracker->enabled_features.core12.descriptorBindingUpdateUnusedWhilePending =
820 descriptor_indexing_features->descriptorBindingUpdateUnusedWhilePending;
821 state_tracker->enabled_features.core12.descriptorBindingPartiallyBound =
822 descriptor_indexing_features->descriptorBindingPartiallyBound;
823 state_tracker->enabled_features.core12.descriptorBindingVariableDescriptorCount =
824 descriptor_indexing_features->descriptorBindingVariableDescriptorCount;
825 state_tracker->enabled_features.core12.runtimeDescriptorArray = descriptor_indexing_features->runtimeDescriptorArray;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700826 }
827
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700828 const auto *scalar_block_layout_features = LvlFindInChain<VkPhysicalDeviceScalarBlockLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700829 if (scalar_block_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700830 state_tracker->enabled_features.core12.scalarBlockLayout = scalar_block_layout_features->scalarBlockLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700831 }
832
833 const auto *imageless_framebuffer_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700834 LvlFindInChain<VkPhysicalDeviceImagelessFramebufferFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700835 if (imageless_framebuffer_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700836 state_tracker->enabled_features.core12.imagelessFramebuffer = imageless_framebuffer_features->imagelessFramebuffer;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700837 }
838
839 const auto *uniform_buffer_standard_layout_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700840 LvlFindInChain<VkPhysicalDeviceUniformBufferStandardLayoutFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700841 if (uniform_buffer_standard_layout_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700842 state_tracker->enabled_features.core12.uniformBufferStandardLayout =
843 uniform_buffer_standard_layout_features->uniformBufferStandardLayout;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700844 }
845
846 const auto *subgroup_extended_types_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700847 LvlFindInChain<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700848 if (subgroup_extended_types_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700849 state_tracker->enabled_features.core12.shaderSubgroupExtendedTypes =
850 subgroup_extended_types_features->shaderSubgroupExtendedTypes;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700851 }
852
853 const auto *separate_depth_stencil_layouts_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700854 LvlFindInChain<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700855 if (separate_depth_stencil_layouts_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700856 state_tracker->enabled_features.core12.separateDepthStencilLayouts =
857 separate_depth_stencil_layouts_features->separateDepthStencilLayouts;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700858 }
859
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700860 const auto *host_query_reset_features = LvlFindInChain<VkPhysicalDeviceHostQueryResetFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700861 if (host_query_reset_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700862 state_tracker->enabled_features.core12.hostQueryReset = host_query_reset_features->hostQueryReset;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700863 }
864
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700865 const auto *timeline_semaphore_features = LvlFindInChain<VkPhysicalDeviceTimelineSemaphoreFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700866 if (timeline_semaphore_features) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700867 state_tracker->enabled_features.core12.timelineSemaphore = timeline_semaphore_features->timelineSemaphore;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700868 }
869
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700870 const auto *buffer_device_address = LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeatures>(pCreateInfo->pNext);
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700871 if (buffer_device_address) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700872 state_tracker->enabled_features.core12.bufferDeviceAddress = buffer_device_address->bufferDeviceAddress;
873 state_tracker->enabled_features.core12.bufferDeviceAddressCaptureReplay =
874 buffer_device_address->bufferDeviceAddressCaptureReplay;
875 state_tracker->enabled_features.core12.bufferDeviceAddressMultiDevice =
876 buffer_device_address->bufferDeviceAddressMultiDevice;
877 }
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800878
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700879 const auto *atomic_int64_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicInt64Features>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800880 if (atomic_int64_features) {
881 state_tracker->enabled_features.core12.shaderBufferInt64Atomics = atomic_int64_features->shaderBufferInt64Atomics;
882 state_tracker->enabled_features.core12.shaderSharedInt64Atomics = atomic_int64_features->shaderSharedInt64Atomics;
883 }
884
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700885 const auto *memory_model_features = LvlFindInChain<VkPhysicalDeviceVulkanMemoryModelFeatures>(pCreateInfo->pNext);
sfricke-samsunga4143ac2020-12-18 00:00:53 -0800886 if (memory_model_features) {
887 state_tracker->enabled_features.core12.vulkanMemoryModel = memory_model_features->vulkanMemoryModel;
888 state_tracker->enabled_features.core12.vulkanMemoryModelDeviceScope =
889 memory_model_features->vulkanMemoryModelDeviceScope;
890 state_tracker->enabled_features.core12.vulkanMemoryModelAvailabilityVisibilityChains =
891 memory_model_features->vulkanMemoryModelAvailabilityVisibilityChains;
892 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700893 }
894
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700895 const auto *vulkan_11_features = LvlFindInChain<VkPhysicalDeviceVulkan11Features>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700896 if (vulkan_11_features) {
897 state_tracker->enabled_features.core11 = *vulkan_11_features;
898 } else {
899 // These structs are only allowed in pNext chain if there is no kPhysicalDeviceVulkan11Features
900
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700901 const auto *sixteen_bit_storage_features = LvlFindInChain<VkPhysicalDevice16BitStorageFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700902 if (sixteen_bit_storage_features) {
903 state_tracker->enabled_features.core11.storageBuffer16BitAccess =
904 sixteen_bit_storage_features->storageBuffer16BitAccess;
905 state_tracker->enabled_features.core11.uniformAndStorageBuffer16BitAccess =
906 sixteen_bit_storage_features->uniformAndStorageBuffer16BitAccess;
907 state_tracker->enabled_features.core11.storagePushConstant16 = sixteen_bit_storage_features->storagePushConstant16;
908 state_tracker->enabled_features.core11.storageInputOutput16 = sixteen_bit_storage_features->storageInputOutput16;
909 }
910
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700911 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700912 if (multiview_features) {
913 state_tracker->enabled_features.core11.multiview = multiview_features->multiview;
914 state_tracker->enabled_features.core11.multiviewGeometryShader = multiview_features->multiviewGeometryShader;
915 state_tracker->enabled_features.core11.multiviewTessellationShader = multiview_features->multiviewTessellationShader;
916 }
917
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700918 const auto *variable_pointers_features = LvlFindInChain<VkPhysicalDeviceVariablePointersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700919 if (variable_pointers_features) {
920 state_tracker->enabled_features.core11.variablePointersStorageBuffer =
921 variable_pointers_features->variablePointersStorageBuffer;
922 state_tracker->enabled_features.core11.variablePointers = variable_pointers_features->variablePointers;
923 }
924
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700925 const auto *protected_memory_features = LvlFindInChain<VkPhysicalDeviceProtectedMemoryFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700926 if (protected_memory_features) {
927 state_tracker->enabled_features.core11.protectedMemory = protected_memory_features->protectedMemory;
928 }
929
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700930 const auto *ycbcr_conversion_features = LvlFindInChain<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700931 if (ycbcr_conversion_features) {
932 state_tracker->enabled_features.core11.samplerYcbcrConversion = ycbcr_conversion_features->samplerYcbcrConversion;
933 }
934
935 const auto *shader_draw_parameters_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700936 LvlFindInChain<VkPhysicalDeviceShaderDrawParametersFeatures>(pCreateInfo->pNext);
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700937 if (shader_draw_parameters_features) {
938 state_tracker->enabled_features.core11.shaderDrawParameters = shader_draw_parameters_features->shaderDrawParameters;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700939 }
940 }
941
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700942 const auto *device_group_ci = LvlFindInChain<VkDeviceGroupDeviceCreateInfo>(pCreateInfo->pNext);
Tony-LunarGca4891a2020-08-10 15:46:46 -0600943 if (device_group_ci) {
944 state_tracker->physical_device_count = device_group_ci->physicalDeviceCount;
945 state_tracker->device_group_create_info = *device_group_ci;
946 } else {
947 state_tracker->physical_device_count = 1;
948 }
locke-lunargd556cc32019-09-17 01:21:23 -0600949
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700950 const auto *exclusive_scissor_features = LvlFindInChain<VkPhysicalDeviceExclusiveScissorFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600951 if (exclusive_scissor_features) {
952 state_tracker->enabled_features.exclusive_scissor = *exclusive_scissor_features;
953 }
954
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700955 const auto *shading_rate_image_features = LvlFindInChain<VkPhysicalDeviceShadingRateImageFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600956 if (shading_rate_image_features) {
957 state_tracker->enabled_features.shading_rate_image = *shading_rate_image_features;
958 }
959
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700960 const auto *mesh_shader_features = LvlFindInChain<VkPhysicalDeviceMeshShaderFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600961 if (mesh_shader_features) {
962 state_tracker->enabled_features.mesh_shader = *mesh_shader_features;
963 }
964
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700965 const auto *inline_uniform_block_features = LvlFindInChain<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600966 if (inline_uniform_block_features) {
967 state_tracker->enabled_features.inline_uniform_block = *inline_uniform_block_features;
968 }
969
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700970 const auto *transform_feedback_features = LvlFindInChain<VkPhysicalDeviceTransformFeedbackFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600971 if (transform_feedback_features) {
972 state_tracker->enabled_features.transform_feedback_features = *transform_feedback_features;
973 }
974
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700975 const auto *vtx_attrib_div_features = LvlFindInChain<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600976 if (vtx_attrib_div_features) {
977 state_tracker->enabled_features.vtx_attrib_divisor_features = *vtx_attrib_div_features;
978 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700979
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700980 const auto *buffer_device_address_ext = LvlFindInChain<VkPhysicalDeviceBufferDeviceAddressFeaturesEXT>(pCreateInfo->pNext);
Jeff Bolz4563f2a2019-12-10 13:30:30 -0600981 if (buffer_device_address_ext) {
Jeff Bolz33fc6722020-03-31 12:58:16 -0500982 state_tracker->enabled_features.buffer_device_address_ext = *buffer_device_address_ext;
locke-lunargd556cc32019-09-17 01:21:23 -0600983 }
984
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700985 const auto *cooperative_matrix_features = LvlFindInChain<VkPhysicalDeviceCooperativeMatrixFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600986 if (cooperative_matrix_features) {
987 state_tracker->enabled_features.cooperative_matrix_features = *cooperative_matrix_features;
988 }
989
locke-lunargd556cc32019-09-17 01:21:23 -0600990 const auto *compute_shader_derivatives_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700991 LvlFindInChain<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600992 if (compute_shader_derivatives_features) {
993 state_tracker->enabled_features.compute_shader_derivatives_features = *compute_shader_derivatives_features;
994 }
995
996 const auto *fragment_shader_barycentric_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700997 LvlFindInChain<VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -0600998 if (fragment_shader_barycentric_features) {
999 state_tracker->enabled_features.fragment_shader_barycentric_features = *fragment_shader_barycentric_features;
1000 }
1001
1002 const auto *shader_image_footprint_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001003 LvlFindInChain<VkPhysicalDeviceShaderImageFootprintFeaturesNV>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001004 if (shader_image_footprint_features) {
1005 state_tracker->enabled_features.shader_image_footprint_features = *shader_image_footprint_features;
1006 }
1007
1008 const auto *fragment_shader_interlock_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001009 LvlFindInChain<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001010 if (fragment_shader_interlock_features) {
1011 state_tracker->enabled_features.fragment_shader_interlock_features = *fragment_shader_interlock_features;
1012 }
1013
1014 const auto *demote_to_helper_invocation_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001015 LvlFindInChain<VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001016 if (demote_to_helper_invocation_features) {
1017 state_tracker->enabled_features.demote_to_helper_invocation_features = *demote_to_helper_invocation_features;
1018 }
1019
1020 const auto *texel_buffer_alignment_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001021 LvlFindInChain<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001022 if (texel_buffer_alignment_features) {
1023 state_tracker->enabled_features.texel_buffer_alignment_features = *texel_buffer_alignment_features;
1024 }
1025
locke-lunargd556cc32019-09-17 01:21:23 -06001026 const auto *pipeline_exe_props_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001027 LvlFindInChain<VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR>(pCreateInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001028 if (pipeline_exe_props_features) {
1029 state_tracker->enabled_features.pipeline_exe_props_features = *pipeline_exe_props_features;
1030 }
1031
Jeff Bolz82f854d2019-09-17 14:56:47 -05001032 const auto *dedicated_allocation_image_aliasing_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001033 LvlFindInChain<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>(pCreateInfo->pNext);
Jeff Bolz82f854d2019-09-17 14:56:47 -05001034 if (dedicated_allocation_image_aliasing_features) {
1035 state_tracker->enabled_features.dedicated_allocation_image_aliasing_features =
1036 *dedicated_allocation_image_aliasing_features;
1037 }
1038
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001039 const auto *performance_query_features = LvlFindInChain<VkPhysicalDevicePerformanceQueryFeaturesKHR>(pCreateInfo->pNext);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001040 if (performance_query_features) {
1041 state_tracker->enabled_features.performance_query_features = *performance_query_features;
1042 }
1043
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001044 const auto *device_coherent_memory_features = LvlFindInChain<VkPhysicalDeviceCoherentMemoryFeaturesAMD>(pCreateInfo->pNext);
Tobias Hector782bcde2019-11-28 16:19:42 +00001045 if (device_coherent_memory_features) {
1046 state_tracker->enabled_features.device_coherent_memory_features = *device_coherent_memory_features;
1047 }
1048
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001049 const auto *ycbcr_image_array_features = LvlFindInChain<VkPhysicalDeviceYcbcrImageArraysFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsungcead0802020-01-30 22:20:10 -08001050 if (ycbcr_image_array_features) {
1051 state_tracker->enabled_features.ycbcr_image_array_features = *ycbcr_image_array_features;
1052 }
1053
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001054 const auto *ray_query_features = LvlFindInChain<VkPhysicalDeviceRayQueryFeaturesKHR>(pCreateInfo->pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07001055 if (ray_query_features) {
1056 state_tracker->enabled_features.ray_query_features = *ray_query_features;
1057 }
1058
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001059 const auto *ray_tracing_pipeline_features = LvlFindInChain<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>(pCreateInfo->pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07001060 if (ray_tracing_pipeline_features) {
1061 state_tracker->enabled_features.ray_tracing_pipeline_features = *ray_tracing_pipeline_features;
1062 }
1063
1064 const auto *ray_tracing_acceleration_structure_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001065 LvlFindInChain<VkPhysicalDeviceAccelerationStructureFeaturesKHR>(pCreateInfo->pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07001066 if (ray_tracing_acceleration_structure_features) {
1067 state_tracker->enabled_features.ray_tracing_acceleration_structure_features = *ray_tracing_acceleration_structure_features;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001068 }
1069
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001070 const auto *robustness2_features = LvlFindInChain<VkPhysicalDeviceRobustness2FeaturesEXT>(pCreateInfo->pNext);
Jeff Bolz165818a2020-05-08 11:19:03 -05001071 if (robustness2_features) {
1072 state_tracker->enabled_features.robustness2_features = *robustness2_features;
1073 }
1074
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001075 const auto *fragment_density_map_features = LvlFindInChain<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(pCreateInfo->pNext);
janharaldfredriksen-arm3b793772020-05-12 18:55:53 +02001076 if (fragment_density_map_features) {
1077 state_tracker->enabled_features.fragment_density_map_features = *fragment_density_map_features;
1078 }
1079
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001080 const auto *fragment_density_map_features2 = LvlFindInChain<VkPhysicalDeviceFragmentDensityMap2FeaturesEXT>(pCreateInfo->pNext);
janharaldfredriksen-arm36e17572020-07-07 13:59:28 +02001081 if (fragment_density_map_features2) {
1082 state_tracker->enabled_features.fragment_density_map2_features = *fragment_density_map_features2;
1083 }
1084
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001085 const auto *astc_decode_features = LvlFindInChain<VkPhysicalDeviceASTCDecodeFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsung0c4a06f2020-06-27 01:24:32 -07001086 if (astc_decode_features) {
1087 state_tracker->enabled_features.astc_decode_features = *astc_decode_features;
1088 }
1089
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001090 const auto *custom_border_color_features = LvlFindInChain<VkPhysicalDeviceCustomBorderColorFeaturesEXT>(pCreateInfo->pNext);
Tony-LunarG7337b312020-04-15 16:40:25 -06001091 if (custom_border_color_features) {
1092 state_tracker->enabled_features.custom_border_color_features = *custom_border_color_features;
1093 }
1094
sfricke-samsungfd661d62020-05-16 00:57:27 -07001095 const auto *pipeline_creation_cache_control_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001096 LvlFindInChain<VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsungfd661d62020-05-16 00:57:27 -07001097 if (pipeline_creation_cache_control_features) {
1098 state_tracker->enabled_features.pipeline_creation_cache_control_features = *pipeline_creation_cache_control_features;
1099 }
1100
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001101 const auto *fragment_shading_rate_features = LvlFindInChain<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>(pCreateInfo->pNext);
Tobias Hector6663c9b2020-11-05 10:18:02 +00001102 if (fragment_shading_rate_features) {
1103 state_tracker->enabled_features.fragment_shading_rate_features = *fragment_shading_rate_features;
1104 }
1105
Piers Daniell39842ee2020-07-10 16:42:33 -06001106 const auto *extended_dynamic_state_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001107 LvlFindInChain<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>(pCreateInfo->pNext);
Piers Daniell39842ee2020-07-10 16:42:33 -06001108 if (extended_dynamic_state_features) {
1109 state_tracker->enabled_features.extended_dynamic_state_features = *extended_dynamic_state_features;
1110 }
1111
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07001112 const auto *extended_dynamic_state2_features =
1113 LvlFindInChain<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>(pCreateInfo->pNext);
1114 if (extended_dynamic_state2_features) {
1115 state_tracker->enabled_features.extended_dynamic_state2_features = *extended_dynamic_state2_features;
1116 }
1117
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001118 const auto *multiview_features = LvlFindInChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
locke-lunarg3fa463a2020-10-23 16:39:04 -06001119 if (multiview_features) {
1120 state_tracker->enabled_features.multiview_features = *multiview_features;
1121 }
1122
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001123 const auto *portability_features = LvlFindInChain<VkPhysicalDevicePortabilitySubsetFeaturesKHR>(pCreateInfo->pNext);
Nathaniel Cesariob3f2d702020-11-09 09:20:49 -07001124 if (portability_features) {
1125 state_tracker->enabled_features.portability_subset_features = *portability_features;
1126 }
1127
sfricke-samsung0065ce02020-12-03 22:46:37 -08001128 const auto *shader_integer_functions2_features =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001129 LvlFindInChain<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001130 if (shader_integer_functions2_features) {
1131 state_tracker->enabled_features.shader_integer_functions2_features = *shader_integer_functions2_features;
1132 }
1133
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001134 const auto *shader_sm_builtins_feature = LvlFindInChain<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001135 if (shader_sm_builtins_feature) {
1136 state_tracker->enabled_features.shader_sm_builtins_feature = *shader_sm_builtins_feature;
1137 }
1138
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001139 const auto *shader_atomic_float_feature = LvlFindInChain<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001140 if (shader_atomic_float_feature) {
1141 state_tracker->enabled_features.shader_atomic_float_feature = *shader_atomic_float_feature;
1142 }
1143
1144 const auto *shader_image_atomic_int64_feature =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001145 LvlFindInChain<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>(pCreateInfo->pNext);
sfricke-samsung0065ce02020-12-03 22:46:37 -08001146 if (shader_image_atomic_int64_feature) {
1147 state_tracker->enabled_features.shader_image_atomic_int64_feature = *shader_image_atomic_int64_feature;
1148 }
1149
sfricke-samsung486a51e2021-01-02 00:10:15 -08001150 const auto *shader_clock_feature = LvlFindInChain<VkPhysicalDeviceShaderClockFeaturesKHR>(pCreateInfo->pNext);
1151 if (shader_clock_feature) {
1152 state_tracker->enabled_features.shader_clock_feature = *shader_clock_feature;
1153 }
1154
Jeremy Gebben5f585ae2021-02-02 09:03:06 -07001155 const auto *conditional_rendering_features =
1156 LvlFindInChain<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(pCreateInfo->pNext);
1157 if (conditional_rendering_features) {
1158 state_tracker->enabled_features.conditional_rendering = *conditional_rendering_features;
1159 }
1160
Shannon McPhersondb287d42021-02-02 15:27:32 -07001161 const auto *workgroup_memory_explicit_layout_features =
1162 LvlFindInChain<VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>(pCreateInfo->pNext);
1163 if (workgroup_memory_explicit_layout_features) {
1164 state_tracker->enabled_features.workgroup_memory_explicit_layout_features = *workgroup_memory_explicit_layout_features;
1165 }
1166
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001167 const auto *synchronization2_features =
1168 LvlFindInChain<VkPhysicalDeviceSynchronization2FeaturesKHR>(pCreateInfo->pNext);
1169 if (synchronization2_features) {
1170 state_tracker->enabled_features.synchronization2_features = *synchronization2_features;
1171 }
1172
Locke Linf3873542021-04-26 11:25:10 -06001173 const auto *provoking_vertex_features = lvl_find_in_chain<VkPhysicalDeviceProvokingVertexFeaturesEXT>(pCreateInfo->pNext);
1174 if (provoking_vertex_features) {
1175 state_tracker->enabled_features.provoking_vertex_features = *provoking_vertex_features;
1176 }
1177
Piers Daniellcb6d8032021-04-19 18:51:26 -06001178 const auto *vertex_input_dynamic_state_features =
1179 LvlFindInChain<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>(pCreateInfo->pNext);
1180 if (vertex_input_dynamic_state_features) {
1181 state_tracker->enabled_features.vertex_input_dynamic_state_features = *vertex_input_dynamic_state_features;
1182 }
1183
David Zhao Akeley44139b12021-04-26 16:16:13 -07001184 const auto *inherited_viewport_scissor_features =
1185 LvlFindInChain<VkPhysicalDeviceInheritedViewportScissorFeaturesNV>(pCreateInfo->pNext);
1186 if (inherited_viewport_scissor_features) {
1187 state_tracker->enabled_features.inherited_viewport_scissor_features = *inherited_viewport_scissor_features;
1188 }
1189
Tony-LunarG4490de42021-06-21 15:49:19 -06001190 const auto *multi_draw_features = LvlFindInChain<VkPhysicalDeviceMultiDrawFeaturesEXT>(pCreateInfo->pNext);
1191 if (multi_draw_features) {
1192 state_tracker->enabled_features.multi_draw_features = *multi_draw_features;
1193 }
1194
ziga-lunarg29ba2b92021-07-20 21:51:45 +02001195 const auto *color_write_features = LvlFindInChain<VkPhysicalDeviceColorWriteEnableFeaturesEXT>(pCreateInfo->pNext);
1196 if (color_write_features) {
1197 state_tracker->enabled_features.color_write_features = *color_write_features;
1198 }
1199
Mike Schuchardtb3870ea2021-07-20 18:56:51 -07001200 const auto *shader_atomic_float2_features = LvlFindInChain<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>(pCreateInfo->pNext);
1201 if (shader_atomic_float2_features) {
1202 state_tracker->enabled_features.shader_atomic_float2_features = *shader_atomic_float2_features;
1203 }
1204
Tony-LunarG6f887e52021-07-27 11:23:14 -06001205 const auto *present_id_features = LvlFindInChain<VkPhysicalDevicePresentIdFeaturesKHR>(pCreateInfo->pNext);
1206 if (present_id_features) {
1207 state_tracker->enabled_features.present_id_features = *present_id_features;
1208 }
1209
1210 const auto *present_wait_features = LvlFindInChain<VkPhysicalDevicePresentWaitFeaturesKHR>(pCreateInfo->pNext);
1211 if (present_wait_features) {
1212 state_tracker->enabled_features.present_wait_features = *present_wait_features;
1213 }
1214
locke-lunargd556cc32019-09-17 01:21:23 -06001215 // Store physical device properties and physical device mem limits into CoreChecks structs
1216 DispatchGetPhysicalDeviceMemoryProperties(gpu, &state_tracker->phys_dev_mem_props);
1217 DispatchGetPhysicalDeviceProperties(gpu, &state_tracker->phys_dev_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001218 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1219 &state_tracker->phys_dev_props_core11);
1220 GetPhysicalDeviceExtProperties(gpu, state_tracker->device_extensions.vk_feature_version_1_2,
1221 &state_tracker->phys_dev_props_core12);
locke-lunargd556cc32019-09-17 01:21:23 -06001222
1223 const auto &dev_ext = state_tracker->device_extensions;
1224 auto *phys_dev_props = &state_tracker->phys_dev_ext_props;
1225
1226 if (dev_ext.vk_khr_push_descriptor) {
1227 // Get the needed push_descriptor limits
1228 VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor_prop;
1229 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_push_descriptor, &push_descriptor_prop);
1230 phys_dev_props->max_push_descriptors = push_descriptor_prop.maxPushDescriptors;
1231 }
1232
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001233 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_ext_descriptor_indexing) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001234 VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing_prop;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001235 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_descriptor_indexing, &descriptor_indexing_prop);
1236 state_tracker->phys_dev_props_core12.maxUpdateAfterBindDescriptorsInAllPools =
1237 descriptor_indexing_prop.maxUpdateAfterBindDescriptorsInAllPools;
1238 state_tracker->phys_dev_props_core12.shaderUniformBufferArrayNonUniformIndexingNative =
1239 descriptor_indexing_prop.shaderUniformBufferArrayNonUniformIndexingNative;
1240 state_tracker->phys_dev_props_core12.shaderSampledImageArrayNonUniformIndexingNative =
1241 descriptor_indexing_prop.shaderSampledImageArrayNonUniformIndexingNative;
1242 state_tracker->phys_dev_props_core12.shaderStorageBufferArrayNonUniformIndexingNative =
1243 descriptor_indexing_prop.shaderStorageBufferArrayNonUniformIndexingNative;
1244 state_tracker->phys_dev_props_core12.shaderStorageImageArrayNonUniformIndexingNative =
1245 descriptor_indexing_prop.shaderStorageImageArrayNonUniformIndexingNative;
1246 state_tracker->phys_dev_props_core12.shaderInputAttachmentArrayNonUniformIndexingNative =
1247 descriptor_indexing_prop.shaderInputAttachmentArrayNonUniformIndexingNative;
1248 state_tracker->phys_dev_props_core12.robustBufferAccessUpdateAfterBind =
1249 descriptor_indexing_prop.robustBufferAccessUpdateAfterBind;
1250 state_tracker->phys_dev_props_core12.quadDivergentImplicitLod = descriptor_indexing_prop.quadDivergentImplicitLod;
1251 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSamplers =
1252 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSamplers;
1253 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindUniformBuffers =
1254 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindUniformBuffers;
1255 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageBuffers =
1256 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageBuffers;
1257 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindSampledImages =
1258 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindSampledImages;
1259 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindStorageImages =
1260 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindStorageImages;
1261 state_tracker->phys_dev_props_core12.maxPerStageDescriptorUpdateAfterBindInputAttachments =
1262 descriptor_indexing_prop.maxPerStageDescriptorUpdateAfterBindInputAttachments;
1263 state_tracker->phys_dev_props_core12.maxPerStageUpdateAfterBindResources =
1264 descriptor_indexing_prop.maxPerStageUpdateAfterBindResources;
1265 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSamplers =
1266 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSamplers;
1267 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffers =
1268 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffers;
1269 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
1270 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
1271 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffers =
1272 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffers;
1273 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
1274 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
1275 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindSampledImages =
1276 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindSampledImages;
1277 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageImages =
1278 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindStorageImages;
1279 state_tracker->phys_dev_props_core12.maxDescriptorSetUpdateAfterBindInputAttachments =
1280 descriptor_indexing_prop.maxDescriptorSetUpdateAfterBindInputAttachments;
1281 }
1282
locke-lunargd556cc32019-09-17 01:21:23 -06001283 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_shading_rate_image, &phys_dev_props->shading_rate_image_props);
1284 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_mesh_shader, &phys_dev_props->mesh_shader_props);
1285 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_inline_uniform_block, &phys_dev_props->inline_uniform_block_props);
1286 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_vertex_attribute_divisor, &phys_dev_props->vtx_attrib_divisor_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001287
1288 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_khr_depth_stencil_resolve) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001289 VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve_props;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001290 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_depth_stencil_resolve, &depth_stencil_resolve_props);
1291 state_tracker->phys_dev_props_core12.supportedDepthResolveModes = depth_stencil_resolve_props.supportedDepthResolveModes;
1292 state_tracker->phys_dev_props_core12.supportedStencilResolveModes =
1293 depth_stencil_resolve_props.supportedStencilResolveModes;
1294 state_tracker->phys_dev_props_core12.independentResolveNone = depth_stencil_resolve_props.independentResolveNone;
1295 state_tracker->phys_dev_props_core12.independentResolve = depth_stencil_resolve_props.independentResolve;
1296 }
1297
locke-lunargd556cc32019-09-17 01:21:23 -06001298 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_transform_feedback, &phys_dev_props->transform_feedback_props);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001299 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_nv_ray_tracing, &phys_dev_props->ray_tracing_propsNV);
sourav parmarcd5fb182020-07-17 12:58:44 -07001300 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_ray_tracing_pipeline, &phys_dev_props->ray_tracing_propsKHR);
1301 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_acceleration_structure, &phys_dev_props->acc_structure_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001302 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_texel_buffer_alignment, &phys_dev_props->texel_buffer_alignment_props);
1303 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map, &phys_dev_props->fragment_density_map_props);
Mike Schuchardtc57de4a2021-07-20 17:26:32 -07001304 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_fragment_density_map2, &phys_dev_props->fragment_density_map2_props);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001305 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_performance_query, &phys_dev_props->performance_query_props);
sfricke-samsung8f658d42020-05-03 20:12:24 -07001306 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_sample_locations, &phys_dev_props->sample_locations_props);
Tony-LunarG7337b312020-04-15 16:40:25 -06001307 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_custom_border_color, &phys_dev_props->custom_border_color_props);
locke-lunarg3fa463a2020-10-23 16:39:04 -06001308 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_multiview, &phys_dev_props->multiview_props);
Nathaniel Cesario3291c912020-11-17 16:54:41 -07001309 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_portability_subset, &phys_dev_props->portability_props);
Locke Lin016d8482021-05-27 12:11:31 -06001310 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_provoking_vertex, &phys_dev_props->provoking_vertex_props);
Tony-LunarG4490de42021-06-21 15:49:19 -06001311 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_multi_draw, &phys_dev_props->multi_draw_props);
ziga-lunarg128904a2021-07-30 13:49:01 +02001312 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_discard_rectangles, &phys_dev_props->discard_rectangle_props);
ziga-lunarg86492812021-08-05 23:58:16 +02001313 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_ext_blend_operation_advanced, &phys_dev_props->blend_operation_advanced_props);
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001314
1315 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_khr_timeline_semaphore) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001316 VkPhysicalDeviceTimelineSemaphoreProperties timeline_semaphore_props;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001317 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_timeline_semaphore, &timeline_semaphore_props);
1318 state_tracker->phys_dev_props_core12.maxTimelineSemaphoreValueDifference =
1319 timeline_semaphore_props.maxTimelineSemaphoreValueDifference;
1320 }
1321
1322 if (!state_tracker->device_extensions.vk_feature_version_1_2 && dev_ext.vk_khr_shader_float_controls) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001323 VkPhysicalDeviceFloatControlsProperties float_controls_props;
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001324 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_shader_float_controls, &float_controls_props);
1325 state_tracker->phys_dev_props_core12.denormBehaviorIndependence = float_controls_props.denormBehaviorIndependence;
1326 state_tracker->phys_dev_props_core12.roundingModeIndependence = float_controls_props.roundingModeIndependence;
1327 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat16 =
1328 float_controls_props.shaderSignedZeroInfNanPreserveFloat16;
1329 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat32 =
1330 float_controls_props.shaderSignedZeroInfNanPreserveFloat32;
1331 state_tracker->phys_dev_props_core12.shaderSignedZeroInfNanPreserveFloat64 =
1332 float_controls_props.shaderSignedZeroInfNanPreserveFloat64;
1333 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat16 = float_controls_props.shaderDenormPreserveFloat16;
1334 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat32 = float_controls_props.shaderDenormPreserveFloat32;
1335 state_tracker->phys_dev_props_core12.shaderDenormPreserveFloat64 = float_controls_props.shaderDenormPreserveFloat64;
1336 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat16 = float_controls_props.shaderDenormFlushToZeroFloat16;
1337 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat32 = float_controls_props.shaderDenormFlushToZeroFloat32;
1338 state_tracker->phys_dev_props_core12.shaderDenormFlushToZeroFloat64 = float_controls_props.shaderDenormFlushToZeroFloat64;
1339 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat16 = float_controls_props.shaderRoundingModeRTEFloat16;
1340 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat32 = float_controls_props.shaderRoundingModeRTEFloat32;
1341 state_tracker->phys_dev_props_core12.shaderRoundingModeRTEFloat64 = float_controls_props.shaderRoundingModeRTEFloat64;
1342 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat16 = float_controls_props.shaderRoundingModeRTZFloat16;
1343 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat32 = float_controls_props.shaderRoundingModeRTZFloat32;
1344 state_tracker->phys_dev_props_core12.shaderRoundingModeRTZFloat64 = float_controls_props.shaderRoundingModeRTZFloat64;
1345 }
Mark Lobodzinskie4a2b7f2019-12-20 12:51:30 -07001346
locke-lunargd556cc32019-09-17 01:21:23 -06001347 if (state_tracker->device_extensions.vk_nv_cooperative_matrix) {
1348 // Get the needed cooperative_matrix properties
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001349 auto cooperative_matrix_props = LvlInitStruct<VkPhysicalDeviceCooperativeMatrixPropertiesNV>();
1350 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&cooperative_matrix_props);
locke-lunargd556cc32019-09-17 01:21:23 -06001351 instance_dispatch_table.GetPhysicalDeviceProperties2KHR(gpu, &prop2);
1352 state_tracker->phys_dev_ext_props.cooperative_matrix_props = cooperative_matrix_props;
1353
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001354 uint32_t num_cooperative_matrix_properties = 0;
1355 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties, NULL);
1356 state_tracker->cooperative_matrix_properties.resize(num_cooperative_matrix_properties,
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001357 LvlInitStruct<VkCooperativeMatrixPropertiesNV>());
locke-lunargd556cc32019-09-17 01:21:23 -06001358
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001359 instance_dispatch_table.GetPhysicalDeviceCooperativeMatrixPropertiesNV(gpu, &num_cooperative_matrix_properties,
locke-lunargd556cc32019-09-17 01:21:23 -06001360 state_tracker->cooperative_matrix_properties.data());
1361 }
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001362 if (!state_tracker->device_extensions.vk_feature_version_1_2 && state_tracker->api_version >= VK_API_VERSION_1_1) {
locke-lunargd556cc32019-09-17 01:21:23 -06001363 // Get the needed subgroup limits
Locke Lin016d8482021-05-27 12:11:31 -06001364 auto subgroup_prop = LvlInitStruct<VkPhysicalDeviceSubgroupProperties>();
Mark Lobodzinski6fe9e702020-12-30 15:36:39 -07001365 auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&subgroup_prop);
locke-lunargd556cc32019-09-17 01:21:23 -06001366 instance_dispatch_table.GetPhysicalDeviceProperties2(gpu, &prop2);
1367
Piers Daniell41b8c5d2020-01-10 15:42:00 -07001368 state_tracker->phys_dev_props_core11.subgroupSize = subgroup_prop.subgroupSize;
1369 state_tracker->phys_dev_props_core11.subgroupSupportedStages = subgroup_prop.supportedStages;
1370 state_tracker->phys_dev_props_core11.subgroupSupportedOperations = subgroup_prop.supportedOperations;
1371 state_tracker->phys_dev_props_core11.subgroupQuadOperationsInAllStages = subgroup_prop.quadOperationsInAllStages;
locke-lunargd556cc32019-09-17 01:21:23 -06001372 }
1373
Tobias Hector6663c9b2020-11-05 10:18:02 +00001374 GetPhysicalDeviceExtProperties(gpu, dev_ext.vk_khr_fragment_shading_rate, &phys_dev_props->fragment_shading_rate_props);
1375
locke-lunargd556cc32019-09-17 01:21:23 -06001376 // Store queue family data
1377 if (pCreateInfo->pQueueCreateInfos != nullptr) {
1378 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
sfricke-samsung590ae1e2020-04-25 01:18:05 -07001379 const VkDeviceQueueCreateInfo &queue_create_info = pCreateInfo->pQueueCreateInfos[i];
sfricke-samsungb585ec12021-05-06 03:10:13 -07001380 state_tracker->queue_family_index_set.insert(queue_create_info.queueFamilyIndex);
1381 state_tracker->device_queue_info_list.push_back(
1382 {i, queue_create_info.queueFamilyIndex, queue_create_info.flags, queue_create_info.queueCount});
locke-lunargd556cc32019-09-17 01:21:23 -06001383 }
1384 }
1385}
1386
1387void ValidationStateTracker::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
1388 if (!device) return;
1389
locke-lunargd556cc32019-09-17 01:21:23 -06001390 // Reset all command buffers before destroying them, to unlink object_bindings.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001391 for (auto &command_buffer : commandBufferMap) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001392 command_buffer.second->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06001393 }
Jeff Bolzadbfa852019-10-04 13:53:30 -05001394 pipelineMap.clear();
1395 renderPassMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001396 commandBufferMap.clear();
1397
1398 // This will also delete all sets in the pool & remove them from setMap
1399 DeleteDescriptorSetPools();
1400 // All sets should be removed
1401 assert(setMap.empty());
1402 descriptorSetLayoutMap.clear();
Jeremy Gebben5a542f52021-07-21 15:25:52 -06001403 // Because swapchains are associated with Surfaces, which are at instance level,
1404 // they need to be explicitly destroyed here to avoid continued references to
1405 // the device we're destroying.
1406 for (auto &entry : swapchainMap) {
1407 entry.second->Destroy();
1408 }
1409 swapchainMap.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06001410 imageViewMap.clear();
1411 imageMap.clear();
1412 bufferViewMap.clear();
1413 bufferMap.clear();
1414 // Queues persist until device is destroyed
1415 queueMap.clear();
1416}
1417
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001418void ValidationStateTracker::RetireWorkOnQueue(QUEUE_STATE *pQueue, uint64_t seq) {
Jeremy Gebbencbf22862021-03-03 12:01:22 -07001419 layer_data::unordered_map<VkQueue, uint64_t> other_queue_seqs;
1420 layer_data::unordered_map<VkSemaphore, uint64_t> timeline_semaphore_counters;
locke-lunargd556cc32019-09-17 01:21:23 -06001421
1422 // Roll this queue forward, one submission at a time.
1423 while (pQueue->seq < seq) {
1424 auto &submission = pQueue->submissions.front();
1425
1426 for (auto &wait : submission.waitSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001427 auto semaphore_state = GetSemaphoreState(wait.semaphore);
1428 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001429 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001430 }
Mike Schuchardt2df08912020-12-15 16:28:09 -08001431 if (wait.type == VK_SEMAPHORE_TYPE_TIMELINE) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001432 auto &last_counter = timeline_semaphore_counters[wait.semaphore];
1433 last_counter = std::max(last_counter, wait.payload);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001434 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001435 auto &last_seq = other_queue_seqs[wait.queue];
1436 last_seq = std::max(last_seq, wait.seq);
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001437 }
locke-lunargd556cc32019-09-17 01:21:23 -06001438 }
1439
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001440 for (auto &signal : submission.signalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001441 auto semaphore_state = GetSemaphoreState(signal.semaphore);
1442 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001443 semaphore_state->EndUse();
Mike Schuchardt2df08912020-12-15 16:28:09 -08001444 if (semaphore_state->type == VK_SEMAPHORE_TYPE_TIMELINE && semaphore_state->payload < signal.payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001445 semaphore_state->payload = signal.payload;
Juan A. Suarez Romero9cef8852020-03-10 12:19:42 +01001446 }
locke-lunargd556cc32019-09-17 01:21:23 -06001447 }
1448 }
1449
1450 for (auto &semaphore : submission.externalSemaphores) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001451 auto semaphore_state = GetSemaphoreState(semaphore);
1452 if (semaphore_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001453 semaphore_state->EndUse();
locke-lunargd556cc32019-09-17 01:21:23 -06001454 }
1455 }
1456
1457 for (auto cb : submission.cbs) {
1458 auto cb_node = GetCBState(cb);
1459 if (!cb_node) {
1460 continue;
1461 }
1462 // First perform decrement on general case bound objects
locke-lunargd556cc32019-09-17 01:21:23 -06001463 for (auto event : cb_node->writeEventsBeforeWait) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001464 auto event_node = eventMap.find(event);
1465 if (event_node != eventMap.end()) {
John Zulauf48057322020-12-02 11:59:31 -07001466 event_node->second->write_in_use--;
locke-lunargd556cc32019-09-17 01:21:23 -06001467 }
1468 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001469 QueryMap local_query_to_state_map;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001470 VkQueryPool first_pool = VK_NULL_HANDLE;
Jeff Bolz310775c2019-10-09 00:46:33 -05001471 for (auto &function : cb_node->queryUpdates) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001472 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
Jeff Bolz310775c2019-10-09 00:46:33 -05001473 }
1474
John Zulauf79f06582021-02-27 18:38:39 -07001475 for (const auto &query_state_pair : local_query_to_state_map) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001476 if (query_state_pair.second == QUERYSTATE_ENDED) {
1477 queryToStateMap[query_state_pair.first] = QUERYSTATE_AVAILABLE;
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001478 }
locke-lunargd556cc32019-09-17 01:21:23 -06001479 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001480 if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
1481 cb_node->EndUse();
1482 }
locke-lunargd556cc32019-09-17 01:21:23 -06001483 }
1484
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001485 auto fence_state = GetFenceState(submission.fence);
1486 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1487 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001488 }
1489
1490 pQueue->submissions.pop_front();
1491 pQueue->seq++;
1492 }
1493
1494 // Roll other queues forward to the highest seq we saw a wait for
John Zulauf79f06582021-02-27 18:38:39 -07001495 for (const auto &qs : other_queue_seqs) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001496 RetireWorkOnQueue(GetQueueState(qs.first), qs.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001497 }
John Zulauf79f06582021-02-27 18:38:39 -07001498 for (const auto &sc : timeline_semaphore_counters) {
Marshall Drew-Brook03847582020-11-06 15:10:45 -08001499 RetireTimelineSemaphore(sc.first, sc.second);
1500 }
locke-lunargd556cc32019-09-17 01:21:23 -06001501}
1502
1503// Submit a fence to a queue, delimiting previous fences and previous untracked
1504// work by it.
1505static void SubmitFence(QUEUE_STATE *pQueue, FENCE_STATE *pFence, uint64_t submitCount) {
1506 pFence->state = FENCE_INFLIGHT;
1507 pFence->signaler.first = pQueue->queue;
1508 pFence->signaler.second = pQueue->seq + pQueue->submissions.size() + submitCount;
1509}
1510
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001511uint64_t ValidationStateTracker::RecordSubmitFence(QUEUE_STATE *queue_state, VkFence fence, uint32_t submit_count) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001512 auto fence_state = GetFenceState(fence);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001513 uint64_t early_retire_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001514 if (fence_state) {
1515 if (fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06001516 // Mark fence in use
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001517 SubmitFence(queue_state, fence_state, std::max(1u, submit_count));
1518 if (!submit_count) {
locke-lunargd556cc32019-09-17 01:21:23 -06001519 // If no submissions, but just dropping a fence on the end of the queue,
1520 // record an empty submission with just the fence, so we can determine
1521 // its completion.
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001522 CB_SUBMISSION submission;
1523 submission.fence = fence;
1524 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001525 }
1526 } else {
1527 // 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 -07001528 early_retire_seq = queue_state->seq + queue_state->submissions.size();
locke-lunargd556cc32019-09-17 01:21:23 -06001529 }
1530 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001531 return early_retire_seq;
1532}
1533
1534void ValidationStateTracker::RecordSubmitCommandBuffer(CB_SUBMISSION &submission, VkCommandBuffer command_buffer) {
1535 auto cb_node = GetCBState(command_buffer);
1536 if (cb_node) {
1537 submission.cbs.push_back(command_buffer);
John Zulauf79f06582021-02-27 18:38:39 -07001538 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001539 submission.cbs.push_back(secondary_cmd_buffer->commandBuffer());
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001540 secondary_cmd_buffer->IncrementResources();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001541 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06001542 cb_node->IncrementResources();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001543 // increment use count for all bound objects including secondary cbs
1544 cb_node->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001545
1546 VkQueryPool first_pool = VK_NULL_HANDLE;
1547 EventToStageMap local_event_to_stage_map;
1548 QueryMap local_query_to_state_map;
1549 for (auto &function : cb_node->queryUpdates) {
1550 function(nullptr, /*do_validate*/ false, first_pool, submission.perf_submit_pass, &local_query_to_state_map);
1551 }
1552
John Zulauf79f06582021-02-27 18:38:39 -07001553 for (const auto &query_state_pair : local_query_to_state_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001554 queryToStateMap[query_state_pair.first] = query_state_pair.second;
1555 }
1556
John Zulauf79f06582021-02-27 18:38:39 -07001557 for (const auto &function : cb_node->eventUpdates) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001558 function(nullptr, /*do_validate*/ false, &local_event_to_stage_map);
1559 }
1560
John Zulauf79f06582021-02-27 18:38:39 -07001561 for (const auto &eventStagePair : local_event_to_stage_map) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001562 eventMap[eventStagePair.first]->stageMask = eventStagePair.second;
1563 }
1564 }
1565}
1566
1567void ValidationStateTracker::RecordSubmitWaitSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1568 uint64_t value, uint64_t next_seq) {
1569 auto semaphore_state = GetSemaphoreState(semaphore);
1570 if (semaphore_state) {
1571 if (semaphore_state->scope == kSyncScopeInternal) {
1572 SEMAPHORE_WAIT wait;
1573 wait.semaphore = semaphore;
1574 wait.type = semaphore_state->type;
1575 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1576 if (semaphore_state->signaler.first != VK_NULL_HANDLE) {
1577 wait.queue = semaphore_state->signaler.first;
1578 wait.seq = semaphore_state->signaler.second;
1579 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001580 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001581 }
1582 semaphore_state->signaler.first = VK_NULL_HANDLE;
1583 semaphore_state->signaled = false;
1584 } else if (semaphore_state->payload < value) {
1585 wait.queue = queue;
1586 wait.seq = next_seq;
1587 wait.payload = value;
1588 submission.waitSemaphores.emplace_back(std::move(wait));
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001589 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001590 }
1591 } else {
1592 submission.externalSemaphores.push_back(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001593 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001594 if (semaphore_state->scope == kSyncScopeExternalTemporary) {
1595 semaphore_state->scope = kSyncScopeInternal;
1596 }
1597 }
1598 }
1599}
1600
1601bool ValidationStateTracker::RecordSubmitSignalSemaphore(CB_SUBMISSION &submission, VkQueue queue, VkSemaphore semaphore,
1602 uint64_t value, uint64_t next_seq) {
1603 bool retire_early = false;
1604 auto semaphore_state = GetSemaphoreState(semaphore);
1605 if (semaphore_state) {
1606 if (semaphore_state->scope == kSyncScopeInternal) {
1607 SEMAPHORE_SIGNAL signal;
1608 signal.semaphore = semaphore;
1609 signal.seq = next_seq;
1610 if (semaphore_state->type == VK_SEMAPHORE_TYPE_BINARY) {
1611 semaphore_state->signaler.first = queue;
1612 semaphore_state->signaler.second = next_seq;
1613 semaphore_state->signaled = true;
1614 } else {
1615 signal.payload = value;
1616 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001617 semaphore_state->BeginUse();
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001618 submission.signalSemaphores.emplace_back(std::move(signal));
1619 } else {
1620 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1621 retire_early = true;
1622 }
1623 }
1624 return retire_early;
1625}
1626
1627void ValidationStateTracker::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
1628 VkFence fence, VkResult result) {
1629 if (result != VK_SUCCESS) return;
1630 auto queue_state = GetQueueState(queue);
1631
1632 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001633
1634 // Now process each individual submit
1635 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001636 CB_SUBMISSION submission;
locke-lunargd556cc32019-09-17 01:21:23 -06001637 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001638 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001639 auto *timeline_semaphore_submit = LvlFindInChain<VkTimelineSemaphoreSubmitInfo>(submit->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06001640 for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001641 uint64_t value = 0;
1642 if (timeline_semaphore_submit && timeline_semaphore_submit->pWaitSemaphoreValues != nullptr &&
1643 (i < timeline_semaphore_submit->waitSemaphoreValueCount)) {
1644 value = timeline_semaphore_submit->pWaitSemaphoreValues[i];
1645 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001646 RecordSubmitWaitSemaphore(submission, queue, submit->pWaitSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001647 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001648
1649 bool retire_early = false;
locke-lunargd556cc32019-09-17 01:21:23 -06001650 for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) {
Jeremy Gebben4ae5cc72021-03-10 15:34:44 -07001651 uint64_t value = 0;
1652 if (timeline_semaphore_submit && timeline_semaphore_submit->pSignalSemaphoreValues != nullptr &&
1653 (i < timeline_semaphore_submit->signalSemaphoreValueCount)) {
1654 value = timeline_semaphore_submit->pSignalSemaphoreValues[i];
1655 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001656 retire_early |= RecordSubmitSignalSemaphore(submission, queue, submit->pSignalSemaphores[i], value, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001657 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001658 if (retire_early) {
1659 early_retire_seq = std::max(early_retire_seq, next_seq);
1660 }
1661
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001662 const auto perf_submit = LvlFindInChain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001663 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02001664
locke-lunargd556cc32019-09-17 01:21:23 -06001665 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001666 RecordSubmitCommandBuffer(submission, submit->pCommandBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06001667 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001668 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1669 queue_state->submissions.emplace_back(std::move(submission));
1670 }
Lionel Landwerlinc7420912019-05-23 00:33:42 +01001671
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001672 if (early_retire_seq) {
1673 RetireWorkOnQueue(queue_state, early_retire_seq);
1674 }
1675}
1676
1677void ValidationStateTracker::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1678 VkFence fence, VkResult result) {
1679 if (result != VK_SUCCESS) return;
1680 auto queue_state = GetQueueState(queue);
1681
1682 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, submitCount);
1683
1684 // Now process each individual submit
1685 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1686 CB_SUBMISSION submission;
1687 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1688 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
1689 for (uint32_t i = 0; i < submit->waitSemaphoreInfoCount; ++i) {
1690 const auto &sem_info = submit->pWaitSemaphoreInfos[i];
1691 RecordSubmitWaitSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1692 }
1693 bool retire_early = false;
1694 for (uint32_t i = 0; i < submit->signalSemaphoreInfoCount; ++i) {
1695 const auto &sem_info = submit->pSignalSemaphoreInfos[i];
1696 retire_early |= RecordSubmitSignalSemaphore(submission, queue, sem_info.semaphore, sem_info.value, next_seq);
1697 }
1698 if (retire_early) {
1699 early_retire_seq = std::max(early_retire_seq, next_seq);
1700 }
1701 const auto perf_submit = lvl_find_in_chain<VkPerformanceQuerySubmitInfoKHR>(submit->pNext);
1702 submission.perf_submit_pass = perf_submit ? perf_submit->counterPassIndex : 0;
1703
1704 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1705 RecordSubmitCommandBuffer(submission, submit->pCommandBufferInfos[i].commandBuffer);
1706 }
1707 submission.fence = submit_idx == (submitCount - 1) ? fence : VK_NULL_HANDLE;
1708 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001709 }
1710
1711 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001712 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001713 }
1714}
1715
1716void ValidationStateTracker::PostCallRecordAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
1717 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory,
1718 VkResult result) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001719 if (VK_SUCCESS != result) {
1720 return;
locke-lunargd556cc32019-09-17 01:21:23 -06001721 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001722 const auto &memory_type = phys_dev_mem_props.memoryTypes[pAllocateInfo->memoryTypeIndex];
1723 const auto &memory_heap = phys_dev_mem_props.memoryHeaps[memory_type.heapIndex];
1724 auto fake_address = fake_memory.Alloc(pAllocateInfo->allocationSize);
1725
1726 layer_data::optional<DedicatedBinding> dedicated_binding;
1727
1728 auto dedicated = LvlFindInChain<VkMemoryDedicatedAllocateInfo>(pAllocateInfo->pNext);
1729 if (dedicated) {
1730 if (dedicated->buffer) {
1731 const auto *buffer_state = GetBufferState(dedicated->buffer);
1732 assert(buffer_state);
1733 if (!buffer_state) {
1734 return;
1735 }
1736 dedicated_binding.emplace(dedicated->buffer, buffer_state->createInfo);
1737 } else if (dedicated->image) {
1738 const auto *image_state = GetImageState(dedicated->image);
1739 assert(image_state);
1740 if (!image_state) {
1741 return;
1742 }
1743 dedicated_binding.emplace(dedicated->image, image_state->createInfo);
1744 }
1745 }
1746 memObjMap[*pMemory] = std::make_shared<DEVICE_MEMORY_STATE>(*pMemory, pAllocateInfo, fake_address, memory_type, memory_heap,
1747 std::move(dedicated_binding));
locke-lunargd556cc32019-09-17 01:21:23 -06001748 return;
1749}
1750
1751void ValidationStateTracker::PreCallRecordFreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
1752 if (!mem) return;
1753 DEVICE_MEMORY_STATE *mem_info = GetDevMemState(mem);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001754 if (!mem_info) return;
locke-lunargd556cc32019-09-17 01:21:23 -06001755 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001756 mem_info->Destroy();
John Zulauf79952712020-04-07 11:25:54 -06001757 fake_memory.Free(mem_info->fake_base_address);
locke-lunargd556cc32019-09-17 01:21:23 -06001758 memObjMap.erase(mem);
1759}
1760
1761void ValidationStateTracker::PostCallRecordQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo,
1762 VkFence fence, VkResult result) {
1763 if (result != VK_SUCCESS) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001764 auto queue_state = GetQueueState(queue);
locke-lunargd556cc32019-09-17 01:21:23 -06001765
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001766 uint64_t early_retire_seq = RecordSubmitFence(queue_state, fence, bindInfoCount);
locke-lunargd556cc32019-09-17 01:21:23 -06001767
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001768 for (uint32_t bind_idx = 0; bind_idx < bindInfoCount; ++bind_idx) {
1769 const VkBindSparseInfo &bind_info = pBindInfo[bind_idx];
locke-lunargd556cc32019-09-17 01:21:23 -06001770 // Track objects tied to memory
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001771 for (uint32_t j = 0; j < bind_info.bufferBindCount; j++) {
1772 for (uint32_t k = 0; k < bind_info.pBufferBinds[j].bindCount; k++) {
1773 auto sparse_binding = bind_info.pBufferBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001774 auto buffer_state = GetBufferState(bind_info.pBufferBinds[j].buffer);
1775 auto mem_state = GetDevMemShared(sparse_binding.memory);
1776 if (buffer_state && mem_state) {
1777 buffer_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1778 }
locke-lunargd556cc32019-09-17 01:21:23 -06001779 }
1780 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001781 for (uint32_t j = 0; j < bind_info.imageOpaqueBindCount; j++) {
1782 for (uint32_t k = 0; k < bind_info.pImageOpaqueBinds[j].bindCount; k++) {
1783 auto sparse_binding = bind_info.pImageOpaqueBinds[j].pBinds[k];
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001784 auto image_state = GetImageState(bind_info.pImageOpaqueBinds[j].image);
1785 auto mem_state = GetDevMemShared(sparse_binding.memory);
1786 if (image_state && mem_state) {
1787 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, sparse_binding.size);
1788 }
locke-lunargd556cc32019-09-17 01:21:23 -06001789 }
1790 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001791 for (uint32_t j = 0; j < bind_info.imageBindCount; j++) {
1792 for (uint32_t k = 0; k < bind_info.pImageBinds[j].bindCount; k++) {
1793 auto sparse_binding = bind_info.pImageBinds[j].pBinds[k];
locke-lunargd556cc32019-09-17 01:21:23 -06001794 // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data
1795 VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001796 auto image_state = GetImageState(bind_info.pImageBinds[j].image);
1797 auto mem_state = GetDevMemShared(sparse_binding.memory);
1798 if (image_state && mem_state) {
1799 image_state->SetSparseMemBinding(mem_state, sparse_binding.memoryOffset, size);
1800 }
locke-lunargd556cc32019-09-17 01:21:23 -06001801 }
1802 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001803 CB_SUBMISSION submission;
1804 const uint64_t next_seq = queue_state->seq + queue_state->submissions.size() + 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001805 for (uint32_t i = 0; i < bind_info.waitSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001806 RecordSubmitWaitSemaphore(submission, queue, bind_info.pWaitSemaphores[i], 0, next_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001807 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001808 bool retire_early = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001809 for (uint32_t i = 0; i < bind_info.signalSemaphoreCount; ++i) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001810 retire_early |= RecordSubmitSignalSemaphore(submission, queue, bind_info.pSignalSemaphores[i], 0, next_seq);
1811 }
1812 // Retire work up until this submit early, we will not see the wait that corresponds to this signal
1813 if (retire_early) {
1814 early_retire_seq = std::max(early_retire_seq, queue_state->seq + queue_state->submissions.size() + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06001815 }
1816
Jeremy Gebben74aa7622020-12-15 11:18:00 -07001817 submission.fence = bind_idx == (bindInfoCount - 1) ? fence : VK_NULL_HANDLE;
1818 queue_state->submissions.emplace_back(std::move(submission));
locke-lunargd556cc32019-09-17 01:21:23 -06001819 }
1820
1821 if (early_retire_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001822 RetireWorkOnQueue(queue_state, early_retire_seq);
locke-lunargd556cc32019-09-17 01:21:23 -06001823 }
1824}
1825
1826void ValidationStateTracker::PostCallRecordCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
1827 const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore,
1828 VkResult result) {
1829 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001830 semaphoreMap[*pSemaphore] = std::make_shared<SEMAPHORE_STATE>(*pSemaphore, LvlFindInChain<VkSemaphoreTypeCreateInfo>(pCreateInfo->pNext));
locke-lunargd556cc32019-09-17 01:21:23 -06001831}
1832
Mike Schuchardt2df08912020-12-15 16:28:09 -08001833void ValidationStateTracker::RecordImportSemaphoreState(VkSemaphore semaphore, VkExternalSemaphoreHandleTypeFlagBits handle_type,
1834 VkSemaphoreImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06001835 SEMAPHORE_STATE *sema_node = GetSemaphoreState(semaphore);
1836 if (sema_node && sema_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08001837 if ((handle_type == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06001838 sema_node->scope == kSyncScopeInternal) {
1839 sema_node->scope = kSyncScopeExternalTemporary;
1840 } else {
1841 sema_node->scope = kSyncScopeExternalPermanent;
1842 }
1843 }
1844}
1845
Mike Schuchardt2df08912020-12-15 16:28:09 -08001846void ValidationStateTracker::PostCallRecordSignalSemaphoreKHR(VkDevice device, const VkSemaphoreSignalInfo *pSignalInfo,
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001847 VkResult result) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001848 auto *semaphore_state = GetSemaphoreState(pSignalInfo->semaphore);
1849 semaphore_state->payload = pSignalInfo->value;
Juan A. Suarez Romerof3024162019-10-31 17:57:50 +00001850}
1851
locke-lunargd556cc32019-09-17 01:21:23 -06001852void ValidationStateTracker::RecordMappedMemory(VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, void **ppData) {
1853 auto mem_info = GetDevMemState(mem);
1854 if (mem_info) {
1855 mem_info->mapped_range.offset = offset;
1856 mem_info->mapped_range.size = size;
1857 mem_info->p_driver_data = *ppData;
1858 }
1859}
1860
1861void ValidationStateTracker::RetireFence(VkFence fence) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001862 auto fence_state = GetFenceState(fence);
1863 if (fence_state && fence_state->scope == kSyncScopeInternal) {
1864 if (fence_state->signaler.first != VK_NULL_HANDLE) {
locke-lunargd556cc32019-09-17 01:21:23 -06001865 // Fence signaller is a queue -- use this as proof that prior operations on that queue have completed.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001866 RetireWorkOnQueue(GetQueueState(fence_state->signaler.first), fence_state->signaler.second);
locke-lunargd556cc32019-09-17 01:21:23 -06001867 } else {
1868 // Fence signaller is the WSI. We're not tracking what the WSI op actually /was/ in CV yet, but we need to mark
1869 // the fence as retired.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001870 fence_state->state = FENCE_RETIRED;
locke-lunargd556cc32019-09-17 01:21:23 -06001871 }
1872 }
1873}
1874
1875void ValidationStateTracker::PostCallRecordWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
1876 VkBool32 waitAll, uint64_t timeout, VkResult result) {
1877 if (VK_SUCCESS != result) return;
1878
1879 // When we know that all fences are complete we can clean/remove their CBs
1880 if ((VK_TRUE == waitAll) || (1 == fenceCount)) {
1881 for (uint32_t i = 0; i < fenceCount; i++) {
1882 RetireFence(pFences[i]);
1883 }
1884 }
1885 // NOTE : Alternate case not handled here is when some fences have completed. In
1886 // this case for app to guarantee which fences completed it will have to call
1887 // vkGetFenceStatus() at which point we'll clean/remove their CBs if complete.
1888}
1889
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001890void ValidationStateTracker::RetireTimelineSemaphore(VkSemaphore semaphore, uint64_t until_payload) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001891 auto semaphore_state = GetSemaphoreState(semaphore);
1892 if (semaphore_state) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001893 for (auto &pair : queueMap) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001894 QUEUE_STATE &queue_state = pair.second;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001895 uint64_t max_seq = 0;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001896 for (const auto &submission : queue_state.submissions) {
1897 for (const auto &signal_semaphore : submission.signalSemaphores) {
1898 if (signal_semaphore.semaphore == semaphore && signal_semaphore.payload <= until_payload) {
1899 if (signal_semaphore.seq > max_seq) {
1900 max_seq = signal_semaphore.seq;
Tony-LunarG47d5e272020-04-07 15:35:55 -06001901 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001902 }
1903 }
1904 }
Tony-LunarG47d5e272020-04-07 15:35:55 -06001905 if (max_seq) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001906 RetireWorkOnQueue(&queue_state, max_seq);
Tony-LunarG47d5e272020-04-07 15:35:55 -06001907 }
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001908 }
1909 }
1910}
1911
John Zulauff89de662020-04-13 18:57:34 -06001912void ValidationStateTracker::RecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1913 VkResult result) {
Jakub Okoński04feb3b2020-02-01 18:31:01 +01001914 if (VK_SUCCESS != result) return;
1915
1916 for (uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++) {
1917 RetireTimelineSemaphore(pWaitInfo->pSemaphores[i], pWaitInfo->pValues[i]);
1918 }
1919}
1920
John Zulauff89de662020-04-13 18:57:34 -06001921void ValidationStateTracker::PostCallRecordWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout,
1922 VkResult result) {
1923 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1924}
1925
1926void ValidationStateTracker::PostCallRecordWaitSemaphoresKHR(VkDevice device, const VkSemaphoreWaitInfo *pWaitInfo,
1927 uint64_t timeout, VkResult result) {
1928 RecordWaitSemaphores(device, pWaitInfo, timeout, result);
1929}
1930
Adrian Coca Lorentec7d76102020-09-28 13:58:16 +02001931void ValidationStateTracker::RecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1932 VkResult result) {
1933 if (VK_SUCCESS != result) return;
1934
1935 RetireTimelineSemaphore(semaphore, *pValue);
1936}
1937
1938void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1939 VkResult result) {
1940 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1941}
1942void ValidationStateTracker::PostCallRecordGetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t *pValue,
1943 VkResult result) {
1944 RecordGetSemaphoreCounterValue(device, semaphore, pValue, result);
1945}
1946
locke-lunargd556cc32019-09-17 01:21:23 -06001947void ValidationStateTracker::PostCallRecordGetFenceStatus(VkDevice device, VkFence fence, VkResult result) {
1948 if (VK_SUCCESS != result) return;
1949 RetireFence(fence);
1950}
1951
1952void ValidationStateTracker::RecordGetDeviceQueueState(uint32_t queue_family_index, VkQueue queue) {
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06001953 queueMap.emplace(queue, QUEUE_STATE(queue, queue_family_index));
locke-lunargd556cc32019-09-17 01:21:23 -06001954}
1955
1956void ValidationStateTracker::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
1957 VkQueue *pQueue) {
1958 RecordGetDeviceQueueState(queueFamilyIndex, *pQueue);
1959}
1960
1961void ValidationStateTracker::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
1962 RecordGetDeviceQueueState(pQueueInfo->queueFamilyIndex, *pQueue);
1963}
1964
1965void ValidationStateTracker::PostCallRecordQueueWaitIdle(VkQueue queue, VkResult result) {
1966 if (VK_SUCCESS != result) return;
1967 QUEUE_STATE *queue_state = GetQueueState(queue);
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001968 RetireWorkOnQueue(queue_state, queue_state->seq + queue_state->submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001969}
1970
1971void ValidationStateTracker::PostCallRecordDeviceWaitIdle(VkDevice device, VkResult result) {
1972 if (VK_SUCCESS != result) return;
1973 for (auto &queue : queueMap) {
Jeff Bolz8041c5b2019-10-20 22:14:20 -05001974 RetireWorkOnQueue(&queue.second, queue.second.seq + queue.second.submissions.size());
locke-lunargd556cc32019-09-17 01:21:23 -06001975 }
1976}
1977
1978void ValidationStateTracker::PreCallRecordDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
1979 if (!fence) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001980 auto fence_state = GetFenceState(fence);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001981 fence_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06001982 fenceMap.erase(fence);
1983}
1984
1985void ValidationStateTracker::PreCallRecordDestroySemaphore(VkDevice device, VkSemaphore semaphore,
1986 const VkAllocationCallbacks *pAllocator) {
1987 if (!semaphore) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001988 auto semaphore_state = GetSemaphoreState(semaphore);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001989 semaphore_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06001990 semaphoreMap.erase(semaphore);
1991}
1992
1993void ValidationStateTracker::PreCallRecordDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
1994 if (!event) return;
John Zulauf48057322020-12-02 11:59:31 -07001995 EVENT_STATE *event_state = Get<EVENT_STATE>(event);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001996 event_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06001997 eventMap.erase(event);
1998}
1999
2000void ValidationStateTracker::PreCallRecordDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
2001 const VkAllocationCallbacks *pAllocator) {
2002 if (!queryPool) return;
2003 QUERY_POOL_STATE *qp_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002004 qp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002005 queryPoolMap.erase(queryPool);
2006}
2007
locke-lunargd556cc32019-09-17 01:21:23 -06002008void ValidationStateTracker::UpdateBindBufferMemoryState(VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memoryOffset) {
2009 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2010 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002011 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002012 auto mem_state = GetDevMemShared(mem);
2013 if (mem_state) {
2014 buffer_state->SetMemBinding(mem_state, memoryOffset);
2015 }
locke-lunargd556cc32019-09-17 01:21:23 -06002016 }
2017}
2018
2019void ValidationStateTracker::PostCallRecordBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
2020 VkDeviceSize memoryOffset, VkResult result) {
2021 if (VK_SUCCESS != result) return;
2022 UpdateBindBufferMemoryState(buffer, mem, memoryOffset);
2023}
2024
2025void ValidationStateTracker::PostCallRecordBindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002026 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002027 for (uint32_t i = 0; i < bindInfoCount; i++) {
2028 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2029 }
2030}
2031
2032void ValidationStateTracker::PostCallRecordBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002033 const VkBindBufferMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002034 for (uint32_t i = 0; i < bindInfoCount; i++) {
2035 UpdateBindBufferMemoryState(pBindInfos[i].buffer, pBindInfos[i].memory, pBindInfos[i].memoryOffset);
2036 }
2037}
2038
Spencer Fricke6c127102020-04-16 06:25:20 -07002039void ValidationStateTracker::RecordGetBufferMemoryRequirementsState(VkBuffer buffer) {
locke-lunargd556cc32019-09-17 01:21:23 -06002040 BUFFER_STATE *buffer_state = GetBufferState(buffer);
2041 if (buffer_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002042 buffer_state->memory_requirements_checked = true;
2043 }
2044}
2045
2046void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
2047 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002048 RecordGetBufferMemoryRequirementsState(buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002049}
2050
2051void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002052 const VkBufferMemoryRequirementsInfo2 *pInfo,
2053 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002054 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002055}
2056
2057void ValidationStateTracker::PostCallRecordGetBufferMemoryRequirements2KHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08002058 const VkBufferMemoryRequirementsInfo2 *pInfo,
2059 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002060 RecordGetBufferMemoryRequirementsState(pInfo->buffer);
locke-lunargd556cc32019-09-17 01:21:23 -06002061}
2062
Spencer Fricke6c127102020-04-16 06:25:20 -07002063void ValidationStateTracker::RecordGetImageMemoryRequirementsState(VkImage image, const VkImageMemoryRequirementsInfo2 *pInfo) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002064 const VkImagePlaneMemoryRequirementsInfo *plane_info =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002065 (pInfo == nullptr) ? nullptr : LvlFindInChain<VkImagePlaneMemoryRequirementsInfo>(pInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06002066 IMAGE_STATE *image_state = GetImageState(image);
2067 if (image_state) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002068 if (plane_info != nullptr) {
2069 // Multi-plane image
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002070 if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_0_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002071 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002072 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_1_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002073 image_state->memory_requirements_checked[1] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002074 } else if (plane_info->planeAspect == VK_IMAGE_ASPECT_PLANE_2_BIT) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002075 image_state->memory_requirements_checked[2] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002076 }
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002077 } else if (!image_state->disjoint) {
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002078 // Single Plane image
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06002079 image_state->memory_requirements_checked[0] = true;
sfricke-samsungd7ea5de2020-04-08 09:19:18 -07002080 }
locke-lunargd556cc32019-09-17 01:21:23 -06002081 }
2082}
2083
2084void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements(VkDevice device, VkImage image,
2085 VkMemoryRequirements *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002086 RecordGetImageMemoryRequirementsState(image, nullptr);
locke-lunargd556cc32019-09-17 01:21:23 -06002087}
2088
2089void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo,
2090 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002091 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002092}
2093
2094void ValidationStateTracker::PostCallRecordGetImageMemoryRequirements2KHR(VkDevice device,
2095 const VkImageMemoryRequirementsInfo2 *pInfo,
2096 VkMemoryRequirements2 *pMemoryRequirements) {
Spencer Fricke6c127102020-04-16 06:25:20 -07002097 RecordGetImageMemoryRequirementsState(pInfo->image, pInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002098}
2099
2100static void RecordGetImageSparseMemoryRequirementsState(IMAGE_STATE *image_state,
2101 VkSparseImageMemoryRequirements *sparse_image_memory_requirements) {
2102 image_state->sparse_requirements.emplace_back(*sparse_image_memory_requirements);
2103 if (sparse_image_memory_requirements->formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) {
2104 image_state->sparse_metadata_required = true;
2105 }
2106}
2107
2108void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements(
2109 VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
2110 VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
2111 auto image_state = GetImageState(image);
2112 image_state->get_sparse_reqs_called = true;
2113 if (!pSparseMemoryRequirements) return;
2114 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2115 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i]);
2116 }
2117}
2118
2119void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002120 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2121 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002122 auto image_state = GetImageState(pInfo->image);
2123 image_state->get_sparse_reqs_called = true;
2124 if (!pSparseMemoryRequirements) return;
2125 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2126 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2127 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2128 }
2129}
2130
2131void ValidationStateTracker::PostCallRecordGetImageSparseMemoryRequirements2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002132 VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount,
2133 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) {
locke-lunargd556cc32019-09-17 01:21:23 -06002134 auto image_state = GetImageState(pInfo->image);
2135 image_state->get_sparse_reqs_called = true;
2136 if (!pSparseMemoryRequirements) return;
2137 for (uint32_t i = 0; i < *pSparseMemoryRequirementCount; i++) {
2138 assert(!pSparseMemoryRequirements[i].pNext); // TODO: If an extension is ever added here we need to handle it
2139 RecordGetImageSparseMemoryRequirementsState(image_state, &pSparseMemoryRequirements[i].memoryRequirements);
2140 }
2141}
2142
2143void ValidationStateTracker::PreCallRecordDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
2144 const VkAllocationCallbacks *pAllocator) {
2145 if (!shaderModule) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002146 auto shader_module_state = GetShaderModuleState(shaderModule);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002147 shader_module_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002148 shaderModuleMap.erase(shaderModule);
2149}
2150
2151void ValidationStateTracker::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline,
2152 const VkAllocationCallbacks *pAllocator) {
2153 if (!pipeline) return;
2154 PIPELINE_STATE *pipeline_state = GetPipelineState(pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06002155 // Any bound cmd buffers are now invalid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002156 pipeline_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002157 pipelineMap.erase(pipeline);
2158}
2159
2160void ValidationStateTracker::PreCallRecordDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
2161 const VkAllocationCallbacks *pAllocator) {
2162 if (!pipelineLayout) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002163 auto pipeline_layout_state = GetPipelineLayout(pipelineLayout);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002164 pipeline_layout_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002165 pipelineLayoutMap.erase(pipelineLayout);
2166}
2167
2168void ValidationStateTracker::PreCallRecordDestroySampler(VkDevice device, VkSampler sampler,
2169 const VkAllocationCallbacks *pAllocator) {
2170 if (!sampler) return;
2171 SAMPLER_STATE *sampler_state = GetSamplerState(sampler);
locke-lunargd556cc32019-09-17 01:21:23 -06002172 // Any bound cmd buffers are now invalid
2173 if (sampler_state) {
Yuly Novikov424cdd52020-05-26 16:45:12 -04002174 if (sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2175 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
2176 custom_border_color_sampler_count--;
2177 }
2178
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002179 sampler_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002180 }
2181 samplerMap.erase(sampler);
2182}
2183
2184void ValidationStateTracker::PreCallRecordDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
2185 const VkAllocationCallbacks *pAllocator) {
2186 if (!descriptorSetLayout) return;
2187 auto layout_it = descriptorSetLayoutMap.find(descriptorSetLayout);
2188 if (layout_it != descriptorSetLayoutMap.end()) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002189 layout_it->second.get()->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002190 descriptorSetLayoutMap.erase(layout_it);
2191 }
2192}
2193
2194void ValidationStateTracker::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2195 const VkAllocationCallbacks *pAllocator) {
2196 if (!descriptorPool) return;
2197 DESCRIPTOR_POOL_STATE *desc_pool_state = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002198 if (desc_pool_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002199 // Free sets that were in this pool
John Zulauf79f06582021-02-27 18:38:39 -07002200 for (auto *ds : desc_pool_state->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002201 FreeDescriptorSet(ds);
2202 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002203 desc_pool_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002204 descriptorPoolMap.erase(descriptorPool);
2205 }
2206}
2207
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002208// 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 -06002209void ValidationStateTracker::FreeCommandBufferStates(COMMAND_POOL_STATE *pool_state, const uint32_t command_buffer_count,
2210 const VkCommandBuffer *command_buffers) {
2211 for (uint32_t i = 0; i < command_buffer_count; i++) {
2212 auto cb_state = GetCBState(command_buffers[i]);
2213 // Remove references to command buffer's state and delete
2214 if (cb_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002215 cb_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002216 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002217 // Remove CBState from CB map
2218 pool_state->commandBuffers.erase(command_buffers[i]);
2219 commandBufferMap.erase(command_buffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002220 }
2221}
2222
2223void ValidationStateTracker::PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
2224 uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002225 auto pool = GetCommandPoolState(commandPool);
2226 FreeCommandBufferStates(pool, commandBufferCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06002227}
2228
2229void ValidationStateTracker::PostCallRecordCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
2230 const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool,
2231 VkResult result) {
2232 if (VK_SUCCESS != result) return;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06002233 auto queue_flags = GetPhysicalDeviceState()->queue_family_properties[pCreateInfo->queueFamilyIndex].queueFlags;
2234 commandPoolMap[*pCommandPool] = std::make_shared<COMMAND_POOL_STATE>(*pCommandPool, pCreateInfo, queue_flags);
locke-lunargd556cc32019-09-17 01:21:23 -06002235}
2236
2237void ValidationStateTracker::PostCallRecordCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
2238 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool,
2239 VkResult result) {
2240 if (VK_SUCCESS != result) return;
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002241
2242 uint32_t index_count = 0, n_perf_pass = 0;
2243 bool has_cb = false, has_rb = false;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002244 if (pCreateInfo->queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002245 const auto *perf = LvlFindInChain<VkQueryPoolPerformanceCreateInfoKHR>(pCreateInfo->pNext);
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002246 index_count = perf->counterIndexCount;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002247
Mark Lobodzinski7e948e42020-09-09 10:23:36 -06002248 const QUEUE_FAMILY_PERF_COUNTERS &counters = *physical_device_state->perf_counters[perf->queueFamilyIndex];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002249 for (uint32_t i = 0; i < perf->counterIndexCount; i++) {
2250 const auto &counter = counters.counters[perf->pCounterIndices[i]];
2251 switch (counter.scope) {
2252 case VK_QUERY_SCOPE_COMMAND_BUFFER_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002253 has_cb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002254 break;
2255 case VK_QUERY_SCOPE_RENDER_PASS_KHR:
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002256 has_rb = true;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002257 break;
2258 default:
2259 break;
2260 }
2261 }
2262
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002263 DispatchGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physical_device_state->phys_device, perf, &n_perf_pass);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01002264 }
2265
Jeremy Gebbene9206ee2021-06-02 12:44:41 -06002266 queryPoolMap[*pQueryPool] =
2267 std::make_shared<QUERY_POOL_STATE>(*pQueryPool, pCreateInfo, index_count, n_perf_pass, has_cb, has_rb);
locke-lunargd556cc32019-09-17 01:21:23 -06002268
2269 QueryObject query_obj{*pQueryPool, 0u};
2270 for (uint32_t i = 0; i < pCreateInfo->queryCount; ++i) {
2271 query_obj.query = i;
2272 queryToStateMap[query_obj] = QUERYSTATE_UNKNOWN;
2273 }
2274}
2275
2276void ValidationStateTracker::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
2277 const VkAllocationCallbacks *pAllocator) {
2278 if (!commandPool) return;
2279 COMMAND_POOL_STATE *cp_state = GetCommandPoolState(commandPool);
2280 // Remove cmdpool from cmdpoolmap, after freeing layer data for the command buffers
2281 // "When a pool is destroyed, all command buffers allocated from the pool are freed."
2282 if (cp_state) {
2283 // Create a vector, as FreeCommandBufferStates deletes from cp_state->commandBuffers during iteration.
2284 std::vector<VkCommandBuffer> cb_vec{cp_state->commandBuffers.begin(), cp_state->commandBuffers.end()};
2285 FreeCommandBufferStates(cp_state, static_cast<uint32_t>(cb_vec.size()), cb_vec.data());
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002286 cp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002287 commandPoolMap.erase(commandPool);
2288 }
2289}
2290
2291void ValidationStateTracker::PostCallRecordResetCommandPool(VkDevice device, VkCommandPool commandPool,
2292 VkCommandPoolResetFlags flags, VkResult result) {
2293 if (VK_SUCCESS != result) return;
2294 // Reset all of the CBs allocated from this pool
2295 auto command_pool_state = GetCommandPoolState(commandPool);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002296 for (auto cmd_buffer : command_pool_state->commandBuffers) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002297 auto cb_state = GetCBState(cmd_buffer);
2298 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002299 }
2300}
2301
2302void ValidationStateTracker::PostCallRecordResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
2303 VkResult result) {
2304 for (uint32_t i = 0; i < fenceCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002305 auto fence_state = GetFenceState(pFences[i]);
2306 if (fence_state) {
2307 if (fence_state->scope == kSyncScopeInternal) {
2308 fence_state->state = FENCE_UNSIGNALED;
2309 } else if (fence_state->scope == kSyncScopeExternalTemporary) {
2310 fence_state->scope = kSyncScopeInternal;
locke-lunargd556cc32019-09-17 01:21:23 -06002311 }
2312 }
2313 }
2314}
2315
locke-lunargd556cc32019-09-17 01:21:23 -06002316void ValidationStateTracker::PreCallRecordDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
2317 const VkAllocationCallbacks *pAllocator) {
2318 if (!framebuffer) return;
2319 FRAMEBUFFER_STATE *framebuffer_state = GetFramebufferState(framebuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002320 framebuffer_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002321 frameBufferMap.erase(framebuffer);
2322}
2323
2324void ValidationStateTracker::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
2325 const VkAllocationCallbacks *pAllocator) {
2326 if (!renderPass) return;
2327 RENDER_PASS_STATE *rp_state = GetRenderPassState(renderPass);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002328 rp_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06002329 renderPassMap.erase(renderPass);
2330}
2331
2332void ValidationStateTracker::PostCallRecordCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
2333 const VkAllocationCallbacks *pAllocator, VkFence *pFence, VkResult result) {
2334 if (VK_SUCCESS != result) return;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002335 fenceMap[*pFence] = std::make_shared<FENCE_STATE>(*pFence, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002336}
2337
2338bool ValidationStateTracker::PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2339 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2340 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002341 void *cgpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002342 // Set up the state that CoreChecks, gpu_validation and later StateTracker Record will use.
2343 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2344 cgpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2345 cgpl_state->pipe_state.reserve(count);
2346 for (uint32_t i = 0; i < count; i++) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002347 cgpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
Jeff Bolz6ae39612019-10-11 20:57:36 -05002348 (cgpl_state->pipe_state)[i]->initGraphicsPipeline(this, &pCreateInfos[i], GetRenderPassShared(pCreateInfos[i].renderPass));
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002349 (cgpl_state->pipe_state)[i]->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002350 }
2351 return false;
2352}
2353
2354void ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2355 const VkGraphicsPipelineCreateInfo *pCreateInfos,
2356 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2357 VkResult result, void *cgpl_state_data) {
2358 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
2359 // This API may create pipelines regardless of the return value
2360 for (uint32_t i = 0; i < count; i++) {
2361 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002362 (cgpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002363 pipelineMap[pPipelines[i]] = std::move((cgpl_state->pipe_state)[i]);
2364 }
2365 }
2366 cgpl_state->pipe_state.clear();
2367}
2368
2369bool ValidationStateTracker::PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2370 const VkComputePipelineCreateInfo *pCreateInfos,
2371 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002372 void *ccpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002373 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2374 ccpl_state->pCreateInfos = pCreateInfos; // GPU validation can alter this, so we have to set a default value for the Chassis
2375 ccpl_state->pipe_state.reserve(count);
2376 for (uint32_t i = 0; i < count; i++) {
2377 // Create and initialize internal tracking data structure
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002378 ccpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
locke-lunargd556cc32019-09-17 01:21:23 -06002379 ccpl_state->pipe_state.back()->initComputePipeline(this, &pCreateInfos[i]);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002380 ccpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002381 }
2382 return false;
2383}
2384
2385void ValidationStateTracker::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
2386 const VkComputePipelineCreateInfo *pCreateInfos,
2387 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
2388 VkResult result, void *ccpl_state_data) {
2389 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
2390
2391 // This API may create pipelines regardless of the return value
2392 for (uint32_t i = 0; i < count; i++) {
2393 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002394 (ccpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002395 pipelineMap[pPipelines[i]] = std::move((ccpl_state->pipe_state)[i]);
2396 }
2397 }
2398 ccpl_state->pipe_state.clear();
2399}
2400
2401bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache,
2402 uint32_t count,
2403 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2404 const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002405 VkPipeline *pPipelines, void *crtpl_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002406 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2407 crtpl_state->pipe_state.reserve(count);
2408 for (uint32_t i = 0; i < count; i++) {
2409 // Create and initialize internal tracking data structure
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002410 crtpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002411 crtpl_state->pipe_state.back()->initRayTracingPipeline(this, &pCreateInfos[i]);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002412 crtpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
locke-lunargd556cc32019-09-17 01:21:23 -06002413 }
2414 return false;
2415}
2416
2417void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(
2418 VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
2419 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines, VkResult result, void *crtpl_state_data) {
2420 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
2421 // This API may create pipelines regardless of the return value
2422 for (uint32_t i = 0; i < count; i++) {
2423 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002424 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002425 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2426 }
2427 }
2428 crtpl_state->pipe_state.clear();
2429}
2430
sourav parmarcd5fb182020-07-17 12:58:44 -07002431bool ValidationStateTracker::PreCallValidateCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2432 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002433 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2434 const VkAllocationCallbacks *pAllocator,
2435 VkPipeline *pPipelines, void *crtpl_state_data) const {
2436 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2437 crtpl_state->pipe_state.reserve(count);
2438 for (uint32_t i = 0; i < count; i++) {
2439 // Create and initialize internal tracking data structure
2440 crtpl_state->pipe_state.push_back(std::make_shared<PIPELINE_STATE>());
2441 crtpl_state->pipe_state.back()->initRayTracingPipeline(this, &pCreateInfos[i]);
2442 crtpl_state->pipe_state.back()->pipeline_layout = GetPipelineLayoutShared(pCreateInfos[i].layout);
2443 }
2444 return false;
2445}
2446
sourav parmarcd5fb182020-07-17 12:58:44 -07002447void ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
2448 VkPipelineCache pipelineCache, uint32_t count,
2449 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
2450 const VkAllocationCallbacks *pAllocator,
2451 VkPipeline *pPipelines, VkResult result,
2452 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002453 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
2454 // This API may create pipelines regardless of the return value
2455 for (uint32_t i = 0; i < count; i++) {
2456 if (pPipelines[i] != VK_NULL_HANDLE) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002457 (crtpl_state->pipe_state)[i]->SetHandle(pPipelines[i]);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05002458 pipelineMap[pPipelines[i]] = std::move((crtpl_state->pipe_state)[i]);
2459 }
2460 }
2461 crtpl_state->pipe_state.clear();
2462}
2463
locke-lunargd556cc32019-09-17 01:21:23 -06002464void ValidationStateTracker::PostCallRecordCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
2465 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler,
2466 VkResult result) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002467 samplerMap[*pSampler] = std::make_shared<SAMPLER_STATE>(pSampler, pCreateInfo);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002468 if (pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
2469 pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
Tony-LunarG7337b312020-04-15 16:40:25 -06002470 custom_border_color_sampler_count++;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002471 }
locke-lunargd556cc32019-09-17 01:21:23 -06002472}
2473
2474void ValidationStateTracker::PostCallRecordCreateDescriptorSetLayout(VkDevice device,
2475 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
2476 const VkAllocationCallbacks *pAllocator,
2477 VkDescriptorSetLayout *pSetLayout, VkResult result) {
2478 if (VK_SUCCESS != result) return;
2479 descriptorSetLayoutMap[*pSetLayout] = std::make_shared<cvdescriptorset::DescriptorSetLayout>(pCreateInfo, *pSetLayout);
2480}
2481
2482// For repeatable sorting, not very useful for "memory in range" search
2483struct PushConstantRangeCompare {
2484 bool operator()(const VkPushConstantRange *lhs, const VkPushConstantRange *rhs) const {
2485 if (lhs->offset == rhs->offset) {
2486 if (lhs->size == rhs->size) {
2487 // The comparison is arbitrary, but avoids false aliasing by comparing all fields.
2488 return lhs->stageFlags < rhs->stageFlags;
2489 }
2490 // If the offsets are the same then sorting by the end of range is useful for validation
2491 return lhs->size < rhs->size;
2492 }
2493 return lhs->offset < rhs->offset;
2494 }
2495};
2496
2497static PushConstantRangesDict push_constant_ranges_dict;
2498
2499PushConstantRangesId GetCanonicalId(const VkPipelineLayoutCreateInfo *info) {
2500 if (!info->pPushConstantRanges) {
2501 // Hand back the empty entry (creating as needed)...
2502 return push_constant_ranges_dict.look_up(PushConstantRanges());
2503 }
2504
2505 // Sort the input ranges to ensure equivalent ranges map to the same id
2506 std::set<const VkPushConstantRange *, PushConstantRangeCompare> sorted;
2507 for (uint32_t i = 0; i < info->pushConstantRangeCount; i++) {
2508 sorted.insert(info->pPushConstantRanges + i);
2509 }
2510
Jeremy Hayesf34b9fb2019-12-06 09:37:03 -07002511 PushConstantRanges ranges;
2512 ranges.reserve(sorted.size());
John Zulauf79f06582021-02-27 18:38:39 -07002513 for (const auto *range : sorted) {
locke-lunargd556cc32019-09-17 01:21:23 -06002514 ranges.emplace_back(*range);
2515 }
2516 return push_constant_ranges_dict.look_up(std::move(ranges));
2517}
2518
2519// Dictionary of canoncial form of the pipeline set layout of descriptor set layouts
2520static PipelineLayoutSetLayoutsDict pipeline_layout_set_layouts_dict;
2521
2522// Dictionary of canonical form of the "compatible for set" records
2523static PipelineLayoutCompatDict pipeline_layout_compat_dict;
2524
2525static PipelineLayoutCompatId GetCanonicalId(const uint32_t set_index, const PushConstantRangesId pcr_id,
2526 const PipelineLayoutSetLayoutsId set_layouts_id) {
2527 return pipeline_layout_compat_dict.look_up(PipelineLayoutCompatDef(set_index, pcr_id, set_layouts_id));
2528}
2529
2530void ValidationStateTracker::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
2531 const VkAllocationCallbacks *pAllocator,
2532 VkPipelineLayout *pPipelineLayout, VkResult result) {
2533 if (VK_SUCCESS != result) return;
2534
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002535 auto pipeline_layout_state = std::make_shared<PIPELINE_LAYOUT_STATE>(*pPipelineLayout);
locke-lunargd556cc32019-09-17 01:21:23 -06002536 pipeline_layout_state->set_layouts.resize(pCreateInfo->setLayoutCount);
2537 PipelineLayoutSetLayoutsDef set_layouts(pCreateInfo->setLayoutCount);
2538 for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; ++i) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05002539 pipeline_layout_state->set_layouts[i] = GetDescriptorSetLayoutShared(pCreateInfo->pSetLayouts[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002540 set_layouts[i] = pipeline_layout_state->set_layouts[i]->GetLayoutId();
2541 }
2542
2543 // Get canonical form IDs for the "compatible for set" contents
2544 pipeline_layout_state->push_constant_ranges = GetCanonicalId(pCreateInfo);
2545 auto set_layouts_id = pipeline_layout_set_layouts_dict.look_up(set_layouts);
2546 pipeline_layout_state->compat_for_set.reserve(pCreateInfo->setLayoutCount);
2547
2548 // Create table of "compatible for set N" cannonical forms for trivial accept validation
2549 for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; ++i) {
2550 pipeline_layout_state->compat_for_set.emplace_back(
2551 GetCanonicalId(i, pipeline_layout_state->push_constant_ranges, set_layouts_id));
2552 }
2553 pipelineLayoutMap[*pPipelineLayout] = std::move(pipeline_layout_state);
2554}
2555
2556void ValidationStateTracker::PostCallRecordCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
2557 const VkAllocationCallbacks *pAllocator,
2558 VkDescriptorPool *pDescriptorPool, VkResult result) {
2559 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002560 descriptorPoolMap[*pDescriptorPool] = std::make_shared<DESCRIPTOR_POOL_STATE>(*pDescriptorPool, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002561}
2562
2563void ValidationStateTracker::PostCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
2564 VkDescriptorPoolResetFlags flags, VkResult result) {
2565 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002566 DESCRIPTOR_POOL_STATE *pool = GetDescriptorPoolState(descriptorPool);
locke-lunargd556cc32019-09-17 01:21:23 -06002567 // TODO: validate flags
2568 // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
John Zulauf79f06582021-02-27 18:38:39 -07002569 for (auto *ds : pool->sets) {
locke-lunargd556cc32019-09-17 01:21:23 -06002570 FreeDescriptorSet(ds);
2571 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002572 pool->sets.clear();
locke-lunargd556cc32019-09-17 01:21:23 -06002573 // Reset available count for each type and available sets for this pool
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002574 for (auto it = pool->availableDescriptorTypeCount.begin(); it != pool->availableDescriptorTypeCount.end(); ++it) {
2575 pool->availableDescriptorTypeCount[it->first] = pool->maxDescriptorTypeCount[it->first];
locke-lunargd556cc32019-09-17 01:21:23 -06002576 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002577 pool->availableSets = pool->maxSets;
locke-lunargd556cc32019-09-17 01:21:23 -06002578}
2579
2580bool ValidationStateTracker::PreCallValidateAllocateDescriptorSets(VkDevice device,
2581 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05002582 VkDescriptorSet *pDescriptorSets, void *ads_state_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06002583 // Always update common data
2584 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2585 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2586 UpdateAllocateDescriptorSetsData(pAllocateInfo, ads_state);
2587
2588 return false;
2589}
2590
2591// Allocation state was good and call down chain was made so update state based on allocating descriptor sets
2592void ValidationStateTracker::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
2593 VkDescriptorSet *pDescriptorSets, VkResult result,
2594 void *ads_state_data) {
2595 if (VK_SUCCESS != result) return;
2596 // All the updates are contained in a single cvdescriptorset function
2597 cvdescriptorset::AllocateDescriptorSetsData *ads_state =
2598 reinterpret_cast<cvdescriptorset::AllocateDescriptorSetsData *>(ads_state_data);
2599 PerformAllocateDescriptorSets(pAllocateInfo, pDescriptorSets, ads_state);
2600}
2601
2602void ValidationStateTracker::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count,
2603 const VkDescriptorSet *pDescriptorSets) {
2604 DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(descriptorPool);
2605 // Update available descriptor sets in pool
2606 pool_state->availableSets += count;
2607
2608 // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
2609 for (uint32_t i = 0; i < count; ++i) {
2610 if (pDescriptorSets[i] != VK_NULL_HANDLE) {
2611 auto descriptor_set = setMap[pDescriptorSets[i]].get();
2612 uint32_t type_index = 0, descriptor_count = 0;
2613 for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) {
2614 type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j));
2615 descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j);
2616 pool_state->availableDescriptorTypeCount[type_index] += descriptor_count;
2617 }
2618 FreeDescriptorSet(descriptor_set);
2619 pool_state->sets.erase(descriptor_set);
2620 }
2621 }
2622}
2623
2624void ValidationStateTracker::PreCallRecordUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
2625 const VkWriteDescriptorSet *pDescriptorWrites,
2626 uint32_t descriptorCopyCount,
2627 const VkCopyDescriptorSet *pDescriptorCopies) {
2628 cvdescriptorset::PerformUpdateDescriptorSets(this, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
2629 pDescriptorCopies);
2630}
2631
2632void ValidationStateTracker::PostCallRecordAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo,
2633 VkCommandBuffer *pCommandBuffer, VkResult result) {
2634 if (VK_SUCCESS != result) return;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002635 auto pool = GetCommandPoolShared(pCreateInfo->commandPool);
2636 if (pool) {
locke-lunargd556cc32019-09-17 01:21:23 -06002637 for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) {
2638 // Add command buffer to its commandPool map
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002639 pool->commandBuffers.insert(pCommandBuffer[i]);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002640 commandBufferMap[pCommandBuffer[i]] = std::make_shared<CMD_BUFFER_STATE>(this, pCommandBuffer[i], pCreateInfo, pool);
locke-lunargfc78e932020-11-19 17:06:24 -07002641 }
2642 }
2643}
2644
locke-lunargd556cc32019-09-17 01:21:23 -06002645void ValidationStateTracker::PreCallRecordBeginCommandBuffer(VkCommandBuffer commandBuffer,
2646 const VkCommandBufferBeginInfo *pBeginInfo) {
2647 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2648 if (!cb_state) return;
locke-lunargfc78e932020-11-19 17:06:24 -07002649
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002650 cb_state->Begin(pBeginInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002651}
2652
2653void ValidationStateTracker::PostCallRecordEndCommandBuffer(VkCommandBuffer commandBuffer, VkResult result) {
2654 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2655 if (!cb_state) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002656
2657 cb_state->End(result);
locke-lunargd556cc32019-09-17 01:21:23 -06002658}
2659
2660void ValidationStateTracker::PostCallRecordResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags,
2661 VkResult result) {
2662 if (VK_SUCCESS == result) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06002663 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2664 cb_state->Reset();
locke-lunargd556cc32019-09-17 01:21:23 -06002665 }
2666}
2667
2668CBStatusFlags MakeStaticStateMask(VkPipelineDynamicStateCreateInfo const *ds) {
2669 // initially assume everything is static state
2670 CBStatusFlags flags = CBSTATUS_ALL_STATE_SET;
2671
2672 if (ds) {
2673 for (uint32_t i = 0; i < ds->dynamicStateCount; i++) {
locke-lunarg4189aa22020-10-21 00:23:48 -06002674 flags &= ~ConvertToCBStatusFlagBits(ds->pDynamicStates[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06002675 }
2676 }
locke-lunargd556cc32019-09-17 01:21:23 -06002677 return flags;
2678}
2679
2680// Validation cache:
2681// CV is the bottommost implementor of this extension. Don't pass calls down.
2682// utility function to set collective state for pipeline
2683void SetPipelineState(PIPELINE_STATE *pPipe) {
2684 // If any attachment used by this pipeline has blendEnable, set top-level blendEnable
2685 if (pPipe->graphicsPipelineCI.pColorBlendState) {
2686 for (size_t i = 0; i < pPipe->attachments.size(); ++i) {
2687 if (VK_TRUE == pPipe->attachments[i].blendEnable) {
2688 if (((pPipe->attachments[i].dstAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2689 (pPipe->attachments[i].dstAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2690 ((pPipe->attachments[i].dstColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2691 (pPipe->attachments[i].dstColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2692 ((pPipe->attachments[i].srcAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2693 (pPipe->attachments[i].srcAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
2694 ((pPipe->attachments[i].srcColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
2695 (pPipe->attachments[i].srcColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA))) {
2696 pPipe->blendConstantsEnabled = true;
2697 }
2698 }
2699 }
2700 }
sfricke-samsung8f658d42020-05-03 20:12:24 -07002701 // Check if sample location is enabled
2702 if (pPipe->graphicsPipelineCI.pMultisampleState) {
2703 const VkPipelineSampleLocationsStateCreateInfoEXT *sample_location_state =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002704 LvlFindInChain<VkPipelineSampleLocationsStateCreateInfoEXT>(pPipe->graphicsPipelineCI.pMultisampleState->pNext);
sfricke-samsung8f658d42020-05-03 20:12:24 -07002705 if (sample_location_state != nullptr) {
2706 pPipe->sample_location_enabled = sample_location_state->sampleLocationsEnable;
2707 }
2708 }
locke-lunargd556cc32019-09-17 01:21:23 -06002709}
2710
2711void ValidationStateTracker::PreCallRecordCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
2712 VkPipeline pipeline) {
2713 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2714 assert(cb_state);
2715
2716 auto pipe_state = GetPipelineState(pipeline);
2717 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002718 bool rasterization_enabled = VK_FALSE == pipe_state->graphicsPipelineCI.ptr()->pRasterizationState->rasterizerDiscardEnable;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002719 const auto* viewport_state = pipe_state->graphicsPipelineCI.ptr()->pViewportState;
2720 const auto* dynamic_state = pipe_state->graphicsPipelineCI.ptr()->pDynamicState;
locke-lunargd556cc32019-09-17 01:21:23 -06002721 cb_state->status &= ~cb_state->static_status;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002722 cb_state->static_status = MakeStaticStateMask(dynamic_state);
locke-lunargd556cc32019-09-17 01:21:23 -06002723 cb_state->status |= cb_state->static_status;
locke-lunarg4189aa22020-10-21 00:23:48 -06002724 cb_state->dynamic_status = CBSTATUS_ALL_STATE_SET & (~cb_state->static_status);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002725
2726 // Used to calculate CMD_BUFFER_STATE::usedViewportScissorCount upon draw command with this graphics pipeline.
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002727 // If rasterization disabled (no viewport/scissors used), or the actual number of viewports/scissors is dynamic (unknown at
2728 // this time), then these are set to 0 to disable this checking.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002729 auto has_dynamic_viewport_count = cb_state->dynamic_status & CBSTATUS_VIEWPORT_WITH_COUNT_SET;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002730 auto has_dynamic_scissor_count = cb_state->dynamic_status & CBSTATUS_SCISSOR_WITH_COUNT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002731 cb_state->pipelineStaticViewportCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002732 has_dynamic_viewport_count || !rasterization_enabled ? 0 : viewport_state->viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002733 cb_state->pipelineStaticScissorCount =
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002734 has_dynamic_scissor_count || !rasterization_enabled ? 0 : viewport_state->scissorCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002735
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002736 // Trash dynamic viewport/scissor state if pipeline defines static state and enabled rasterization.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002737 // akeley98 NOTE: There's a bit of an ambiguity in the spec, whether binding such a pipeline overwrites
2738 // the entire viewport (scissor) array, or only the subsection defined by the viewport (scissor) count.
2739 // I am taking the latter interpretation based on the implementation details of NVIDIA's Vulkan driver.
David Zhao Akeley44139b12021-04-26 16:16:13 -07002740 if (!has_dynamic_viewport_count) {
2741 cb_state->trashedViewportCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002742 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_VIEWPORT_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002743 cb_state->trashedViewportMask |= (uint32_t(1) << viewport_state->viewportCount) - 1u;
2744 // should become = ~uint32_t(0) if the other interpretation is correct.
2745 }
2746 }
2747 if (!has_dynamic_scissor_count) {
2748 cb_state->trashedScissorCount = true;
David Zhao Akeley5f40eb72021-05-04 21:56:14 -07002749 if (rasterization_enabled && (cb_state->static_status & CBSTATUS_SCISSOR_SET)) {
David Zhao Akeley44139b12021-04-26 16:16:13 -07002750 cb_state->trashedScissorMask |= (uint32_t(1) << viewport_state->scissorCount) - 1u;
2751 // should become = ~uint32_t(0) if the other interpretation is correct.
2752 }
2753 }
locke-lunargd556cc32019-09-17 01:21:23 -06002754 }
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002755 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
2756 cb_state->lastBound[lv_bind_point].pipeline_state = pipe_state;
locke-lunargd556cc32019-09-17 01:21:23 -06002757 SetPipelineState(pipe_state);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002758 if (!disabled[command_buffer_state]) {
2759 cb_state->AddChild(pipe_state);
2760 }
locke-lunargb8be8222020-10-20 00:34:37 -06002761 for (auto &slot : pipe_state->active_slots) {
2762 for (auto &req : slot.second) {
2763 for (auto &sampler : req.second.samplers_used_by_image) {
2764 for (auto &des : sampler) {
2765 des.second = nullptr;
2766 }
2767 }
2768 }
2769 }
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06002770 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
locke-lunargd556cc32019-09-17 01:21:23 -06002771}
2772
2773void ValidationStateTracker::PreCallRecordCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2774 uint32_t viewportCount, const VkViewport *pViewports) {
2775 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07002776 uint32_t bits = ((1u << viewportCount) - 1u) << firstViewport;
2777 cb_state->viewportMask |= bits;
2778 cb_state->trashedViewportMask &= ~bits;
locke-lunargd556cc32019-09-17 01:21:23 -06002779 cb_state->status |= CBSTATUS_VIEWPORT_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06002780 cb_state->static_status &= ~CBSTATUS_VIEWPORT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07002781
2782 cb_state->dynamicViewports.resize(std::max(size_t(firstViewport + viewportCount), cb_state->dynamicViewports.size()));
2783 for (size_t i = 0; i < viewportCount; ++i) {
2784 cb_state->dynamicViewports[firstViewport + i] = pViewports[i];
2785 }
locke-lunargd556cc32019-09-17 01:21:23 -06002786}
2787
2788void ValidationStateTracker::PreCallRecordCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
2789 uint32_t exclusiveScissorCount,
2790 const VkRect2D *pExclusiveScissors) {
2791 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2792 // TODO: We don't have VUIDs for validating that all exclusive scissors have been set.
2793 // cb_state->exclusiveScissorMask |= ((1u << exclusiveScissorCount) - 1u) << firstExclusiveScissor;
2794 cb_state->status |= CBSTATUS_EXCLUSIVE_SCISSOR_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06002795 cb_state->static_status &= ~CBSTATUS_EXCLUSIVE_SCISSOR_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06002796}
2797
2798void ValidationStateTracker::PreCallRecordCmdBindShadingRateImageNV(VkCommandBuffer commandBuffer, VkImageView imageView,
2799 VkImageLayout imageLayout) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002800 if (disabled[command_buffer_state]) return;
2801
locke-lunargd556cc32019-09-17 01:21:23 -06002802 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2803
2804 if (imageView != VK_NULL_HANDLE) {
2805 auto view_state = GetImageViewState(imageView);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002806 cb_state->AddChild(view_state);
locke-lunargd556cc32019-09-17 01:21:23 -06002807 }
2808}
2809
2810void ValidationStateTracker::PreCallRecordCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2811 uint32_t viewportCount,
2812 const VkShadingRatePaletteNV *pShadingRatePalettes) {
2813 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2814 // TODO: We don't have VUIDs for validating that all shading rate palettes have been set.
2815 // cb_state->shadingRatePaletteMask |= ((1u << viewportCount) - 1u) << firstViewport;
2816 cb_state->status |= CBSTATUS_SHADING_RATE_PALETTE_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06002817 cb_state->static_status &= ~CBSTATUS_SHADING_RATE_PALETTE_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06002818}
2819
2820void ValidationStateTracker::PostCallRecordCreateAccelerationStructureNV(VkDevice device,
2821 const VkAccelerationStructureCreateInfoNV *pCreateInfo,
2822 const VkAllocationCallbacks *pAllocator,
2823 VkAccelerationStructureNV *pAccelerationStructure,
2824 VkResult result) {
2825 if (VK_SUCCESS != result) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002826 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE>(*pAccelerationStructure, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06002827
2828 // Query the requirements in case the application doesn't (to avoid bind/validation time query)
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002829 auto as_memory_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002830 as_memory_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002831 as_memory_requirements_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002832 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &as_memory_requirements_info, &as_state->memory_requirements);
2833
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002834 auto scratch_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002835 scratch_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002836 scratch_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002837 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &scratch_memory_req_info,
2838 &as_state->build_scratch_memory_requirements);
2839
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002840 auto update_memory_req_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
locke-lunargd556cc32019-09-17 01:21:23 -06002841 update_memory_req_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002842 update_memory_req_info.accelerationStructure = as_state->acceleration_structure();
locke-lunargd556cc32019-09-17 01:21:23 -06002843 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &update_memory_req_info,
2844 &as_state->update_scratch_memory_requirements);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002845 as_state->allocator = pAllocator;
locke-lunargd556cc32019-09-17 01:21:23 -06002846 accelerationStructureMap[*pAccelerationStructure] = std::move(as_state);
2847}
2848
Jeff Bolz95176d02020-04-01 00:36:16 -05002849void ValidationStateTracker::PostCallRecordCreateAccelerationStructureKHR(VkDevice device,
2850 const VkAccelerationStructureCreateInfoKHR *pCreateInfo,
2851 const VkAllocationCallbacks *pAllocator,
2852 VkAccelerationStructureKHR *pAccelerationStructure,
2853 VkResult result) {
2854 if (VK_SUCCESS != result) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07002855 auto as_state = std::make_shared<ACCELERATION_STRUCTURE_STATE_KHR>(*pAccelerationStructure, pCreateInfo);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002856 as_state->allocator = pAllocator;
sourav parmarcd5fb182020-07-17 12:58:44 -07002857 accelerationStructureMap_khr[*pAccelerationStructure] = std::move(as_state);
Jeff Bolz95176d02020-04-01 00:36:16 -05002858}
2859
sourav parmarcd5fb182020-07-17 12:58:44 -07002860void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresKHR(
2861 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2862 const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) {
2863 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2864 if (cb_state == nullptr) {
2865 return;
2866 }
2867 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002868 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002869 if (dst_as_state != nullptr) {
2870 dst_as_state->built = true;
2871 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002872 if (!disabled[command_buffer_state]) {
2873 cb_state->AddChild(dst_as_state);
2874 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002875 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002876 if (!disabled[command_buffer_state]) {
2877 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2878 if (src_as_state != nullptr) {
2879 cb_state->AddChild(src_as_state);
2880 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002881 }
2882 }
2883 cb_state->hasBuildAccelerationStructureCmd = true;
2884}
2885
2886void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructuresIndirectKHR(
2887 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
2888 const VkDeviceAddress *pIndirectDeviceAddresses, const uint32_t *pIndirectStrides,
2889 const uint32_t *const *ppMaxPrimitiveCounts) {
2890 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2891 if (cb_state == nullptr) {
2892 return;
2893 }
2894 for (uint32_t i = 0; i < infoCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002895 auto *dst_as_state = GetAccelerationStructureStateKHR(pInfos[i].dstAccelerationStructure);
sourav parmarcd5fb182020-07-17 12:58:44 -07002896 if (dst_as_state != nullptr) {
2897 dst_as_state->built = true;
2898 dst_as_state->build_info_khr.initialize(&pInfos[i]);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002899 if (!disabled[command_buffer_state]) {
2900 cb_state->AddChild(dst_as_state);
2901 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002902 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002903 if (!disabled[command_buffer_state]) {
2904 auto *src_as_state = GetAccelerationStructureStateKHR(pInfos[i].srcAccelerationStructure);
2905 if (src_as_state != nullptr) {
2906 cb_state->AddChild(src_as_state);
2907 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002908 }
2909 }
2910 cb_state->hasBuildAccelerationStructureCmd = true;
2911}
locke-lunargd556cc32019-09-17 01:21:23 -06002912void ValidationStateTracker::PostCallRecordGetAccelerationStructureMemoryRequirementsNV(
Mike Schuchardt2df08912020-12-15 16:28:09 -08002913 VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV *pInfo, VkMemoryRequirements2 *pMemoryRequirements) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002914 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(pInfo->accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002915 if (as_state != nullptr) {
2916 if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV) {
2917 as_state->memory_requirements = *pMemoryRequirements;
2918 as_state->memory_requirements_checked = true;
2919 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV) {
2920 as_state->build_scratch_memory_requirements = *pMemoryRequirements;
2921 as_state->build_scratch_memory_requirements_checked = true;
2922 } else if (pInfo->type == VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV) {
2923 as_state->update_scratch_memory_requirements = *pMemoryRequirements;
2924 as_state->update_scratch_memory_requirements_checked = true;
2925 }
2926 }
2927}
2928
sourav parmarcd5fb182020-07-17 12:58:44 -07002929void ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(
2930 VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06002931 if (VK_SUCCESS != result) return;
2932 for (uint32_t i = 0; i < bindInfoCount; i++) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002933 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
locke-lunargd556cc32019-09-17 01:21:23 -06002934
sourav parmarcd5fb182020-07-17 12:58:44 -07002935 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(info.accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06002936 if (as_state) {
locke-lunargd556cc32019-09-17 01:21:23 -06002937 // Track objects tied to memory
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002938 auto mem_state = GetDevMemShared(info.memory);
2939 if (mem_state) {
2940 as_state->SetMemBinding(mem_state, info.memoryOffset);
2941 }
locke-lunargd556cc32019-09-17 01:21:23 -06002942
2943 // GPU validation of top level acceleration structure building needs acceleration structure handles.
Jeff Bolz95176d02020-04-01 00:36:16 -05002944 // XXX TODO: Query device address for KHR extension
sourav parmarcd5fb182020-07-17 12:58:44 -07002945 if (enabled[gpu_validation]) {
locke-lunargd556cc32019-09-17 01:21:23 -06002946 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
2947 }
2948 }
2949 }
2950}
2951
2952void ValidationStateTracker::PostCallRecordCmdBuildAccelerationStructureNV(
2953 VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset,
2954 VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset) {
2955 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2956 if (cb_state == nullptr) {
2957 return;
2958 }
2959
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002960 auto *dst_as_state = GetAccelerationStructureStateNV(dst);
locke-lunargd556cc32019-09-17 01:21:23 -06002961 if (dst_as_state != nullptr) {
2962 dst_as_state->built = true;
2963 dst_as_state->build_info.initialize(pInfo);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002964 if (!disabled[command_buffer_state]) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002965 cb_state->AddChild(dst_as_state);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002966 }
locke-lunargd556cc32019-09-17 01:21:23 -06002967 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002968 if (!disabled[command_buffer_state]) {
2969 auto *src_as_state = GetAccelerationStructureStateNV(src);
2970 if (src_as_state != nullptr) {
2971 cb_state->AddChild(src_as_state);
2972 }
locke-lunargd556cc32019-09-17 01:21:23 -06002973 }
2974 cb_state->hasBuildAccelerationStructureCmd = true;
2975}
2976
2977void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureNV(VkCommandBuffer commandBuffer,
2978 VkAccelerationStructureNV dst,
2979 VkAccelerationStructureNV src,
2980 VkCopyAccelerationStructureModeNV mode) {
2981 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
2982 if (cb_state) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002983 ACCELERATION_STRUCTURE_STATE *src_as_state = GetAccelerationStructureStateNV(src);
2984 ACCELERATION_STRUCTURE_STATE *dst_as_state = GetAccelerationStructureStateNV(dst);
locke-lunargd556cc32019-09-17 01:21:23 -06002985 if (dst_as_state != nullptr && src_as_state != nullptr) {
2986 dst_as_state->built = true;
2987 dst_as_state->build_info = src_as_state->build_info;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002988 if (!disabled[command_buffer_state]) {
2989 cb_state->AddChild(dst_as_state);
2990 cb_state->AddChild(src_as_state);
2991 }
locke-lunargd556cc32019-09-17 01:21:23 -06002992 }
2993 }
2994}
2995
Jeff Bolz95176d02020-04-01 00:36:16 -05002996void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureKHR(VkDevice device,
2997 VkAccelerationStructureKHR accelerationStructure,
2998 const VkAllocationCallbacks *pAllocator) {
locke-lunargd556cc32019-09-17 01:21:23 -06002999 if (!accelerationStructure) return;
sourav parmarcd5fb182020-07-17 12:58:44 -07003000 auto *as_state = GetAccelerationStructureStateKHR(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06003001 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003002 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07003003 accelerationStructureMap_khr.erase(accelerationStructure);
locke-lunargd556cc32019-09-17 01:21:23 -06003004 }
3005}
3006
Jeff Bolz95176d02020-04-01 00:36:16 -05003007void ValidationStateTracker::PreCallRecordDestroyAccelerationStructureNV(VkDevice device,
3008 VkAccelerationStructureNV accelerationStructure,
3009 const VkAllocationCallbacks *pAllocator) {
sourav parmarcd5fb182020-07-17 12:58:44 -07003010 if (!accelerationStructure) return;
3011 auto *as_state = GetAccelerationStructureStateNV(accelerationStructure);
3012 if (as_state) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003013 as_state->Destroy();
sourav parmarcd5fb182020-07-17 12:58:44 -07003014 accelerationStructureMap.erase(accelerationStructure);
3015 }
Jeff Bolz95176d02020-04-01 00:36:16 -05003016}
3017
Chris Mayer9ded5eb2019-09-19 16:33:26 +02003018void ValidationStateTracker::PreCallRecordCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
3019 uint32_t viewportCount,
3020 const VkViewportWScalingNV *pViewportWScalings) {
3021 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3022 cb_state->status |= CBSTATUS_VIEWPORT_W_SCALING_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003023 cb_state->static_status &= ~CBSTATUS_VIEWPORT_W_SCALING_SET;
Chris Mayer9ded5eb2019-09-19 16:33:26 +02003024}
3025
locke-lunargd556cc32019-09-17 01:21:23 -06003026void ValidationStateTracker::PreCallRecordCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
3027 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3028 cb_state->status |= CBSTATUS_LINE_WIDTH_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003029 cb_state->static_status &= ~CBSTATUS_LINE_WIDTH_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003030}
3031
3032void ValidationStateTracker::PreCallRecordCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
3033 uint16_t lineStipplePattern) {
3034 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3035 cb_state->status |= CBSTATUS_LINE_STIPPLE_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003036 cb_state->static_status &= ~CBSTATUS_LINE_STIPPLE_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003037}
3038
3039void ValidationStateTracker::PreCallRecordCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
3040 float depthBiasClamp, float depthBiasSlopeFactor) {
3041 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3042 cb_state->status |= CBSTATUS_DEPTH_BIAS_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003043 cb_state->static_status &= ~CBSTATUS_DEPTH_BIAS_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003044}
3045
Lionel Landwerlinc7420912019-05-23 00:33:42 +01003046void ValidationStateTracker::PreCallRecordCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
3047 const VkRect2D *pScissors) {
3048 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07003049 uint32_t bits = ((1u << scissorCount) - 1u) << firstScissor;
3050 cb_state->scissorMask |= bits;
3051 cb_state->trashedScissorMask &= ~bits;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01003052 cb_state->status |= CBSTATUS_SCISSOR_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003053 cb_state->static_status &= ~CBSTATUS_SCISSOR_SET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01003054}
3055
locke-lunargd556cc32019-09-17 01:21:23 -06003056void ValidationStateTracker::PreCallRecordCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
3057 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3058 cb_state->status |= CBSTATUS_BLEND_CONSTANTS_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003059 cb_state->static_status &= ~CBSTATUS_BLEND_CONSTANTS_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003060}
3061
3062void ValidationStateTracker::PreCallRecordCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
3063 float maxDepthBounds) {
3064 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3065 cb_state->status |= CBSTATUS_DEPTH_BOUNDS_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003066 cb_state->static_status &= ~CBSTATUS_DEPTH_BOUNDS_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003067}
3068
3069void ValidationStateTracker::PreCallRecordCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3070 uint32_t compareMask) {
3071 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3072 cb_state->status |= CBSTATUS_STENCIL_READ_MASK_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003073 cb_state->static_status &= ~CBSTATUS_STENCIL_READ_MASK_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003074}
3075
3076void ValidationStateTracker::PreCallRecordCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3077 uint32_t writeMask) {
3078 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3079 cb_state->status |= CBSTATUS_STENCIL_WRITE_MASK_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003080 cb_state->static_status &= ~CBSTATUS_STENCIL_WRITE_MASK_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003081}
3082
3083void ValidationStateTracker::PreCallRecordCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
3084 uint32_t reference) {
3085 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3086 cb_state->status |= CBSTATUS_STENCIL_REFERENCE_SET;
Piers Daniell39842ee2020-07-10 16:42:33 -06003087 cb_state->static_status &= ~CBSTATUS_STENCIL_REFERENCE_SET;
locke-lunargd556cc32019-09-17 01:21:23 -06003088}
3089
locke-lunargd556cc32019-09-17 01:21:23 -06003090
3091// Update the bound state for the bind point, including the effects of incompatible pipeline layouts
3092void ValidationStateTracker::PreCallRecordCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
3093 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3094 uint32_t firstSet, uint32_t setCount,
3095 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
3096 const uint32_t *pDynamicOffsets) {
3097 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3098 auto pipeline_layout = GetPipelineLayout(layout);
3099
3100 // Resize binding arrays
3101 uint32_t last_set_index = firstSet + setCount - 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003102 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
3103 if (last_set_index >= cb_state->lastBound[lv_bind_point].per_set.size()) {
3104 cb_state->lastBound[lv_bind_point].per_set.resize(last_set_index + 1);
locke-lunargd556cc32019-09-17 01:21:23 -06003105 }
3106
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003107 cb_state->UpdateLastBoundDescriptorSets(pipelineBindPoint, pipeline_layout, firstSet, setCount, pDescriptorSets, nullptr,
3108 dynamicOffsetCount, pDynamicOffsets);
locke-lunargb8d7a7a2020-10-25 16:01:52 -06003109 cb_state->lastBound[lv_bind_point].pipeline_layout = layout;
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06003110 cb_state->lastBound[lv_bind_point].UpdateSamplerDescriptorsUsedByImage();
Jeremy Gebben5570abe2021-05-16 18:35:13 -06003111}
3112
locke-lunargd556cc32019-09-17 01:21:23 -06003113void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
3114 VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
3115 uint32_t set, uint32_t descriptorWriteCount,
3116 const VkWriteDescriptorSet *pDescriptorWrites) {
3117 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003118 auto pipeline_layout = GetPipelineLayout(layout);
3119 cb_state->PushDescriptorSetState(pipelineBindPoint, pipeline_layout, set, descriptorWriteCount, pDescriptorWrites);
locke-lunargd556cc32019-09-17 01:21:23 -06003120}
3121
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003122void ValidationStateTracker::PostCallRecordCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
3123 VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
3124 const void *pValues) {
3125 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3126 if (cb_state != nullptr) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003127 cb_state->ResetPushConstantDataIfIncompatible(GetPipelineLayout(layout));
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003128
3129 auto &push_constant_data = cb_state->push_constant_data;
3130 assert((offset + size) <= static_cast<uint32_t>(push_constant_data.size()));
3131 std::memcpy(push_constant_data.data() + offset, pValues, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003132 cb_state->push_constant_pipeline_layout_set = layout;
3133
3134 auto flags = stageFlags;
3135 uint32_t bit_shift = 0;
3136 while (flags) {
3137 if (flags & 1) {
3138 VkShaderStageFlagBits flag = static_cast<VkShaderStageFlagBits>(1 << bit_shift);
3139 const auto it = cb_state->push_constant_data_update.find(flag);
3140
3141 if (it != cb_state->push_constant_data_update.end()) {
locke-lunarg3d8b8f32020-10-26 17:04:16 -06003142 std::memset(it->second.data() + offset, PC_Byte_Updated, static_cast<std::size_t>(size));
locke-lunargde3f0fa2020-09-10 11:55:31 -06003143 }
3144 }
3145 flags = flags >> 1;
3146 ++bit_shift;
3147 }
Tony-LunarG6bb1d0c2019-09-23 10:39:25 -06003148 }
3149}
3150
locke-lunargd556cc32019-09-17 01:21:23 -06003151void ValidationStateTracker::PreCallRecordCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
3152 VkIndexType indexType) {
locke-lunargd556cc32019-09-17 01:21:23 -06003153 auto cb_state = GetCBState(commandBuffer);
3154
3155 cb_state->status |= CBSTATUS_INDEX_BUFFER_BOUND;
Piers Daniell39842ee2020-07-10 16:42:33 -06003156 cb_state->static_status &= ~CBSTATUS_INDEX_BUFFER_BOUND;
locke-lunarg1ae57d62020-11-18 10:49:19 -07003157 cb_state->index_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(buffer);
3158 cb_state->index_buffer_binding.size = cb_state->index_buffer_binding.buffer_state->createInfo.size;
locke-lunargd556cc32019-09-17 01:21:23 -06003159 cb_state->index_buffer_binding.offset = offset;
3160 cb_state->index_buffer_binding.index_type = indexType;
3161 // Add binding for this index buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003162 if (!disabled[command_buffer_state]) {
3163 cb_state->AddChild(cb_state->index_buffer_binding.buffer_state.get());
3164 }
locke-lunargd556cc32019-09-17 01:21:23 -06003165}
3166
3167void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
3168 uint32_t bindingCount, const VkBuffer *pBuffers,
3169 const VkDeviceSize *pOffsets) {
3170 auto cb_state = GetCBState(commandBuffer);
3171
3172 uint32_t end = firstBinding + bindingCount;
3173 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
3174 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
3175 }
3176
3177 for (uint32_t i = 0; i < bindingCount; ++i) {
3178 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07003179 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003180 vertex_buffer_binding.offset = pOffsets[i];
Piers Daniell39842ee2020-07-10 16:42:33 -06003181 vertex_buffer_binding.size = VK_WHOLE_SIZE;
3182 vertex_buffer_binding.stride = 0;
locke-lunargd556cc32019-09-17 01:21:23 -06003183 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003184 if (pBuffers[i] && !disabled[command_buffer_state]) {
3185 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Jeff Bolz165818a2020-05-08 11:19:03 -05003186 }
locke-lunargd556cc32019-09-17 01:21:23 -06003187 }
3188}
3189
3190void ValidationStateTracker::PostCallRecordCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
3191 VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003192 if (disabled[command_buffer_state]) return;
3193
locke-lunargd556cc32019-09-17 01:21:23 -06003194 auto cb_state = GetCBState(commandBuffer);
3195 auto dst_buffer_state = GetBufferState(dstBuffer);
3196
3197 // Update bindings between buffer and cmd buffer
Jeremy Gebben5570abe2021-05-16 18:35:13 -06003198 if (cb_state && dst_buffer_state) {
3199 cb_state->AddChild(dst_buffer_state);
3200 }
locke-lunargd556cc32019-09-17 01:21:23 -06003201}
3202
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06003203static bool SetEventStageMask(VkEvent event, VkPipelineStageFlags2KHR stageMask,
Jeff Bolz310775c2019-10-09 00:46:33 -05003204 EventToStageMap *localEventToStageMap) {
3205 (*localEventToStageMap)[event] = stageMask;
locke-lunargd556cc32019-09-17 01:21:23 -06003206 return false;
3207}
3208
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003209void ValidationStateTracker::RecordCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR stageMask) {
locke-lunargd556cc32019-09-17 01:21:23 -06003210 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003211 if (!disabled[command_buffer_state]) {
3212 auto event_state = GetEventState(event);
3213 if (event_state) {
3214 cb_state->AddChild(event_state);
3215 }
locke-lunargd556cc32019-09-17 01:21:23 -06003216 }
3217 cb_state->events.push_back(event);
3218 if (!cb_state->waitedEvents.count(event)) {
3219 cb_state->writeEventsBeforeWait.push_back(event);
3220 }
Jeff Bolz310775c2019-10-09 00:46:33 -05003221 cb_state->eventUpdates.emplace_back(
3222 [event, stageMask](const ValidationStateTracker *device_data, bool do_validate, EventToStageMap *localEventToStageMap) {
3223 return SetEventStageMask(event, stageMask, localEventToStageMap);
3224 });
locke-lunargd556cc32019-09-17 01:21:23 -06003225}
3226
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003227void ValidationStateTracker::PreCallRecordCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3228 VkPipelineStageFlags stageMask) {
3229 RecordCmdSetEvent(commandBuffer, event, stageMask);
3230}
3231
3232void ValidationStateTracker::PreCallRecordCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3233 const VkDependencyInfoKHR *pDependencyInfo) {
3234 auto stage_masks = sync_utils::GetGlobalStageMasks(*pDependencyInfo);
3235
3236 RecordCmdSetEvent(commandBuffer, event, stage_masks.src);
Jeremy Gebben79649152021-06-22 14:46:24 -06003237
3238 RecordBarriers(commandBuffer, pDependencyInfo);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003239}
3240
3241void ValidationStateTracker::RecordCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3242 VkPipelineStageFlags2KHR stageMask) {
locke-lunargd556cc32019-09-17 01:21:23 -06003243 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003244 if (!disabled[command_buffer_state]) {
3245 auto event_state = GetEventState(event);
3246 if (event_state) {
3247 cb_state->AddChild(event_state);
3248 }
locke-lunargd556cc32019-09-17 01:21:23 -06003249 }
3250 cb_state->events.push_back(event);
3251 if (!cb_state->waitedEvents.count(event)) {
3252 cb_state->writeEventsBeforeWait.push_back(event);
3253 }
3254
3255 cb_state->eventUpdates.emplace_back(
Jeff Bolz310775c2019-10-09 00:46:33 -05003256 [event](const ValidationStateTracker *, bool do_validate, EventToStageMap *localEventToStageMap) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003257 return SetEventStageMask(event, VkPipelineStageFlags2KHR(0), localEventToStageMap);
Jeff Bolz310775c2019-10-09 00:46:33 -05003258 });
locke-lunargd556cc32019-09-17 01:21:23 -06003259}
3260
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003261void ValidationStateTracker::PreCallRecordCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
3262 VkPipelineStageFlags stageMask) {
3263 RecordCmdResetEvent(commandBuffer, event, stageMask);
3264}
3265
3266void ValidationStateTracker::PreCallRecordCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
3267 VkPipelineStageFlags2KHR stageMask) {
3268 RecordCmdResetEvent(commandBuffer, event, stageMask);
3269}
3270
3271void ValidationStateTracker::RecordCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents) {
locke-lunargd556cc32019-09-17 01:21:23 -06003272 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3273 for (uint32_t i = 0; i < eventCount; ++i) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003274 if (!disabled[command_buffer_state]) {
3275 auto event_state = GetEventState(pEvents[i]);
3276 if (event_state) {
3277 cb_state->AddChild(event_state);
3278 }
locke-lunargd556cc32019-09-17 01:21:23 -06003279 }
3280 cb_state->waitedEvents.insert(pEvents[i]);
3281 cb_state->events.push_back(pEvents[i]);
3282 }
3283}
3284
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003285void ValidationStateTracker::PreCallRecordCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
3286 VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
3287 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3288 uint32_t bufferMemoryBarrierCount,
3289 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3290 uint32_t imageMemoryBarrierCount,
3291 const VkImageMemoryBarrier *pImageMemoryBarriers) {
3292 RecordCmdWaitEvents(commandBuffer, eventCount, pEvents);
Jeremy Gebben79649152021-06-22 14:46:24 -06003293 RecordBarriers(commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3294 imageMemoryBarrierCount, pImageMemoryBarriers);
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003295}
3296
3297void ValidationStateTracker::PreCallRecordCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount,
3298 const VkEvent *pEvents, const VkDependencyInfoKHR *pDependencyInfos) {
3299 RecordCmdWaitEvents(commandBuffer, eventCount, pEvents);
Jeremy Gebben79649152021-06-22 14:46:24 -06003300 for (uint32_t i = 0; i < eventCount; i++) {
3301 RecordBarriers(commandBuffer, &pDependencyInfos[i]);
3302 }
3303}
3304
3305void ValidationStateTracker::PostCallRecordCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
3306 VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
3307 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
3308 uint32_t bufferMemoryBarrierCount,
3309 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
3310 uint32_t imageMemoryBarrierCount,
3311 const VkImageMemoryBarrier *pImageMemoryBarriers) {
3312 RecordBarriers(commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
3313 imageMemoryBarrierCount, pImageMemoryBarriers);
3314}
3315
3316void ValidationStateTracker::PreCallRecordCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
3317 const VkDependencyInfoKHR *pDependencyInfo) {
3318 RecordBarriers(commandBuffer, pDependencyInfo);
3319}
3320
3321void ValidationStateTracker::RecordBarriers(VkCommandBuffer commandBuffer, uint32_t memoryBarrierCount,
3322 const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
3323 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
3324 const VkImageMemoryBarrier *pImageMemoryBarriers) {
3325 if (disabled[command_buffer_state]) return;
3326
3327 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3328 for (uint32_t i = 0; i < bufferMemoryBarrierCount; i++) {
3329 auto buffer_state = GetBufferState(pBufferMemoryBarriers[i].buffer);
3330 if (buffer_state) {
3331 cb_state->AddChild(buffer_state);
3332 }
3333 }
3334 for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
3335 auto image_state = GetImageState(pImageMemoryBarriers[i].image);
3336 if (image_state) {
3337 cb_state->AddChild(image_state);
3338 }
3339 }
3340}
3341
3342void ValidationStateTracker::RecordBarriers(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR *pDependencyInfo) {
3343 if (disabled[command_buffer_state]) return;
3344
3345 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3346 for (uint32_t i = 0; i < pDependencyInfo->bufferMemoryBarrierCount; i++) {
3347 auto buffer_state = GetBufferState(pDependencyInfo->pBufferMemoryBarriers[i].buffer);
3348 if (buffer_state) {
3349 cb_state->AddChild(buffer_state);
3350 }
3351 }
3352 for (uint32_t i = 0; i < pDependencyInfo->imageMemoryBarrierCount; i++) {
3353 auto image_state = GetImageState(pDependencyInfo->pImageMemoryBarriers[i].image);
3354 if (image_state) {
3355 cb_state->AddChild(image_state);
3356 }
3357 }
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003358}
3359
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003360QueryState ValidationStateTracker::GetQueryState(const QueryMap *localQueryToStateMap, VkQueryPool queryPool, uint32_t queryIndex,
3361 uint32_t perfPass) const {
3362 QueryObject query = QueryObject(QueryObject(queryPool, queryIndex), perfPass);
locke-lunargd556cc32019-09-17 01:21:23 -06003363
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02003364 auto iter = localQueryToStateMap->find(query);
3365 if (iter != localQueryToStateMap->end()) return iter->second;
Jeff Bolz310775c2019-10-09 00:46:33 -05003366
Jeff Bolz310775c2019-10-09 00:46:33 -05003367 return QUERYSTATE_UNKNOWN;
locke-lunargd556cc32019-09-17 01:21:23 -06003368}
3369
locke-lunargd556cc32019-09-17 01:21:23 -06003370void ValidationStateTracker::PostCallRecordCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot,
3371 VkFlags flags) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003372 if (disabled[query_validation]) return;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003373
locke-lunargd556cc32019-09-17 01:21:23 -06003374 QueryObject query = {queryPool, slot};
3375 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003376 if (!disabled[query_validation]) {
3377 cb_state->BeginQuery(query);
3378 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003379 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003380 auto pool_state = GetQueryPoolState(query.pool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003381 cb_state->AddChild(pool_state);
3382 }
locke-lunargd556cc32019-09-17 01:21:23 -06003383}
3384
3385void ValidationStateTracker::PostCallRecordCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003386 if (disabled[query_validation]) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003387 QueryObject query_obj = {queryPool, slot};
3388 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003389 if (!disabled[query_validation]) {
3390 cb_state->EndQuery(query_obj);
3391 }
3392 if (!disabled[command_buffer_state]) {
3393 auto pool_state = GetQueryPoolState(query_obj.pool);
3394 cb_state->AddChild(pool_state);
3395 }
locke-lunargd556cc32019-09-17 01:21:23 -06003396}
3397
3398void ValidationStateTracker::PostCallRecordCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3399 uint32_t firstQuery, uint32_t queryCount) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003400 if (disabled[query_validation]) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003401 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3402
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003403 cb_state->ResetQueryPool(queryPool, firstQuery, queryCount);
Lionel Landwerlinb1e5a422020-02-18 16:49:09 +02003404
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003405 if (!disabled[command_buffer_state]) {
3406 auto pool_state = GetQueryPoolState(queryPool);
3407 cb_state->AddChild(pool_state);
3408 }
locke-lunargd556cc32019-09-17 01:21:23 -06003409}
3410
3411void ValidationStateTracker::PostCallRecordCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3412 uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer,
3413 VkDeviceSize dstOffset, VkDeviceSize stride,
3414 VkQueryResultFlags flags) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003415 if (disabled[query_validation] || disabled[command_buffer_state]) return;
3416
locke-lunargd556cc32019-09-17 01:21:23 -06003417 auto cb_state = GetCBState(commandBuffer);
3418 auto dst_buff_state = GetBufferState(dstBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003419 cb_state->AddChild(dst_buff_state);
Jeff Bolzadbfa852019-10-04 13:53:30 -05003420 auto pool_state = GetQueryPoolState(queryPool);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003421 cb_state->AddChild(pool_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003422}
3423
3424void ValidationStateTracker::PostCallRecordCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
3425 VkQueryPool queryPool, uint32_t slot) {
Jeremy Gebben74aa7622020-12-15 11:18:00 -07003426 PostCallRecordCmdWriteTimestamp2KHR(commandBuffer, pipelineStage, queryPool, slot);
3427}
3428
3429void ValidationStateTracker::PostCallRecordCmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer,
3430 VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool,
3431 uint32_t slot) {
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06003432 if (disabled[query_validation]) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003433 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003434 if (!disabled[command_buffer_state]) {
3435 auto pool_state = GetQueryPoolState(queryPool);
3436 cb_state->AddChild(pool_state);
3437 }
locke-lunargd556cc32019-09-17 01:21:23 -06003438 QueryObject query = {queryPool, slot};
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003439 cb_state->EndQuery(query);
locke-lunargd556cc32019-09-17 01:21:23 -06003440}
3441
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003442void ValidationStateTracker::PostCallRecordCmdWriteAccelerationStructuresPropertiesKHR(
3443 VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR *pAccelerationStructures,
3444 VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery) {
3445 if (disabled[query_validation]) return;
3446 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003447 if (!disabled[command_buffer_state]) {
3448 auto pool_state = GetQueryPoolState(queryPool);
3449 cb_state->AddChild(pool_state);
3450 }
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003451 cb_state->EndQueries(queryPool, firstQuery, accelerationStructureCount);
Marijn Suijten6750fdc2020-12-30 22:06:42 +01003452}
3453
locke-lunargd556cc32019-09-17 01:21:23 -06003454void ValidationStateTracker::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
3455 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
3456 VkResult result) {
3457 if (VK_SUCCESS != result) return;
locke-lunargd556cc32019-09-17 01:21:23 -06003458
Jeremy Gebben88f58142021-06-01 10:07:52 -06003459 std::vector<std::shared_ptr<IMAGE_VIEW_STATE>> views;
Mike Schuchardt2df08912020-12-15 16:28:09 -08003460 if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) == 0) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003461 views.resize(pCreateInfo->attachmentCount);
locke-lunarg1ae57d62020-11-18 10:49:19 -07003462
locke-lunargd556cc32019-09-17 01:21:23 -06003463 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003464 views[i] = GetShared<IMAGE_VIEW_STATE>(pCreateInfo->pAttachments[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06003465 }
3466 }
Jeremy Gebben88f58142021-06-01 10:07:52 -06003467
3468 frameBufferMap[*pFramebuffer] = std::make_shared<FRAMEBUFFER_STATE>(
3469 *pFramebuffer, pCreateInfo, GetRenderPassShared(pCreateInfo->renderPass), std::move(views));
locke-lunargd556cc32019-09-17 01:21:23 -06003470}
3471
locke-lunargd556cc32019-09-17 01:21:23 -06003472void ValidationStateTracker::PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
3473 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3474 VkResult result) {
3475 if (VK_SUCCESS != result) return;
Jeremy Gebben88f58142021-06-01 10:07:52 -06003476 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
locke-lunargd556cc32019-09-17 01:21:23 -06003477}
3478
Mike Schuchardt2df08912020-12-15 16:28:09 -08003479void ValidationStateTracker::PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003480 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3481 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003482 if (VK_SUCCESS != result) return;
3483
3484 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003485}
3486
Mike Schuchardt2df08912020-12-15 16:28:09 -08003487void ValidationStateTracker::PostCallRecordCreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
Tony-LunarG977448c2019-12-02 14:52:02 -07003488 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3489 VkResult result) {
Jeremy Gebben88f58142021-06-01 10:07:52 -06003490 if (VK_SUCCESS != result) return;
3491
3492 renderPassMap[*pRenderPass] = std::make_shared<RENDER_PASS_STATE>(*pRenderPass, pCreateInfo);
Tony-LunarG977448c2019-12-02 14:52:02 -07003493}
3494
locke-lunargd556cc32019-09-17 01:21:23 -06003495void ValidationStateTracker::RecordCmdBeginRenderPassState(VkCommandBuffer commandBuffer,
3496 const VkRenderPassBeginInfo *pRenderPassBegin,
3497 const VkSubpassContents contents) {
3498 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003499 cb_state->BeginRenderPass(pRenderPassBegin, contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003500}
3501
3502void ValidationStateTracker::PreCallRecordCmdBeginRenderPass(VkCommandBuffer commandBuffer,
3503 const VkRenderPassBeginInfo *pRenderPassBegin,
3504 VkSubpassContents contents) {
3505 RecordCmdBeginRenderPassState(commandBuffer, pRenderPassBegin, contents);
3506}
3507
3508void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
3509 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003510 const VkSubpassBeginInfo *pSubpassBeginInfo) {
locke-lunargd556cc32019-09-17 01:21:23 -06003511 RecordCmdBeginRenderPassState(commandBuffer, pRenderPassBegin, pSubpassBeginInfo->contents);
3512}
3513
Jeremy Hayes9bda85a2020-05-21 16:36:17 -06003514void ValidationStateTracker::PostCallRecordCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3515 uint32_t counterBufferCount,
3516 const VkBuffer *pCounterBuffers,
3517 const VkDeviceSize *pCounterBufferOffsets) {
3518 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3519
3520 cb_state->transform_feedback_active = true;
3521}
3522
3523void ValidationStateTracker::PostCallRecordCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
3524 uint32_t counterBufferCount, const VkBuffer *pCounterBuffers,
3525 const VkDeviceSize *pCounterBufferOffsets) {
3526 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3527
3528 cb_state->transform_feedback_active = false;
3529}
3530
ziga-lunarg40f5fbc2021-08-14 23:06:41 +02003531void ValidationStateTracker::PostCallRecordCmdBeginConditionalRenderingEXT(
3532 VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin) {
3533 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3534
3535 cb_state->conditional_rendering_active = true;
3536}
3537
3538void ValidationStateTracker::PostCallRecordCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer) {
3539 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3540
3541 cb_state->conditional_rendering_active = false;
3542
3543}
3544
Tony-LunarG977448c2019-12-02 14:52:02 -07003545void ValidationStateTracker::PreCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
3546 const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003547 const VkSubpassBeginInfo *pSubpassBeginInfo) {
Tony-LunarG977448c2019-12-02 14:52:02 -07003548 RecordCmdBeginRenderPassState(commandBuffer, pRenderPassBegin, pSubpassBeginInfo->contents);
3549}
3550
locke-lunargd556cc32019-09-17 01:21:23 -06003551void ValidationStateTracker::RecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
3552 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003553 cb_state->NextSubpass(contents);
locke-lunargd556cc32019-09-17 01:21:23 -06003554}
3555
3556void ValidationStateTracker::PostCallRecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
3557 RecordCmdNextSubpass(commandBuffer, contents);
3558}
3559
3560void ValidationStateTracker::PostCallRecordCmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003561 const VkSubpassBeginInfo *pSubpassBeginInfo,
3562 const VkSubpassEndInfo *pSubpassEndInfo) {
locke-lunargd556cc32019-09-17 01:21:23 -06003563 RecordCmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
3564}
3565
Tony-LunarG977448c2019-12-02 14:52:02 -07003566void ValidationStateTracker::PostCallRecordCmdNextSubpass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003567 const VkSubpassBeginInfo *pSubpassBeginInfo,
3568 const VkSubpassEndInfo *pSubpassEndInfo) {
Tony-LunarG977448c2019-12-02 14:52:02 -07003569 RecordCmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
3570}
3571
locke-lunargd556cc32019-09-17 01:21:23 -06003572void ValidationStateTracker::RecordCmdEndRenderPassState(VkCommandBuffer commandBuffer) {
3573 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003574 cb_state->EndRenderPass();
locke-lunargd556cc32019-09-17 01:21:23 -06003575}
3576
3577void ValidationStateTracker::PostCallRecordCmdEndRenderPass(VkCommandBuffer commandBuffer) {
3578 RecordCmdEndRenderPassState(commandBuffer);
3579}
3580
3581void ValidationStateTracker::PostCallRecordCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003582 const VkSubpassEndInfo *pSubpassEndInfo) {
locke-lunargd556cc32019-09-17 01:21:23 -06003583 RecordCmdEndRenderPassState(commandBuffer);
3584}
3585
Tony-LunarG977448c2019-12-02 14:52:02 -07003586void ValidationStateTracker::PostCallRecordCmdEndRenderPass2(VkCommandBuffer commandBuffer,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003587 const VkSubpassEndInfo *pSubpassEndInfo) {
Tony-LunarG977448c2019-12-02 14:52:02 -07003588 RecordCmdEndRenderPassState(commandBuffer);
3589}
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003590
locke-lunargd556cc32019-09-17 01:21:23 -06003591void ValidationStateTracker::PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
3592 const VkCommandBuffer *pCommandBuffers) {
3593 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
3594
Jeremy Gebben1ec89332021-08-05 13:51:49 -06003595 cb_state->ExecuteCommands(commandBuffersCount, pCommandBuffers);
locke-lunargd556cc32019-09-17 01:21:23 -06003596}
3597
3598void ValidationStateTracker::PostCallRecordMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size,
3599 VkFlags flags, void **ppData, VkResult result) {
3600 if (VK_SUCCESS != result) return;
3601 RecordMappedMemory(mem, offset, size, ppData);
3602}
3603
3604void ValidationStateTracker::PreCallRecordUnmapMemory(VkDevice device, VkDeviceMemory mem) {
3605 auto mem_info = GetDevMemState(mem);
3606 if (mem_info) {
3607 mem_info->mapped_range = MemRange();
3608 mem_info->p_driver_data = nullptr;
3609 }
3610}
3611
3612void ValidationStateTracker::UpdateBindImageMemoryState(const VkBindImageMemoryInfo &bindInfo) {
Jeremy Gebben8ee02af2021-07-16 10:15:55 -06003613 auto image_state = GetShared<IMAGE_STATE>(bindInfo.image);
locke-lunargd556cc32019-09-17 01:21:23 -06003614 if (image_state) {
locke-lunargae26eac2020-04-16 15:29:05 -06003615 // An Android sepcial image cannot get VkSubresourceLayout until the image binds a memory.
3616 // See: VUID-vkGetImageSubresourceLayout-image-01895
3617 image_state->fragment_encoder =
3618 std::unique_ptr<const subresource_adapter::ImageRangeEncoder>(new subresource_adapter::ImageRangeEncoder(*image_state));
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003619 const auto swapchain_info = LvlFindInChain<VkBindImageMemorySwapchainInfoKHR>(bindInfo.pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003620 if (swapchain_info) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003621 auto swapchain = GetShared<SWAPCHAIN_NODE>(swapchain_info->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003622 if (swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003623 SWAPCHAIN_IMAGE &swapchain_image = swapchain->images[swapchain_info->imageIndex];
John Zulaufd13b38e2021-03-05 08:17:38 -07003624
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003625 if (!swapchain_image.fake_base_address) {
3626 auto size = image_state->fragment_encoder->TotalSize();
3627 swapchain_image.fake_base_address = fake_memory.Alloc(size);
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06003628 }
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06003629 // All images bound to this swapchain and index are aliases
3630 image_state->SetSwapchain(swapchain, swapchain_info->imageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003631 }
3632 } else {
3633 // Track bound memory range information
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003634 auto mem_info = GetDevMemShared(bindInfo.memory);
locke-lunargd556cc32019-09-17 01:21:23 -06003635 if (mem_info) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003636 image_state->SetMemBinding(mem_info, bindInfo.memoryOffset);
locke-lunargd556cc32019-09-17 01:21:23 -06003637 }
locke-lunargd556cc32019-09-17 01:21:23 -06003638 }
locke-lunargd556cc32019-09-17 01:21:23 -06003639 }
3640}
3641
3642void ValidationStateTracker::PostCallRecordBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
3643 VkDeviceSize memoryOffset, VkResult result) {
3644 if (VK_SUCCESS != result) return;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003645 auto bind_info = LvlInitStruct<VkBindImageMemoryInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003646 bind_info.image = image;
3647 bind_info.memory = mem;
3648 bind_info.memoryOffset = memoryOffset;
3649 UpdateBindImageMemoryState(bind_info);
locke-lunargd556cc32019-09-17 01:21:23 -06003650}
3651
3652void ValidationStateTracker::PostCallRecordBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003653 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003654 if (VK_SUCCESS != result) return;
3655 for (uint32_t i = 0; i < bindInfoCount; i++) {
3656 UpdateBindImageMemoryState(pBindInfos[i]);
3657 }
3658}
3659
3660void ValidationStateTracker::PostCallRecordBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003661 const VkBindImageMemoryInfo *pBindInfos, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06003662 if (VK_SUCCESS != result) return;
3663 for (uint32_t i = 0; i < bindInfoCount; i++) {
3664 UpdateBindImageMemoryState(pBindInfos[i]);
3665 }
3666}
3667
3668void ValidationStateTracker::PreCallRecordSetEvent(VkDevice device, VkEvent event) {
3669 auto event_state = GetEventState(event);
3670 if (event_state) {
3671 event_state->stageMask = VK_PIPELINE_STAGE_HOST_BIT;
3672 }
locke-lunargd556cc32019-09-17 01:21:23 -06003673}
3674
3675void ValidationStateTracker::PostCallRecordImportSemaphoreFdKHR(VkDevice device,
3676 const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo,
3677 VkResult result) {
3678 if (VK_SUCCESS != result) return;
3679 RecordImportSemaphoreState(pImportSemaphoreFdInfo->semaphore, pImportSemaphoreFdInfo->handleType,
3680 pImportSemaphoreFdInfo->flags);
3681}
3682
3683void ValidationStateTracker::RecordGetExternalSemaphoreState(VkSemaphore semaphore,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003684 VkExternalSemaphoreHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003685 SEMAPHORE_STATE *semaphore_state = GetSemaphoreState(semaphore);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003686 if (semaphore_state && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003687 // Cannot track semaphore state once it is exported, except for Sync FD handle types which have copy transference
3688 semaphore_state->scope = kSyncScopeExternalPermanent;
3689 }
3690}
3691
3692#ifdef VK_USE_PLATFORM_WIN32_KHR
3693void ValidationStateTracker::PostCallRecordImportSemaphoreWin32HandleKHR(
3694 VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR *pImportSemaphoreWin32HandleInfo, VkResult result) {
3695 if (VK_SUCCESS != result) return;
3696 RecordImportSemaphoreState(pImportSemaphoreWin32HandleInfo->semaphore, pImportSemaphoreWin32HandleInfo->handleType,
3697 pImportSemaphoreWin32HandleInfo->flags);
3698}
3699
3700void ValidationStateTracker::PostCallRecordGetSemaphoreWin32HandleKHR(VkDevice device,
3701 const VkSemaphoreGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3702 HANDLE *pHandle, VkResult result) {
3703 if (VK_SUCCESS != result) return;
3704 RecordGetExternalSemaphoreState(pGetWin32HandleInfo->semaphore, pGetWin32HandleInfo->handleType);
3705}
3706
3707void ValidationStateTracker::PostCallRecordImportFenceWin32HandleKHR(
3708 VkDevice device, const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo, VkResult result) {
3709 if (VK_SUCCESS != result) return;
3710 RecordImportFenceState(pImportFenceWin32HandleInfo->fence, pImportFenceWin32HandleInfo->handleType,
3711 pImportFenceWin32HandleInfo->flags);
3712}
3713
3714void ValidationStateTracker::PostCallRecordGetFenceWin32HandleKHR(VkDevice device,
3715 const VkFenceGetWin32HandleInfoKHR *pGetWin32HandleInfo,
3716 HANDLE *pHandle, VkResult result) {
3717 if (VK_SUCCESS != result) return;
3718 RecordGetExternalFenceState(pGetWin32HandleInfo->fence, pGetWin32HandleInfo->handleType);
3719}
3720#endif
3721
3722void ValidationStateTracker::PostCallRecordGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *pGetFdInfo, int *pFd,
3723 VkResult result) {
3724 if (VK_SUCCESS != result) return;
3725 RecordGetExternalSemaphoreState(pGetFdInfo->semaphore, pGetFdInfo->handleType);
3726}
3727
Mike Schuchardt2df08912020-12-15 16:28:09 -08003728void ValidationStateTracker::RecordImportFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type,
3729 VkFenceImportFlags flags) {
locke-lunargd556cc32019-09-17 01:21:23 -06003730 FENCE_STATE *fence_node = GetFenceState(fence);
3731 if (fence_node && fence_node->scope != kSyncScopeExternalPermanent) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003732 if ((handle_type == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT || flags & VK_FENCE_IMPORT_TEMPORARY_BIT) &&
locke-lunargd556cc32019-09-17 01:21:23 -06003733 fence_node->scope == kSyncScopeInternal) {
3734 fence_node->scope = kSyncScopeExternalTemporary;
3735 } else {
3736 fence_node->scope = kSyncScopeExternalPermanent;
3737 }
3738 }
3739}
3740
3741void ValidationStateTracker::PostCallRecordImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo,
3742 VkResult result) {
3743 if (VK_SUCCESS != result) return;
3744 RecordImportFenceState(pImportFenceFdInfo->fence, pImportFenceFdInfo->handleType, pImportFenceFdInfo->flags);
3745}
3746
Mike Schuchardt2df08912020-12-15 16:28:09 -08003747void ValidationStateTracker::RecordGetExternalFenceState(VkFence fence, VkExternalFenceHandleTypeFlagBits handle_type) {
locke-lunargd556cc32019-09-17 01:21:23 -06003748 FENCE_STATE *fence_state = GetFenceState(fence);
3749 if (fence_state) {
Mike Schuchardt2df08912020-12-15 16:28:09 -08003750 if (handle_type != VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT) {
locke-lunargd556cc32019-09-17 01:21:23 -06003751 // Export with reference transference becomes external
3752 fence_state->scope = kSyncScopeExternalPermanent;
3753 } else if (fence_state->scope == kSyncScopeInternal) {
3754 // Export with copy transference has a side effect of resetting the fence
3755 fence_state->state = FENCE_UNSIGNALED;
3756 }
3757 }
3758}
3759
3760void ValidationStateTracker::PostCallRecordGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *pGetFdInfo, int *pFd,
3761 VkResult result) {
3762 if (VK_SUCCESS != result) return;
3763 RecordGetExternalFenceState(pGetFdInfo->fence, pGetFdInfo->handleType);
3764}
3765
3766void ValidationStateTracker::PostCallRecordCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
3767 const VkAllocationCallbacks *pAllocator, VkEvent *pEvent, VkResult result) {
3768 if (VK_SUCCESS != result) return;
John Zulaufd5115702021-01-18 12:34:33 -07003769 const auto event = *pEvent;
Jeremy Gebbencbf22862021-03-03 12:01:22 -07003770 eventMap.emplace(event, std::make_shared<EVENT_STATE>(event, pCreateInfo->flags));
locke-lunargd556cc32019-09-17 01:21:23 -06003771}
3772
3773void ValidationStateTracker::RecordCreateSwapchainState(VkResult result, const VkSwapchainCreateInfoKHR *pCreateInfo,
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003774 VkSwapchainKHR *pSwapchain, std::shared_ptr<SURFACE_STATE> &&surface_state,
locke-lunargd556cc32019-09-17 01:21:23 -06003775 SWAPCHAIN_NODE *old_swapchain_state) {
3776 if (VK_SUCCESS == result) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003777 if (surface_state->swapchain) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003778 surface_state->RemoveParent(surface_state->swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003779 }
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003780 auto swapchain = CreateSwapchainState(pCreateInfo, *pSwapchain);
3781 surface_state->AddParent(swapchain.get());
3782 surface_state->swapchain = swapchain.get();
3783 swapchain->surface = std::move(surface_state);
3784 swapchainMap[*pSwapchain] = std::move(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003785 } else {
3786 surface_state->swapchain = nullptr;
3787 }
3788 // Spec requires that even if CreateSwapchainKHR fails, oldSwapchain is retired
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003789 // Retired swapchains remain associated with the surface until they are destroyed.
locke-lunargd556cc32019-09-17 01:21:23 -06003790 if (old_swapchain_state) {
3791 old_swapchain_state->retired = true;
3792 }
3793 return;
3794}
3795
3796void ValidationStateTracker::PostCallRecordCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
3797 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain,
3798 VkResult result) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003799 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfo->surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003800 auto old_swapchain_state = GetSwapchainState(pCreateInfo->oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003801 RecordCreateSwapchainState(result, pCreateInfo, pSwapchain, std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003802}
3803
3804void ValidationStateTracker::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
3805 const VkAllocationCallbacks *pAllocator) {
3806 if (!swapchain) return;
3807 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003808 if (!swapchain_data) return;
John Zulauffaa7a522021-03-05 12:22:45 -07003809
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003810 swapchain_data->Destroy();
3811 swapchainMap.erase(swapchain);
locke-lunargd556cc32019-09-17 01:21:23 -06003812}
3813
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003814void ValidationStateTracker::PostCallRecordCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
3815 const VkDisplayModeCreateInfoKHR *pCreateInfo,
3816 const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode,
3817 VkResult result) {
3818 if (VK_SUCCESS != result) return;
3819 if (!pMode) return;
Jeremy Gebben5573a8c2021-06-04 08:55:10 -06003820 display_mode_map[*pMode] = std::make_shared<DISPLAY_MODE_STATE>(*pMode, physicalDevice);
sfricke-samsung5c1b7392020-12-13 22:17:15 -08003821}
3822
locke-lunargd556cc32019-09-17 01:21:23 -06003823void ValidationStateTracker::PostCallRecordQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo, VkResult result) {
3824 // Semaphore waits occur before error generation, if the call reached the ICD. (Confirm?)
3825 for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003826 auto semaphore_state = GetSemaphoreState(pPresentInfo->pWaitSemaphores[i]);
3827 if (semaphore_state) {
3828 semaphore_state->signaler.first = VK_NULL_HANDLE;
3829 semaphore_state->signaled = false;
locke-lunargd556cc32019-09-17 01:21:23 -06003830 }
3831 }
3832
Tony-LunarG6f887e52021-07-27 11:23:14 -06003833 const auto *present_id_info = LvlFindInChain<VkPresentIdKHR>(pPresentInfo->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06003834 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
3835 // 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
3836 // confused itself just as much.
3837 auto local_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result;
3838 if (local_result != VK_SUCCESS && local_result != VK_SUBOPTIMAL_KHR) continue; // this present didn't actually happen.
3839 // Mark the image as having been released to the WSI
3840 auto swapchain_data = GetSwapchainState(pPresentInfo->pSwapchains[i]);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003841 if (swapchain_data) {
3842 swapchain_data->PresentImage(pPresentInfo->pImageIndices[i]);
Tony-LunarG6f887e52021-07-27 11:23:14 -06003843 if (present_id_info) {
3844 if (i < present_id_info->swapchainCount && present_id_info->pPresentIds[i] > swapchain_data->max_present_id) {
3845 swapchain_data->max_present_id = present_id_info->pPresentIds[i];
3846 }
3847 }
locke-lunargd556cc32019-09-17 01:21:23 -06003848 }
3849 }
3850 // Note: even though presentation is directed to a queue, there is no direct ordering between QP and subsequent work, so QP (and
3851 // its semaphore waits) /never/ participate in any completion proof.
3852}
3853
3854void ValidationStateTracker::PostCallRecordCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
3855 const VkSwapchainCreateInfoKHR *pCreateInfos,
3856 const VkAllocationCallbacks *pAllocator,
3857 VkSwapchainKHR *pSwapchains, VkResult result) {
3858 if (pCreateInfos) {
3859 for (uint32_t i = 0; i < swapchainCount; i++) {
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003860 auto surface_state = GetShared<SURFACE_STATE>(pCreateInfos[i].surface);
locke-lunargd556cc32019-09-17 01:21:23 -06003861 auto old_swapchain_state = GetSwapchainState(pCreateInfos[i].oldSwapchain);
Jeremy Gebben5a542f52021-07-21 15:25:52 -06003862 RecordCreateSwapchainState(result, &pCreateInfos[i], &pSwapchains[i], std::move(surface_state), old_swapchain_state);
locke-lunargd556cc32019-09-17 01:21:23 -06003863 }
3864 }
3865}
3866
3867void ValidationStateTracker::RecordAcquireNextImageState(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3868 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003869 auto fence_state = GetFenceState(fence);
3870 if (fence_state && fence_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003871 // Treat as inflight since it is valid to wait on this fence, even in cases where it is technically a temporary
3872 // import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003873 fence_state->state = FENCE_INFLIGHT;
3874 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 -06003875 }
3876
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003877 auto semaphore_state = GetSemaphoreState(semaphore);
3878 if (semaphore_state && semaphore_state->scope == kSyncScopeInternal) {
locke-lunargd556cc32019-09-17 01:21:23 -06003879 // Treat as signaled since it is valid to wait on this semaphore, even in cases where it is technically a
3880 // temporary import
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003881 semaphore_state->signaled = true;
3882 semaphore_state->signaler.first = VK_NULL_HANDLE;
locke-lunargd556cc32019-09-17 01:21:23 -06003883 }
3884
3885 // Mark the image as acquired.
3886 auto swapchain_data = GetSwapchainState(swapchain);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06003887 if (swapchain_data) {
3888 swapchain_data->AcquireImage(*pImageIndex);
locke-lunargd556cc32019-09-17 01:21:23 -06003889 }
3890}
3891
3892void ValidationStateTracker::PostCallRecordAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
3893 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex,
3894 VkResult result) {
3895 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3896 RecordAcquireNextImageState(device, swapchain, timeout, semaphore, fence, pImageIndex);
3897}
3898
3899void ValidationStateTracker::PostCallRecordAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
3900 uint32_t *pImageIndex, VkResult result) {
3901 if ((VK_SUCCESS != result) && (VK_SUBOPTIMAL_KHR != result)) return;
3902 RecordAcquireNextImageState(device, pAcquireInfo->swapchain, pAcquireInfo->timeout, pAcquireInfo->semaphore,
3903 pAcquireInfo->fence, pImageIndex);
3904}
3905
3906void ValidationStateTracker::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
3907 VkPhysicalDevice *pPhysicalDevices, VkResult result) {
3908 if ((NULL != pPhysicalDevices) && ((result == VK_SUCCESS || result == VK_INCOMPLETE))) {
3909 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
3910 auto &phys_device_state = physical_device_map[pPhysicalDevices[i]];
3911 phys_device_state.phys_device = pPhysicalDevices[i];
3912 // Init actual features for each physical device
3913 DispatchGetPhysicalDeviceFeatures(pPhysicalDevices[i], &phys_device_state.features2.features);
3914 }
3915 }
3916}
3917
3918// Common function to update state for GetPhysicalDeviceQueueFamilyProperties & 2KHR version
3919static void StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count,
Mike Schuchardt2df08912020-12-15 16:28:09 -08003920 VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003921 pd_state->queue_family_known_count = std::max(pd_state->queue_family_known_count, count);
3922
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06003923 if (pQueueFamilyProperties) { // Save queue family properties
locke-lunargd556cc32019-09-17 01:21:23 -06003924 pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
3925 for (uint32_t i = 0; i < count; ++i) {
3926 pd_state->queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
3927 }
3928 }
3929}
3930
3931void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
3932 uint32_t *pQueueFamilyPropertyCount,
3933 VkQueueFamilyProperties *pQueueFamilyProperties) {
3934 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3935 assert(physical_device_state);
Mike Schuchardt2df08912020-12-15 16:28:09 -08003936 VkQueueFamilyProperties2 *pqfp = nullptr;
3937 std::vector<VkQueueFamilyProperties2> qfp;
locke-lunargd556cc32019-09-17 01:21:23 -06003938 qfp.resize(*pQueueFamilyPropertyCount);
3939 if (pQueueFamilyProperties) {
3940 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06003941 qfp[i] = LvlInitStruct<VkQueueFamilyProperties2>();
locke-lunargd556cc32019-09-17 01:21:23 -06003942 qfp[i].queueFamilyProperties = pQueueFamilyProperties[i];
3943 }
3944 pqfp = qfp.data();
3945 }
3946 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount, pqfp);
3947}
3948
3949void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003950 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003951 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3952 assert(physical_device_state);
3953 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3954 pQueueFamilyProperties);
3955}
3956
3957void ValidationStateTracker::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08003958 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06003959 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
3960 assert(physical_device_state);
3961 StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount,
3962 pQueueFamilyProperties);
3963}
3964void ValidationStateTracker::PreCallRecordDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
3965 const VkAllocationCallbacks *pAllocator) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003966 if (!surface) return;
3967 auto surface_state = GetSurfaceState(surface);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003968 surface_state->Destroy();
locke-lunargd556cc32019-09-17 01:21:23 -06003969 surface_map.erase(surface);
3970}
3971
3972void ValidationStateTracker::RecordVulkanSurface(VkSurfaceKHR *pSurface) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05003973 surface_map[*pSurface] = std::make_shared<SURFACE_STATE>(*pSurface);
locke-lunargd556cc32019-09-17 01:21:23 -06003974}
3975
3976void ValidationStateTracker::PostCallRecordCreateDisplayPlaneSurfaceKHR(VkInstance instance,
3977 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
3978 const VkAllocationCallbacks *pAllocator,
3979 VkSurfaceKHR *pSurface, VkResult result) {
3980 if (VK_SUCCESS != result) return;
3981 RecordVulkanSurface(pSurface);
3982}
3983
3984#ifdef VK_USE_PLATFORM_ANDROID_KHR
3985void ValidationStateTracker::PostCallRecordCreateAndroidSurfaceKHR(VkInstance instance,
3986 const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
3987 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3988 VkResult result) {
3989 if (VK_SUCCESS != result) return;
3990 RecordVulkanSurface(pSurface);
3991}
3992#endif // VK_USE_PLATFORM_ANDROID_KHR
3993
3994#ifdef VK_USE_PLATFORM_IOS_MVK
3995void ValidationStateTracker::PostCallRecordCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
3996 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
3997 VkResult result) {
3998 if (VK_SUCCESS != result) return;
3999 RecordVulkanSurface(pSurface);
4000}
4001#endif // VK_USE_PLATFORM_IOS_MVK
4002
4003#ifdef VK_USE_PLATFORM_MACOS_MVK
4004void ValidationStateTracker::PostCallRecordCreateMacOSSurfaceMVK(VkInstance instance,
4005 const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
4006 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4007 VkResult result) {
4008 if (VK_SUCCESS != result) return;
4009 RecordVulkanSurface(pSurface);
4010}
4011#endif // VK_USE_PLATFORM_MACOS_MVK
4012
Jeremy Kniagerf33a67c2019-12-09 09:44:39 -07004013#ifdef VK_USE_PLATFORM_METAL_EXT
4014void ValidationStateTracker::PostCallRecordCreateMetalSurfaceEXT(VkInstance instance,
4015 const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
4016 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4017 VkResult result) {
4018 if (VK_SUCCESS != result) return;
4019 RecordVulkanSurface(pSurface);
4020}
4021#endif // VK_USE_PLATFORM_METAL_EXT
4022
locke-lunargd556cc32019-09-17 01:21:23 -06004023#ifdef VK_USE_PLATFORM_WAYLAND_KHR
4024void ValidationStateTracker::PostCallRecordCreateWaylandSurfaceKHR(VkInstance instance,
4025 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
4026 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4027 VkResult result) {
4028 if (VK_SUCCESS != result) return;
4029 RecordVulkanSurface(pSurface);
4030}
4031#endif // VK_USE_PLATFORM_WAYLAND_KHR
4032
4033#ifdef VK_USE_PLATFORM_WIN32_KHR
4034void ValidationStateTracker::PostCallRecordCreateWin32SurfaceKHR(VkInstance instance,
4035 const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
4036 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4037 VkResult result) {
4038 if (VK_SUCCESS != result) return;
4039 RecordVulkanSurface(pSurface);
4040}
4041#endif // VK_USE_PLATFORM_WIN32_KHR
4042
4043#ifdef VK_USE_PLATFORM_XCB_KHR
4044void ValidationStateTracker::PostCallRecordCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
4045 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4046 VkResult result) {
4047 if (VK_SUCCESS != result) return;
4048 RecordVulkanSurface(pSurface);
4049}
4050#endif // VK_USE_PLATFORM_XCB_KHR
4051
4052#ifdef VK_USE_PLATFORM_XLIB_KHR
4053void ValidationStateTracker::PostCallRecordCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
4054 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4055 VkResult result) {
4056 if (VK_SUCCESS != result) return;
4057 RecordVulkanSurface(pSurface);
4058}
4059#endif // VK_USE_PLATFORM_XLIB_KHR
4060
Niklas Haas8b84af12020-04-19 22:20:11 +02004061void ValidationStateTracker::PostCallRecordCreateHeadlessSurfaceEXT(VkInstance instance,
4062 const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
4063 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
4064 VkResult result) {
4065 if (VK_SUCCESS != result) return;
4066 RecordVulkanSurface(pSurface);
4067}
4068
Cort23cf2282019-09-20 18:58:18 +02004069void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02004070 VkPhysicalDeviceFeatures *pFeatures) {
4071 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Yilong Li358152a2020-07-08 02:16:45 -07004072 // Reset the features2 safe struct before setting up the features field.
4073 physical_device_state->features2 = safe_VkPhysicalDeviceFeatures2();
Cortffba2642019-09-20 22:09:41 +02004074 physical_device_state->features2.features = *pFeatures;
Cort23cf2282019-09-20 18:58:18 +02004075}
4076
4077void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02004078 VkPhysicalDeviceFeatures2 *pFeatures) {
4079 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02004080 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02004081}
4082
4083void ValidationStateTracker::PostCallRecordGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
Cortffba2642019-09-20 22:09:41 +02004084 VkPhysicalDeviceFeatures2 *pFeatures) {
4085 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
Cortffba2642019-09-20 22:09:41 +02004086 physical_device_state->features2.initialize(pFeatures);
Cort23cf2282019-09-20 18:58:18 +02004087}
4088
locke-lunargd556cc32019-09-17 01:21:23 -06004089void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
4090 VkSurfaceKHR surface,
4091 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities,
4092 VkResult result) {
4093 if (VK_SUCCESS != result) return;
4094 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004095 physical_device_state->surfaceCapabilities = *pSurfaceCapabilities;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004096
4097 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
4098 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004099}
4100
4101void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(
4102 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
4103 VkSurfaceCapabilities2KHR *pSurfaceCapabilities, VkResult result) {
4104 if (VK_SUCCESS != result) return;
4105 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004106 physical_device_state->surfaceCapabilities = pSurfaceCapabilities->surfaceCapabilities;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004107
4108 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
4109 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004110}
4111
4112void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,
4113 VkSurfaceKHR surface,
4114 VkSurfaceCapabilities2EXT *pSurfaceCapabilities,
4115 VkResult result) {
4116 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004117 physical_device_state->surfaceCapabilities.minImageCount = pSurfaceCapabilities->minImageCount;
4118 physical_device_state->surfaceCapabilities.maxImageCount = pSurfaceCapabilities->maxImageCount;
4119 physical_device_state->surfaceCapabilities.currentExtent = pSurfaceCapabilities->currentExtent;
4120 physical_device_state->surfaceCapabilities.minImageExtent = pSurfaceCapabilities->minImageExtent;
4121 physical_device_state->surfaceCapabilities.maxImageExtent = pSurfaceCapabilities->maxImageExtent;
4122 physical_device_state->surfaceCapabilities.maxImageArrayLayers = pSurfaceCapabilities->maxImageArrayLayers;
4123 physical_device_state->surfaceCapabilities.supportedTransforms = pSurfaceCapabilities->supportedTransforms;
4124 physical_device_state->surfaceCapabilities.currentTransform = pSurfaceCapabilities->currentTransform;
4125 physical_device_state->surfaceCapabilities.supportedCompositeAlpha = pSurfaceCapabilities->supportedCompositeAlpha;
4126 physical_device_state->surfaceCapabilities.supportedUsageFlags = pSurfaceCapabilities->supportedUsageFlags;
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004127
4128 // TODO May make sense to move this to BestPractices, but needs further refactoring in CoreChecks first
4129 physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004130}
4131
4132void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
4133 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
4134 VkBool32 *pSupported, VkResult result) {
4135 if (VK_SUCCESS != result) return;
4136 auto surface_state = GetSurfaceState(surface);
4137 surface_state->gpu_queue_support[{physicalDevice, queueFamilyIndex}] = (*pSupported == VK_TRUE);
4138}
4139
4140void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
4141 VkSurfaceKHR surface,
4142 uint32_t *pPresentModeCount,
4143 VkPresentModeKHR *pPresentModes,
4144 VkResult result) {
4145 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4146
4147 // TODO: This isn't quite right -- available modes may differ by surface AND physical device.
4148 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004149
4150 if (*pPresentModeCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004151 if (*pPresentModeCount > physical_device_state->present_modes.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06004152 physical_device_state->present_modes.resize(*pPresentModeCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004153 }
locke-lunargd556cc32019-09-17 01:21:23 -06004154 }
4155 if (pPresentModes) {
locke-lunargd556cc32019-09-17 01:21:23 -06004156 for (uint32_t i = 0; i < *pPresentModeCount; i++) {
4157 physical_device_state->present_modes[i] = pPresentModes[i];
4158 }
4159 }
4160}
4161
4162void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
4163 uint32_t *pSurfaceFormatCount,
4164 VkSurfaceFormatKHR *pSurfaceFormats,
4165 VkResult result) {
4166 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4167
4168 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004169
4170 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004171 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
locke-lunargd556cc32019-09-17 01:21:23 -06004172 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004173 }
locke-lunargd556cc32019-09-17 01:21:23 -06004174 }
4175 if (pSurfaceFormats) {
locke-lunargd556cc32019-09-17 01:21:23 -06004176 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
4177 physical_device_state->surface_formats[i] = pSurfaceFormats[i];
4178 }
4179 }
4180}
4181
4182void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
4183 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
4184 uint32_t *pSurfaceFormatCount,
4185 VkSurfaceFormat2KHR *pSurfaceFormats,
4186 VkResult result) {
4187 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4188
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004189 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
locke-lunargd556cc32019-09-17 01:21:23 -06004190 if (*pSurfaceFormatCount) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004191 if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) {
4192 physical_device_state->surface_formats.resize(*pSurfaceFormatCount);
4193 }
locke-lunargd556cc32019-09-17 01:21:23 -06004194 }
4195 if (pSurfaceFormats) {
locke-lunargd556cc32019-09-17 01:21:23 -06004196 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004197 physical_device_state->surface_formats[i] = pSurfaceFormats[i].surfaceFormat;
locke-lunargd556cc32019-09-17 01:21:23 -06004198 }
4199 }
4200}
4201
4202void ValidationStateTracker::PreCallRecordCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4203 const VkDebugUtilsLabelEXT *pLabelInfo) {
4204 BeginCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4205}
4206
4207void ValidationStateTracker::PostCallRecordCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
4208 EndCmdDebugUtilsLabel(report_data, commandBuffer);
4209}
4210
4211void ValidationStateTracker::PreCallRecordCmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
4212 const VkDebugUtilsLabelEXT *pLabelInfo) {
4213 InsertCmdDebugUtilsLabel(report_data, commandBuffer, pLabelInfo);
4214
4215 // Squirrel away an easily accessible copy.
4216 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4217 cb_state->debug_label = LoggingLabel(pLabelInfo);
4218}
4219
4220void ValidationStateTracker::RecordEnumeratePhysicalDeviceGroupsState(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004221 uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
locke-lunargd556cc32019-09-17 01:21:23 -06004222 if (NULL != pPhysicalDeviceGroupProperties) {
4223 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
4224 for (uint32_t j = 0; j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount; j++) {
4225 VkPhysicalDevice cur_phys_dev = pPhysicalDeviceGroupProperties[i].physicalDevices[j];
4226 auto &phys_device_state = physical_device_map[cur_phys_dev];
4227 phys_device_state.phys_device = cur_phys_dev;
4228 // Init actual features for each physical device
4229 DispatchGetPhysicalDeviceFeatures(cur_phys_dev, &phys_device_state.features2.features);
4230 }
4231 }
4232 }
4233}
4234
4235void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroups(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004236 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004237 VkResult result) {
4238 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4239 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4240}
4241
4242void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceGroupsKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004243 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
locke-lunargd556cc32019-09-17 01:21:23 -06004244 VkResult result) {
4245 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4246 RecordEnumeratePhysicalDeviceGroupsState(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
4247}
4248
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004249void ValidationStateTracker::RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(VkPhysicalDevice physicalDevice,
4250 uint32_t queueFamilyIndex,
4251 uint32_t *pCounterCount,
4252 VkPerformanceCounterKHR *pCounters) {
4253 if (NULL == pCounters) return;
4254
4255 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4256 assert(physical_device_state);
4257
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004258 std::unique_ptr<QUEUE_FAMILY_PERF_COUNTERS> queue_family_counters(new QUEUE_FAMILY_PERF_COUNTERS());
4259 queue_family_counters->counters.resize(*pCounterCount);
4260 for (uint32_t i = 0; i < *pCounterCount; i++) queue_family_counters->counters[i] = pCounters[i];
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004261
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004262 physical_device_state->perf_counters[queueFamilyIndex] = std::move(queue_family_counters);
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004263}
4264
4265void ValidationStateTracker::PostCallRecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
4266 VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t *pCounterCount, VkPerformanceCounterKHR *pCounters,
4267 VkPerformanceCounterDescriptionKHR *pCounterDescriptions, VkResult result) {
4268 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4269 RecordEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(physicalDevice, queueFamilyIndex, pCounterCount, pCounters);
4270}
4271
4272void ValidationStateTracker::PostCallRecordAcquireProfilingLockKHR(VkDevice device, const VkAcquireProfilingLockInfoKHR *pInfo,
4273 VkResult result) {
4274 if (result == VK_SUCCESS) performance_lock_acquired = true;
4275}
4276
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004277void ValidationStateTracker::PostCallRecordReleaseProfilingLockKHR(VkDevice device) {
4278 performance_lock_acquired = false;
4279 for (auto &cmd_buffer : commandBufferMap) {
4280 cmd_buffer.second->performance_lock_released = true;
4281 }
4282}
4283
locke-lunargd556cc32019-09-17 01:21:23 -06004284void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplate(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004285 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004286 const VkAllocationCallbacks *pAllocator) {
4287 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004288 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4289 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004290 desc_template_map.erase(descriptorUpdateTemplate);
4291}
4292
4293void ValidationStateTracker::PreCallRecordDestroyDescriptorUpdateTemplateKHR(VkDevice device,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004294 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004295 const VkAllocationCallbacks *pAllocator) {
4296 if (!descriptorUpdateTemplate) return;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004297 auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4298 template_state->destroyed = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004299 desc_template_map.erase(descriptorUpdateTemplate);
4300}
4301
Mike Schuchardt2df08912020-12-15 16:28:09 -08004302void ValidationStateTracker::RecordCreateDescriptorUpdateTemplateState(const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4303 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
locke-lunargd556cc32019-09-17 01:21:23 -06004304 safe_VkDescriptorUpdateTemplateCreateInfo local_create_info(pCreateInfo);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004305 auto template_state = std::make_shared<TEMPLATE_STATE>(*pDescriptorUpdateTemplate, &local_create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004306 desc_template_map[*pDescriptorUpdateTemplate] = std::move(template_state);
4307}
4308
Mike Schuchardt2df08912020-12-15 16:28:09 -08004309void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplate(VkDevice device,
4310 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
4311 const VkAllocationCallbacks *pAllocator,
4312 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate,
4313 VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004314 if (VK_SUCCESS != result) return;
4315 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4316}
4317
4318void ValidationStateTracker::PostCallRecordCreateDescriptorUpdateTemplateKHR(
Mike Schuchardt2df08912020-12-15 16:28:09 -08004319 VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
4320 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate, VkResult result) {
locke-lunargd556cc32019-09-17 01:21:23 -06004321 if (VK_SUCCESS != result) return;
4322 RecordCreateDescriptorUpdateTemplateState(pCreateInfo, pDescriptorUpdateTemplate);
4323}
4324
4325void ValidationStateTracker::RecordUpdateDescriptorSetWithTemplateState(VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004326 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004327 const void *pData) {
4328 auto const template_map_entry = desc_template_map.find(descriptorUpdateTemplate);
4329 if ((template_map_entry == desc_template_map.end()) || (template_map_entry->second.get() == nullptr)) {
4330 assert(0);
4331 } else {
4332 const TEMPLATE_STATE *template_state = template_map_entry->second.get();
4333 // TODO: Record template push descriptor updates
4334 if (template_state->create_info.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET) {
4335 PerformUpdateDescriptorSetsWithTemplateKHR(descriptorSet, template_state, pData);
4336 }
4337 }
4338}
4339
4340void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
4341 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4342 const void *pData) {
4343 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4344}
4345
4346void ValidationStateTracker::PreCallRecordUpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
Mike Schuchardt2df08912020-12-15 16:28:09 -08004347 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
locke-lunargd556cc32019-09-17 01:21:23 -06004348 const void *pData) {
4349 RecordUpdateDescriptorSetWithTemplateState(descriptorSet, descriptorUpdateTemplate, pData);
4350}
4351
Mike Schuchardt2df08912020-12-15 16:28:09 -08004352void ValidationStateTracker::PreCallRecordCmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
4353 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
4354 VkPipelineLayout layout, uint32_t set,
4355 const void *pData) {
locke-lunargd556cc32019-09-17 01:21:23 -06004356 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4357
4358 const auto template_state = GetDescriptorTemplateState(descriptorUpdateTemplate);
4359 if (template_state) {
4360 auto layout_data = GetPipelineLayout(layout);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06004361 auto dsl = layout_data ? layout_data->GetDsl(set) : nullptr;
locke-lunargd556cc32019-09-17 01:21:23 -06004362 const auto &template_ci = template_state->create_info;
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004363 // Decode the template into a set of write updates
4364 cvdescriptorset::DecodedTemplateUpdate decoded_template(this, VK_NULL_HANDLE, template_state, pData,
4365 dsl->GetDescriptorSetLayout());
4366 cb_state->PushDescriptorSetState(template_ci.pipelineBindPoint, layout_data, set,
4367 static_cast<uint32_t>(decoded_template.desc_writes.size()),
4368 decoded_template.desc_writes.data());
locke-lunargd556cc32019-09-17 01:21:23 -06004369 }
4370}
4371
4372void ValidationStateTracker::RecordGetPhysicalDeviceDisplayPlanePropertiesState(VkPhysicalDevice physicalDevice,
4373 uint32_t *pPropertyCount, void *pProperties) {
4374 auto physical_device_state = GetPhysicalDeviceState(physicalDevice);
4375 if (*pPropertyCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004376 physical_device_state->display_plane_property_count = *pPropertyCount;
4377 }
Nathaniel Cesario24184fe2020-10-06 12:46:12 -06004378 if (*pPropertyCount || pProperties) {
4379 physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHR_called = true;
locke-lunargd556cc32019-09-17 01:21:23 -06004380 }
4381}
4382
4383void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
4384 uint32_t *pPropertyCount,
4385 VkDisplayPlanePropertiesKHR *pProperties,
4386 VkResult result) {
4387 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4388 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4389}
4390
4391void ValidationStateTracker::PostCallRecordGetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
4392 uint32_t *pPropertyCount,
4393 VkDisplayPlaneProperties2KHR *pProperties,
4394 VkResult result) {
4395 if ((VK_SUCCESS != result) && (VK_INCOMPLETE != result)) return;
4396 RecordGetPhysicalDeviceDisplayPlanePropertiesState(physicalDevice, pPropertyCount, pProperties);
4397}
4398
4399void ValidationStateTracker::PostCallRecordCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4400 uint32_t query, VkQueryControlFlags flags, uint32_t index) {
4401 QueryObject query_obj = {queryPool, query, index};
4402 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004403 cb_state->BeginQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004404}
4405
4406void ValidationStateTracker::PostCallRecordCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
4407 uint32_t query, uint32_t index) {
4408 QueryObject query_obj = {queryPool, query, index};
4409 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004410 cb_state->EndQuery(query_obj);
locke-lunargd556cc32019-09-17 01:21:23 -06004411}
4412
4413void ValidationStateTracker::RecordCreateSamplerYcbcrConversionState(const VkSamplerYcbcrConversionCreateInfo *create_info,
4414 VkSamplerYcbcrConversion ycbcr_conversion) {
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004415 VkFormatFeatureFlags format_features = 0;
4416
4417 if (create_info->format != VK_FORMAT_UNDEFINED) {
4418 format_features = GetPotentialFormatFeatures(create_info->format);
4419 } else if (device_extensions.vk_android_external_memory_android_hardware_buffer) {
4420 // If format is VK_FORMAT_UNDEFINED, format_features will be set by external AHB features
4421 format_features = GetExternalFormatFeaturesANDROID(create_info);
locke-lunargd556cc32019-09-17 01:21:23 -06004422 }
Jeremy Gebbenf4fb2a02021-07-08 09:57:46 -06004423
4424 samplerYcbcrConversionMap[ycbcr_conversion] =
4425 std::make_shared<SAMPLER_YCBCR_CONVERSION_STATE>(ycbcr_conversion, create_info, format_features);
locke-lunargd556cc32019-09-17 01:21:23 -06004426}
4427
4428void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversion(VkDevice device,
4429 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4430 const VkAllocationCallbacks *pAllocator,
4431 VkSamplerYcbcrConversion *pYcbcrConversion,
4432 VkResult result) {
4433 if (VK_SUCCESS != result) return;
4434 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4435}
4436
4437void ValidationStateTracker::PostCallRecordCreateSamplerYcbcrConversionKHR(VkDevice device,
4438 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
4439 const VkAllocationCallbacks *pAllocator,
4440 VkSamplerYcbcrConversion *pYcbcrConversion,
4441 VkResult result) {
4442 if (VK_SUCCESS != result) return;
4443 RecordCreateSamplerYcbcrConversionState(pCreateInfo, *pYcbcrConversion);
4444}
4445
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004446void ValidationStateTracker::RecordDestroySamplerYcbcrConversionState(VkSamplerYcbcrConversion ycbcr_conversion) {
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004447 auto ycbcr_state = GetSamplerYcbcrConversionState(ycbcr_conversion);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004448 ycbcr_state->Destroy();
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004449 samplerYcbcrConversionMap.erase(ycbcr_conversion);
4450}
4451
locke-lunargd556cc32019-09-17 01:21:23 -06004452void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
4453 const VkAllocationCallbacks *pAllocator) {
4454 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004455 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004456}
4457
4458void ValidationStateTracker::PostCallRecordDestroySamplerYcbcrConversionKHR(VkDevice device,
4459 VkSamplerYcbcrConversion ycbcrConversion,
4460 const VkAllocationCallbacks *pAllocator) {
4461 if (!ycbcrConversion) return;
sfricke-samsungbe3584f2020-04-22 14:58:06 -07004462 RecordDestroySamplerYcbcrConversionState(ycbcrConversion);
locke-lunargd556cc32019-09-17 01:21:23 -06004463}
4464
Tony-LunarG977448c2019-12-02 14:52:02 -07004465void ValidationStateTracker::RecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4466 uint32_t queryCount) {
locke-lunargd556cc32019-09-17 01:21:23 -06004467 // Do nothing if the feature is not enabled.
Piers Daniell41b8c5d2020-01-10 15:42:00 -07004468 if (!enabled_features.core12.hostQueryReset) return;
locke-lunargd556cc32019-09-17 01:21:23 -06004469
4470 // Do nothing if the query pool has been destroyed.
4471 auto query_pool_state = GetQueryPoolState(queryPool);
4472 if (!query_pool_state) return;
4473
4474 // Reset the state of existing entries.
4475 QueryObject query_obj{queryPool, 0};
4476 const uint32_t max_query_count = std::min(queryCount, query_pool_state->createInfo.queryCount - firstQuery);
4477 for (uint32_t i = 0; i < max_query_count; ++i) {
4478 query_obj.query = firstQuery + i;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004479 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004480 if (query_pool_state->createInfo.queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004481 for (uint32_t pass_index = 0; pass_index < query_pool_state->n_performance_passes; pass_index++) {
4482 query_obj.perf_pass = pass_index;
Lionel Landwerlin7dc796b2020-02-18 18:17:10 +02004483 queryToStateMap[query_obj] = QUERYSTATE_RESET;
Lionel Landwerlinc7420912019-05-23 00:33:42 +01004484 }
4485 }
locke-lunargd556cc32019-09-17 01:21:23 -06004486 }
4487}
4488
Tony-LunarG977448c2019-12-02 14:52:02 -07004489void ValidationStateTracker::PostCallRecordResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4490 uint32_t queryCount) {
4491 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4492}
4493
4494void ValidationStateTracker::PostCallRecordResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
4495 uint32_t queryCount) {
4496 RecordResetQueryPool(device, queryPool, firstQuery, queryCount);
4497}
4498
locke-lunargd556cc32019-09-17 01:21:23 -06004499void ValidationStateTracker::PerformUpdateDescriptorSetsWithTemplateKHR(VkDescriptorSet descriptorSet,
4500 const TEMPLATE_STATE *template_state, const void *pData) {
4501 // Translate the templated update into a normal update for validation...
4502 cvdescriptorset::DecodedTemplateUpdate decoded_update(this, descriptorSet, template_state, pData);
4503 cvdescriptorset::PerformUpdateDescriptorSets(this, static_cast<uint32_t>(decoded_update.desc_writes.size()),
4504 decoded_update.desc_writes.data(), 0, NULL);
4505}
4506
4507// Update the common AllocateDescriptorSetsData
4508void ValidationStateTracker::UpdateAllocateDescriptorSetsData(const VkDescriptorSetAllocateInfo *p_alloc_info,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05004509 cvdescriptorset::AllocateDescriptorSetsData *ds_data) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004510 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05004511 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
locke-lunargd556cc32019-09-17 01:21:23 -06004512 if (layout) {
4513 ds_data->layout_nodes[i] = layout;
4514 // Count total descriptors required per type
4515 for (uint32_t j = 0; j < layout->GetBindingCount(); ++j) {
4516 const auto &binding_layout = layout->GetDescriptorSetLayoutBindingPtrFromIndex(j);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004517 uint32_t type_index = static_cast<uint32_t>(binding_layout->descriptorType);
4518 ds_data->required_descriptors_by_type[type_index] += binding_layout->descriptorCount;
locke-lunargd556cc32019-09-17 01:21:23 -06004519 }
4520 }
4521 // Any unknown layouts will be flagged as errors during ValidateAllocateDescriptorSets() call
4522 }
4523}
4524
4525// Decrement allocated sets from the pool and insert new sets into set_map
4526void ValidationStateTracker::PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
4527 const VkDescriptorSet *descriptor_sets,
4528 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) {
4529 auto pool_state = descriptorPoolMap[p_alloc_info->descriptorPool].get();
4530 // Account for sets and individual descriptors allocated from pool
4531 pool_state->availableSets -= p_alloc_info->descriptorSetCount;
4532 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
4533 pool_state->availableDescriptorTypeCount[it->first] -= ds_data->required_descriptors_by_type.at(it->first);
4534 }
4535
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07004536 const auto *variable_count_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(p_alloc_info->pNext);
locke-lunargd556cc32019-09-17 01:21:23 -06004537 bool variable_count_valid = variable_count_info && variable_count_info->descriptorSetCount == p_alloc_info->descriptorSetCount;
4538
4539 // Create tracking object for each descriptor set; insert into global map and the pool's set.
4540 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
4541 uint32_t variable_count = variable_count_valid ? variable_count_info->pDescriptorCounts[i] : 0;
4542
Jeff Bolz41a1ced2019-10-11 11:40:49 -05004543 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 -07004544 variable_count, this);
locke-lunargd556cc32019-09-17 01:21:23 -06004545 pool_state->sets.insert(new_ds.get());
locke-lunargd556cc32019-09-17 01:21:23 -06004546 setMap[descriptor_sets[i]] = std::move(new_ds);
4547 }
4548}
4549
locke-lunargd556cc32019-09-17 01:21:23 -06004550void ValidationStateTracker::PostCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
4551 uint32_t firstVertex, uint32_t firstInstance) {
4552 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004553 cb_state->UpdateStateCmdDrawType(CMD_DRAW, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDraw()");
locke-lunargd556cc32019-09-17 01:21:23 -06004554}
4555
Tony-LunarG745150c2021-07-02 15:07:31 -06004556void ValidationStateTracker::PostCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4557 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
4558 uint32_t firstInstance, uint32_t stride) {
4559 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004560 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004561}
4562
locke-lunargd556cc32019-09-17 01:21:23 -06004563void ValidationStateTracker::PostCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
4564 uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
4565 uint32_t firstInstance) {
4566 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004567 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXED, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexed()");
locke-lunargd556cc32019-09-17 01:21:23 -06004568}
4569
Tony-LunarG745150c2021-07-02 15:07:31 -06004570void ValidationStateTracker::PostCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
4571 const VkMultiDrawIndexedInfoEXT *pIndexInfo,
4572 uint32_t instanceCount, uint32_t firstInstance, uint32_t stride,
4573 const int32_t *pVertexOffset) {
4574 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004575 cb_state->UpdateStateCmdDrawType(CMD_DRAWMULTIINDEXEDEXT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMultiIndexedEXT()");
Tony-LunarG745150c2021-07-02 15:07:31 -06004576}
4577
locke-lunargd556cc32019-09-17 01:21:23 -06004578void ValidationStateTracker::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4579 uint32_t count, uint32_t stride) {
4580 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4581 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004582 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004583 if (!disabled[command_buffer_state]) {
4584 cb_state->AddChild(buffer_state);
4585 }
locke-lunargd556cc32019-09-17 01:21:23 -06004586}
4587
4588void ValidationStateTracker::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4589 VkDeviceSize offset, uint32_t count, uint32_t stride) {
4590 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4591 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004592 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECT, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawIndexedIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004593 if (!disabled[command_buffer_state]) {
4594 cb_state->AddChild(buffer_state);
4595 }
locke-lunargd556cc32019-09-17 01:21:23 -06004596}
4597
4598void ValidationStateTracker::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
4599 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004600 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCH, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatch()");
locke-lunargd556cc32019-09-17 01:21:23 -06004601}
4602
4603void ValidationStateTracker::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
4604 VkDeviceSize offset) {
4605 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004606 cb_state->UpdateStateCmdDrawDispatchType(CMD_DISPATCHINDIRECT, VK_PIPELINE_BIND_POINT_COMPUTE, "vkCmdDispatchIndirect()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004607 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004608 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004609 cb_state->AddChild(buffer_state);
4610 }
locke-lunargd556cc32019-09-17 01:21:23 -06004611}
4612
Tony-LunarG977448c2019-12-02 14:52:02 -07004613void ValidationStateTracker::RecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4614 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
locke-lunarg540b2252020-08-03 13:23:36 -06004615 uint32_t stride, const char *function) {
Tony-LunarG977448c2019-12-02 14:52:02 -07004616 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004617 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004618 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004619 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4620 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004621 cb_state->AddChild(buffer_state);
4622 cb_state->AddChild(count_buffer_state);
4623 }
Tony-LunarG977448c2019-12-02 14:52:02 -07004624}
4625
locke-lunargd556cc32019-09-17 01:21:23 -06004626void ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4627 VkDeviceSize offset, VkBuffer countBuffer,
4628 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4629 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004630 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4631 "vkCmdDrawIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004632}
4633
4634void ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4635 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
4636 uint32_t maxDrawCount, uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004637 RecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4638 "vkCmdDrawIndirectCount()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004639}
4640
4641void ValidationStateTracker::RecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
4642 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
locke-lunarg540b2252020-08-03 13:23:36 -06004643 uint32_t maxDrawCount, uint32_t stride, const char *function) {
locke-lunargd556cc32019-09-17 01:21:23 -06004644 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004645 cb_state->UpdateStateCmdDrawType(CMD_DRAWINDEXEDINDIRECTCOUNT, VK_PIPELINE_BIND_POINT_GRAPHICS, function);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004646 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004647 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4648 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004649 cb_state->AddChild(buffer_state);
4650 cb_state->AddChild(count_buffer_state);
4651 }
locke-lunargd556cc32019-09-17 01:21:23 -06004652}
4653
4654void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
4655 VkDeviceSize offset, VkBuffer countBuffer,
4656 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4657 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004658 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4659 "vkCmdDrawIndexedIndirectCountKHR()");
Tony-LunarG977448c2019-12-02 14:52:02 -07004660}
4661
4662void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
4663 VkDeviceSize offset, VkBuffer countBuffer,
4664 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4665 uint32_t stride) {
locke-lunarg540b2252020-08-03 13:23:36 -06004666 RecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
4667 "vkCmdDrawIndexedIndirectCount()");
locke-lunargd556cc32019-09-17 01:21:23 -06004668}
4669
4670void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount,
4671 uint32_t firstTask) {
4672 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004673 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSNV, VK_PIPELINE_BIND_POINT_GRAPHICS, "vkCmdDrawMeshTasksNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004674}
4675
4676void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4677 VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
4678 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004679 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4680 "vkCmdDrawMeshTasksIndirectNV()");
locke-lunargd556cc32019-09-17 01:21:23 -06004681 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004682 if (!disabled[command_buffer_state] && buffer_state) {
4683 cb_state->AddChild(buffer_state);
locke-lunargd556cc32019-09-17 01:21:23 -06004684 }
4685}
4686
4687void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
4688 VkDeviceSize offset, VkBuffer countBuffer,
4689 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
4690 uint32_t stride) {
4691 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004692 cb_state->UpdateStateCmdDrawType(CMD_DRAWMESHTASKSINDIRECTCOUNTNV, VK_PIPELINE_BIND_POINT_GRAPHICS,
4693 "vkCmdDrawMeshTasksIndirectCountNV()");
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004694 if (!disabled[command_buffer_state]) {
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004695 BUFFER_STATE *buffer_state = GetBufferState(buffer);
4696 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004697 if (buffer_state) {
4698 cb_state->AddChild(buffer_state);
4699 }
4700 if (count_buffer_state) {
4701 cb_state->AddChild(count_buffer_state);
4702 }
locke-lunargd556cc32019-09-17 01:21:23 -06004703 }
4704}
4705
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004706void ValidationStateTracker::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
4707 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
4708 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
4709 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
4710 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
4711 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
4712 uint32_t width, uint32_t height, uint32_t depth) {
4713 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004714 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSNV, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, "vkCmdTraceRaysNV()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004715 cb_state->hasTraceRaysCmd = true;
4716}
4717
4718
4719void ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
4720 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4721 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4722 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4723 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
4724 uint32_t height, uint32_t depth) {
4725 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004726 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, "vkCmdTraceRaysKHR()");
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004727 cb_state->hasTraceRaysCmd = true;
4728}
4729
4730void ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
4731 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
4732 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
4733 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
4734 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
4735 VkDeviceAddress indirectDeviceAddress) {
4736 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jeremy Gebben1ec89332021-08-05 13:51:49 -06004737 cb_state->UpdateStateCmdDrawDispatchType(CMD_TRACERAYSINDIRECTKHR, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
Jeremy Gebben252f60c2021-07-15 14:54:30 -06004738 "vkCmdTraceRaysIndirectKHR()");
4739 cb_state->hasTraceRaysCmd = true;
4740}
4741
locke-lunargd556cc32019-09-17 01:21:23 -06004742void ValidationStateTracker::PostCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
4743 const VkAllocationCallbacks *pAllocator,
4744 VkShaderModule *pShaderModule, VkResult result,
4745 void *csm_state_data) {
4746 if (VK_SUCCESS != result) return;
4747 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
4748
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06004749 spv_target_env spirv_environment = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
locke-lunargd556cc32019-09-17 01:21:23 -06004750 bool is_spirv = (pCreateInfo->pCode[0] == spv::MagicNumber);
Jeff Bolze7fc67b2019-10-04 12:29:31 -05004751 auto new_shader_module = is_spirv ? std::make_shared<SHADER_MODULE_STATE>(pCreateInfo, *pShaderModule, spirv_environment,
4752 csm_state->unique_shader_id)
4753 : std::make_shared<SHADER_MODULE_STATE>();
sfricke-samsung962cad92021-04-13 00:46:29 -07004754 new_shader_module->SetPushConstantUsedInShader();
locke-lunargd556cc32019-09-17 01:21:23 -06004755 shaderModuleMap[*pShaderModule] = std::move(new_shader_module);
4756}
4757
4758void ValidationStateTracker::RecordPipelineShaderStage(VkPipelineShaderStageCreateInfo const *pStage, PIPELINE_STATE *pipeline,
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06004759 PipelineStageState *stage_state) const {
locke-lunargd556cc32019-09-17 01:21:23 -06004760 // Validation shouldn't rely on anything in stage state being valid if the spirv isn't
locke-lunargde3f0fa2020-09-10 11:55:31 -06004761 stage_state->entry_point_name = pStage->pName;
4762 stage_state->shader_state = GetShared<SHADER_MODULE_STATE>(pStage->module);
4763 auto module = stage_state->shader_state.get();
locke-lunargd556cc32019-09-17 01:21:23 -06004764 if (!module->has_valid_spirv) return;
4765
4766 // Validation shouldn't rely on anything in stage state being valid if the entrypoint isn't present
sfricke-samsung962cad92021-04-13 00:46:29 -07004767 auto entrypoint = module->FindEntrypoint(pStage->pName, pStage->stage);
locke-lunargd556cc32019-09-17 01:21:23 -06004768 if (entrypoint == module->end()) return;
4769
locke-lunarg654e3692020-06-04 17:19:15 -06004770 stage_state->stage_flag = pStage->stage;
4771
locke-lunargd556cc32019-09-17 01:21:23 -06004772 // Mark accessible ids
sfricke-samsung962cad92021-04-13 00:46:29 -07004773 stage_state->accessible_ids = module->MarkAccessibleIds(entrypoint);
4774 module->ProcessExecutionModes(entrypoint, pipeline);
locke-lunargd556cc32019-09-17 01:21:23 -06004775
sfricke-samsung962cad92021-04-13 00:46:29 -07004776 stage_state->descriptor_uses = module->CollectInterfaceByDescriptorSlot(
4777 stage_state->accessible_ids, &stage_state->has_writable_descriptor, &stage_state->has_atomic_descriptor);
locke-lunargd556cc32019-09-17 01:21:23 -06004778 // Capture descriptor uses for the pipeline
locke-lunarg36045992020-08-20 16:54:37 -06004779 for (const auto &use : stage_state->descriptor_uses) {
locke-lunargd556cc32019-09-17 01:21:23 -06004780 // While validating shaders capture which slots are used by the pipeline
John Zulauf649edd52019-10-02 14:39:41 -06004781 const uint32_t slot = use.first.first;
locke-lunarg351c9d82020-10-23 14:43:21 -06004782 pipeline->active_slots[slot][use.first.second].is_writable |= use.second.is_writable;
locke-lunarg36045992020-08-20 16:54:37 -06004783 auto &reqs = pipeline->active_slots[slot][use.first.second].reqs;
sfricke-samsung962cad92021-04-13 00:46:29 -07004784 reqs = descriptor_req(reqs | module->DescriptorTypeToReqs(use.second.type_id));
locke-lunarg25b6c352020-08-06 17:44:18 -06004785 if (use.second.is_atomic_operation) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION);
locke-lunarg12d20992020-09-21 12:46:49 -06004786 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 -06004787 if (use.second.is_sampler_bias_offset) reqs = descriptor_req(reqs | DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET);
locke-lunarg12d20992020-09-21 12:46:49 -06004788
John Zulauf649edd52019-10-02 14:39:41 -06004789 pipeline->max_active_slot = std::max(pipeline->max_active_slot, slot);
locke-lunarg36045992020-08-20 16:54:37 -06004790 if (use.second.samplers_used_by_image.size()) {
locke-lunarg654a9052020-10-13 16:28:42 -06004791 auto &samplers_used_by_image = pipeline->active_slots[slot][use.first.second].samplers_used_by_image;
4792 if (use.second.samplers_used_by_image.size() > samplers_used_by_image.size()) {
4793 samplers_used_by_image.resize(use.second.samplers_used_by_image.size());
4794 }
locke-lunarg654a9052020-10-13 16:28:42 -06004795 uint32_t image_index = 0;
4796 for (const auto &samplers : use.second.samplers_used_by_image) {
4797 for (const auto &sampler : samplers) {
locke-lunargb8be8222020-10-20 00:34:37 -06004798 samplers_used_by_image[image_index].emplace(sampler, nullptr);
locke-lunarg654a9052020-10-13 16:28:42 -06004799 }
4800 ++image_index;
4801 }
locke-lunarg36045992020-08-20 16:54:37 -06004802 }
locke-lunargd556cc32019-09-17 01:21:23 -06004803 }
locke-lunarg78486832020-09-09 19:39:42 -06004804
locke-lunarg96dc9632020-06-10 17:22:18 -06004805 if (pStage->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
sfricke-samsung962cad92021-04-13 00:46:29 -07004806 pipeline->fragmentShader_writable_output_location_list = module->CollectWritableOutputLocationinFS(*pStage);
locke-lunarg96dc9632020-06-10 17:22:18 -06004807 }
locke-lunargd556cc32019-09-17 01:21:23 -06004808}
4809
John Zulauf22b0fbe2019-10-15 06:26:16 -06004810void ValidationStateTracker::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
4811 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages,
4812 VkResult result) {
4813 if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004814 auto swapchain_state = GetShared<SWAPCHAIN_NODE>(swapchain);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004815
4816 if (*pSwapchainImageCount > swapchain_state->images.size()) swapchain_state->images.resize(*pSwapchainImageCount);
4817
4818 if (pSwapchainImages) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004819 for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
John Zulauf29d00532021-03-04 13:28:54 -07004820 SWAPCHAIN_IMAGE &swapchain_image = swapchain_state->images[i];
John Zulauffaa7a522021-03-05 12:22:45 -07004821 if (swapchain_image.image_state) continue; // Already retrieved this.
John Zulauf22b0fbe2019-10-15 06:26:16 -06004822
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004823 auto format_features =
4824 GetImageFormatFeatures(physical_device, device, pSwapchainImages[i], swapchain_state->image_create_info.format,
4825 swapchain_state->image_create_info.tiling);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004826
Jeremy Gebbenbcba6d32021-07-16 11:41:41 -06004827 auto image_state = std::make_shared<IMAGE_STATE>(device, pSwapchainImages[i], swapchain_state->image_create_info.ptr(),
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004828 swapchain, i, format_features);
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004829 if (!swapchain_image.fake_base_address) {
4830 auto size = image_state->fragment_encoder->TotalSize();
4831 swapchain_image.fake_base_address = fake_memory.Alloc(size);
John Zulauf29d00532021-03-04 13:28:54 -07004832 }
4833
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06004834 image_state->SetSwapchain(swapchain_state, i);
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004835 swapchain_image.image_state = image_state.get();
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06004836 imageMap[pSwapchainImages[i]] = std::move(image_state);
John Zulauf22b0fbe2019-10-15 06:26:16 -06004837 }
4838 }
4839
4840 if (*pSwapchainImageCount) {
John Zulauf22b0fbe2019-10-15 06:26:16 -06004841 swapchain_state->get_swapchain_image_count = *pSwapchainImageCount;
4842 }
4843}
sourav parmar35e7a002020-06-09 17:58:44 -07004844
sourav parmar35e7a002020-06-09 17:58:44 -07004845void ValidationStateTracker::PostCallRecordCmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer,
4846 const VkCopyAccelerationStructureInfoKHR *pInfo) {
4847 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4848 if (cb_state) {
sourav parmarcd5fb182020-07-17 12:58:44 -07004849 ACCELERATION_STRUCTURE_STATE_KHR *src_as_state = GetAccelerationStructureStateKHR(pInfo->src);
4850 ACCELERATION_STRUCTURE_STATE_KHR *dst_as_state = GetAccelerationStructureStateKHR(pInfo->dst);
sourav parmar35e7a002020-06-09 17:58:44 -07004851 if (dst_as_state != nullptr && src_as_state != nullptr) {
4852 dst_as_state->built = true;
4853 dst_as_state->build_info_khr = src_as_state->build_info_khr;
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004854 if (!disabled[command_buffer_state]) {
4855 cb_state->AddChild(dst_as_state);
4856 cb_state->AddChild(src_as_state);
4857 }
sourav parmar35e7a002020-06-09 17:58:44 -07004858 }
4859 }
4860}
Piers Daniell39842ee2020-07-10 16:42:33 -06004861
4862void ValidationStateTracker::PreCallRecordCmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
4863 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4864 cb_state->status |= CBSTATUS_CULL_MODE_SET;
4865 cb_state->static_status &= ~CBSTATUS_CULL_MODE_SET;
4866}
4867
4868void ValidationStateTracker::PreCallRecordCmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
4869 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4870 cb_state->status |= CBSTATUS_FRONT_FACE_SET;
4871 cb_state->static_status &= ~CBSTATUS_FRONT_FACE_SET;
4872}
4873
4874void ValidationStateTracker::PreCallRecordCmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
4875 VkPrimitiveTopology primitiveTopology) {
4876 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4877 cb_state->primitiveTopology = primitiveTopology;
4878 cb_state->status |= CBSTATUS_PRIMITIVE_TOPOLOGY_SET;
4879 cb_state->static_status &= ~CBSTATUS_PRIMITIVE_TOPOLOGY_SET;
4880}
4881
4882void ValidationStateTracker::PreCallRecordCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer, uint32_t viewportCount,
4883 const VkViewport *pViewports) {
4884 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004885 uint32_t bits = (1u << viewportCount) - 1u;
4886 cb_state->viewportWithCountMask |= bits;
4887 cb_state->trashedViewportMask &= ~bits;
Tobias Hector6663c9b2020-11-05 10:18:02 +00004888 cb_state->viewportWithCountCount = viewportCount;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004889 cb_state->trashedViewportCount = false;
Piers Daniell39842ee2020-07-10 16:42:33 -06004890 cb_state->status |= CBSTATUS_VIEWPORT_WITH_COUNT_SET;
4891 cb_state->static_status &= ~CBSTATUS_VIEWPORT_WITH_COUNT_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07004892
4893 cb_state->dynamicViewports.resize(std::max(size_t(viewportCount), cb_state->dynamicViewports.size()));
4894 for (size_t i = 0; i < viewportCount; ++i) {
4895 cb_state->dynamicViewports[i] = pViewports[i];
4896 }
Piers Daniell39842ee2020-07-10 16:42:33 -06004897}
4898
4899void ValidationStateTracker::PreCallRecordCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount,
4900 const VkRect2D *pScissors) {
4901 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
David Zhao Akeley44139b12021-04-26 16:16:13 -07004902 uint32_t bits = (1u << scissorCount) - 1u;
4903 cb_state->scissorWithCountMask |= bits;
4904 cb_state->trashedScissorMask &= ~bits;
4905 cb_state->scissorWithCountCount = scissorCount;
4906 cb_state->trashedScissorCount = false;
Piers Daniell39842ee2020-07-10 16:42:33 -06004907 cb_state->status |= CBSTATUS_SCISSOR_WITH_COUNT_SET;
4908 cb_state->static_status &= ~CBSTATUS_SCISSOR_WITH_COUNT_SET;
4909}
4910
4911void ValidationStateTracker::PreCallRecordCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
4912 uint32_t bindingCount, const VkBuffer *pBuffers,
4913 const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes,
4914 const VkDeviceSize *pStrides) {
4915 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4916 if (pStrides) {
4917 cb_state->status |= CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET;
4918 cb_state->static_status &= ~CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET;
4919 }
4920
4921 uint32_t end = firstBinding + bindingCount;
4922 if (cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.size() < end) {
4923 cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings.resize(end);
4924 }
4925
4926 for (uint32_t i = 0; i < bindingCount; ++i) {
4927 auto &vertex_buffer_binding = cb_state->current_vertex_buffer_binding_info.vertex_buffer_bindings[i + firstBinding];
locke-lunarg1ae57d62020-11-18 10:49:19 -07004928 vertex_buffer_binding.buffer_state = GetShared<BUFFER_STATE>(pBuffers[i]);
Piers Daniell39842ee2020-07-10 16:42:33 -06004929 vertex_buffer_binding.offset = pOffsets[i];
4930 vertex_buffer_binding.size = (pSizes) ? pSizes[i] : VK_WHOLE_SIZE;
4931 vertex_buffer_binding.stride = (pStrides) ? pStrides[i] : 0;
4932 // Add binding for this vertex buffer to this commandbuffer
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06004933 if (!disabled[command_buffer_state] && pBuffers[i]) {
4934 cb_state->AddChild(vertex_buffer_binding.buffer_state.get());
Piers Daniell39842ee2020-07-10 16:42:33 -06004935 }
4936 }
4937}
4938
4939void ValidationStateTracker::PreCallRecordCmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
4940 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4941 cb_state->status |= CBSTATUS_DEPTH_TEST_ENABLE_SET;
4942 cb_state->static_status &= ~CBSTATUS_DEPTH_TEST_ENABLE_SET;
4943}
4944
4945void ValidationStateTracker::PreCallRecordCmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
4946 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4947 cb_state->status |= CBSTATUS_DEPTH_WRITE_ENABLE_SET;
4948 cb_state->static_status &= ~CBSTATUS_DEPTH_WRITE_ENABLE_SET;
4949}
4950
4951void ValidationStateTracker::PreCallRecordCmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
4952 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4953 cb_state->status |= CBSTATUS_DEPTH_COMPARE_OP_SET;
4954 cb_state->static_status &= ~CBSTATUS_DEPTH_COMPARE_OP_SET;
4955}
4956
4957void ValidationStateTracker::PreCallRecordCmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,
4958 VkBool32 depthBoundsTestEnable) {
4959 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4960 cb_state->status |= CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET;
4961 cb_state->static_status &= ~CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET;
4962}
4963void ValidationStateTracker::PreCallRecordCmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable) {
4964 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4965 cb_state->status |= CBSTATUS_STENCIL_TEST_ENABLE_SET;
4966 cb_state->static_status &= ~CBSTATUS_STENCIL_TEST_ENABLE_SET;
4967}
4968
4969void ValidationStateTracker::PreCallRecordCmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
4970 VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
4971 VkCompareOp compareOp) {
4972 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4973 cb_state->status |= CBSTATUS_STENCIL_OP_SET;
4974 cb_state->static_status &= ~CBSTATUS_STENCIL_OP_SET;
4975}
locke-lunarg4189aa22020-10-21 00:23:48 -06004976
4977void ValidationStateTracker::PreCallRecordCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle,
4978 uint32_t discardRectangleCount,
4979 const VkRect2D *pDiscardRectangles) {
4980 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4981 cb_state->status |= CBSTATUS_DISCARD_RECTANGLE_SET;
4982 cb_state->static_status &= ~CBSTATUS_DISCARD_RECTANGLE_SET;
4983}
4984
4985void ValidationStateTracker::PreCallRecordCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
4986 const VkSampleLocationsInfoEXT *pSampleLocationsInfo) {
4987 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4988 cb_state->status |= CBSTATUS_SAMPLE_LOCATIONS_SET;
4989 cb_state->static_status &= ~CBSTATUS_SAMPLE_LOCATIONS_SET;
4990}
4991
4992void ValidationStateTracker::PreCallRecordCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer,
4993 VkCoarseSampleOrderTypeNV sampleOrderType,
4994 uint32_t customSampleOrderCount,
4995 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) {
4996 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
4997 cb_state->status |= CBSTATUS_COARSE_SAMPLE_ORDER_SET;
4998 cb_state->static_status &= ~CBSTATUS_COARSE_SAMPLE_ORDER_SET;
4999}
Vikram Kushwahaa57b0c32021-04-19 12:21:46 -07005000
5001void ValidationStateTracker::PreCallRecordCmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, uint32_t patchControlPoints) {
5002 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
5003 cb_state->status |= CBSTATUS_PATCH_CONTROL_POINTS_SET;
5004 cb_state->static_status &= ~CBSTATUS_PATCH_CONTROL_POINTS_SET;
5005}
5006
5007void ValidationStateTracker::PreCallRecordCmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
5008 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
5009 cb_state->status |= CBSTATUS_LOGIC_OP_SET;
5010 cb_state->static_status &= ~CBSTATUS_LOGIC_OP_SET;
5011}
5012
5013void ValidationStateTracker::PreCallRecordCmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
5014 VkBool32 rasterizerDiscardEnable) {
5015 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
5016 cb_state->status |= CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET;
5017 cb_state->static_status &= ~CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET;
5018}
5019
5020void ValidationStateTracker::PreCallRecordCmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
5021 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
5022 cb_state->status |= CBSTATUS_DEPTH_BIAS_ENABLE_SET;
5023 cb_state->static_status &= ~CBSTATUS_DEPTH_BIAS_ENABLE_SET;
5024}
5025
5026void ValidationStateTracker::PreCallRecordCmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,
5027 VkBool32 primitiveRestartEnable) {
5028 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
5029 cb_state->status |= CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET;
5030 cb_state->static_status &= ~CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET;
David Zhao Akeley44139b12021-04-26 16:16:13 -07005031}
Piers Daniell924cd832021-05-18 13:48:47 -06005032
5033void ValidationStateTracker::PreCallRecordCmdSetVertexInputEXT(
5034 VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount,
5035 const VkVertexInputBindingDescription2EXT *pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount,
5036 const VkVertexInputAttributeDescription2EXT *pVertexAttributeDescriptions) {
5037 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
5038 cb_state->status |= CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET | CBSTATUS_VERTEX_INPUT_SET;
5039 cb_state->static_status &= ~(CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET | CBSTATUS_VERTEX_INPUT_SET);
5040}
Nathaniel Cesario42ac6ca2021-06-15 17:23:05 -06005041
5042void ValidationStateTracker::RecordGetBufferDeviceAddress(const VkBufferDeviceAddressInfo *pInfo, VkDeviceAddress address) {
5043 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
5044 if (buffer_state) {
5045 // address is used for GPU-AV and ray tracing buffer validation
5046 buffer_state->deviceAddress = address;
5047 buffer_address_map_.emplace(address, buffer_state);
5048 }
5049}
5050
5051void ValidationStateTracker::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
5052 VkDeviceAddress address) {
5053 RecordGetBufferDeviceAddress(pInfo, address);
5054}
5055
5056void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
5057 VkDeviceAddress address) {
5058 RecordGetBufferDeviceAddress(pInfo, address);
5059}
5060
5061void ValidationStateTracker::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
5062 VkDeviceAddress address) {
5063 RecordGetBufferDeviceAddress(pInfo, address);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06005064}
5065
5066std::shared_ptr<SWAPCHAIN_NODE> ValidationStateTracker::CreateSwapchainState(const VkSwapchainCreateInfoKHR *create_info,
5067 VkSwapchainKHR swapchain) {
Jeremy Gebben62c3bf42021-07-21 15:38:24 -06005068 return std::make_shared<SWAPCHAIN_NODE>(this, create_info, swapchain);
Nathaniel Cesario39152e62021-07-02 13:04:16 -06005069}