blob: 9c1be3fb6a91af501aa2be27beb334eb22a13566 [file] [log] [blame]
Dave Houlton4d9b2f82018-10-24 18:21:06 -06001/* Copyright (c) 2015-2018 The Khronos Group Inc.
2 * Copyright (c) 2015-2018 Valve Corporation
3 * Copyright (c) 2015-2018 LunarG, Inc.
4 * Copyright (C) 2015-2018 Google Inc.
Mark Lobodzinskid4950072017-08-01 13:02:20 -06005 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Mark Lobodzinski <mark@LunarG.com>
John Zulaufa999d1b2018-11-29 13:38:40 -070019 * Author: John Zulauf <jzulauf@lunarg.com>
Mark Lobodzinskid4950072017-08-01 13:02:20 -060020 */
21
22#define NOMINMAX
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070023#include "chassis.h"
24#include "stateless_validation.h"
Tobias Hectord942eb92018-10-22 15:18:56 +010025
Mark Lobodzinskid4950072017-08-01 13:02:20 -060026static const int MaxParamCheckerStringLength = 256;
27
John Zulauf71968502017-10-26 13:51:15 -060028template <typename T>
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070029inline bool in_inclusive_range(const T &value, const T &min, const T &max) {
John Zulauf71968502017-10-26 13:51:15 -060030 // Using only < for generality and || for early abort
31 return !((value < min) || (max < value));
32}
33
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070034bool StatelessValidation::validate_string(const char *apiName, const ParameterName &stringName,
Mark Lobodzinskiebee3552018-05-29 09:55:54 -060035 const std::string &vuid, const char *validateString) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -060036 bool skip = false;
37
38 VkStringErrorFlags result = vk_string_validate(MaxParamCheckerStringLength, validateString);
39
40 if (result == VK_STRING_ERROR_NONE) {
41 return skip;
42 } else if (result & VK_STRING_ERROR_LENGTH) {
Mark Lobodzinskiebee3552018-05-29 09:55:54 -060043 skip = log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
44 "%s: string %s exceeds max length %d", apiName, stringName.get_name().c_str(), MaxParamCheckerStringLength);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060045 } else if (result & VK_STRING_ERROR_BAD_DATA) {
Mark Lobodzinskiebee3552018-05-29 09:55:54 -060046 skip = log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
47 "%s: string %s contains invalid characters or is badly formed", apiName, stringName.get_name().c_str());
Mark Lobodzinskid4950072017-08-01 13:02:20 -060048 }
49 return skip;
50}
51
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070052bool StatelessValidation::ValidateDeviceQueueFamily(uint32_t queue_family, const char *cmd_name,
Dave Houlton13b65502018-05-23 13:35:24 -060053 const char *parameter_name, const std::string &error_code, bool optional = false) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -060054 bool skip = false;
55
Mark Lobodzinskid4950072017-08-01 13:02:20 -060056 if (!optional && queue_family == VK_QUEUE_FAMILY_IGNORED) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070057 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
58 HandleToUint64(device), error_code,
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060059 "%s: %s is VK_QUEUE_FAMILY_IGNORED, but it is required to provide a valid queue family index value.",
60 cmd_name, parameter_name);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070061 } else if (queueFamilyIndexMap.find(queue_family) == queueFamilyIndexMap.end()) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060062 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070063 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
64 HandleToUint64(device), error_code,
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060065 "%s: %s (= %" PRIu32
66 ") is not one of the queue families given via VkDeviceQueueCreateInfo structures when the device was created.",
67 cmd_name, parameter_name, queue_family);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060068 }
69
70 return skip;
71}
72
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070073bool StatelessValidation::ValidateQueueFamilies(uint32_t queue_family_count, const uint32_t *queue_families,
74 const char *cmd_name, const char *array_parameter_name, const std::string &unique_error_code,
75 const std::string &valid_error_code, bool optional = false) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -060076 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -060077 if (queue_families) {
78 std::unordered_set<uint32_t> set;
79 for (uint32_t i = 0; i < queue_family_count; ++i) {
80 std::string parameter_name = std::string(array_parameter_name) + "[" + std::to_string(i) + "]";
81
82 if (set.count(queue_families[i])) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070083 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
84 HandleToUint64(device), "VUID-VkDeviceCreateInfo-queueFamilyIndex-00372",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060085 "%s: %s (=%" PRIu32 ") is not unique within %s array.", cmd_name, parameter_name.c_str(),
86 queue_families[i], array_parameter_name);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060087 } else {
88 set.insert(queue_families[i]);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070089 skip |= ValidateDeviceQueueFamily(queue_families[i], cmd_name, parameter_name.c_str(),
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060090 valid_error_code, optional);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060091 }
92 }
93 }
94 return skip;
95}
96
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070097bool StatelessValidation::validate_api_version(uint32_t api_version, uint32_t effective_api_version) {
John Zulauf620755c2018-04-16 11:00:43 -060098 bool skip = false;
99 uint32_t api_version_nopatch = VK_MAKE_VERSION(VK_VERSION_MAJOR(api_version), VK_VERSION_MINOR(api_version), 0);
100 if (api_version_nopatch != effective_api_version) {
101 if (api_version_nopatch < VK_API_VERSION_1_0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700102 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
103 HandleToUint64(instance), kVUIDUndefined,
John Zulauf620755c2018-04-16 11:00:43 -0600104 "Invalid CreateInstance->pCreateInfo->pApplicationInfo.apiVersion number (0x%08x). "
105 "Using VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
106 api_version, VK_VERSION_MAJOR(effective_api_version), VK_VERSION_MINOR(effective_api_version));
107 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700108 skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
109 HandleToUint64(instance), kVUIDUndefined,
John Zulauf620755c2018-04-16 11:00:43 -0600110 "Unrecognized CreateInstance->pCreateInfo->pApplicationInfo.apiVersion number (0x%08x). "
111 "Assuming VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
112 api_version, VK_VERSION_MAJOR(effective_api_version), VK_VERSION_MINOR(effective_api_version));
113 }
114 }
115 return skip;
116}
117
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700118bool StatelessValidation::validate_instance_extensions(const VkInstanceCreateInfo *pCreateInfo) {
John Zulauf620755c2018-04-16 11:00:43 -0600119 bool skip = false;
120 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Dave Houlton413a6782018-05-22 13:01:54 -0600121 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700122 validate_extension_reqs(instance_extensions, "VUID-vkCreateInstance-ppEnabledExtensionNames-01388",
Dave Houlton413a6782018-05-22 13:01:54 -0600123 "instance", pCreateInfo->ppEnabledExtensionNames[i]);
John Zulauf620755c2018-04-16 11:00:43 -0600124 }
125
126 return skip;
127}
128
John Zulauf620755c2018-04-16 11:00:43 -0600129template <typename ExtensionState>
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700130bool extension_state_by_name(const ExtensionState &extensions, const char *extension_name) {
John Zulauf620755c2018-04-16 11:00:43 -0600131 if (!extension_name) return false; // null strings specify nothing
132 auto info = ExtensionState::get_info(extension_name);
133 bool state = info.state ? extensions.*(info.state) : false; // unknown extensions can't be enabled in extension struct
134 return state;
135}
136
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700137bool StatelessValidation::manual_PreCallValidateCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
138 VkInstance *pInstance) {
139 bool skip = false;
140 // Note: From the spec--
141 // Providing a NULL VkInstanceCreateInfo::pApplicationInfo or providing an apiVersion of 0 is equivalent to providing
142 // an apiVersion of VK_MAKE_VERSION(1, 0, 0). (a.k.a. VK_API_VERSION_1_0)
143 uint32_t local_api_version = (pCreateInfo->pApplicationInfo && pCreateInfo->pApplicationInfo->apiVersion)
144 ? pCreateInfo->pApplicationInfo->apiVersion
145 : VK_API_VERSION_1_0;
146 skip |= validate_api_version(local_api_version, api_version);
147 skip |= validate_instance_extensions(pCreateInfo);
148 return skip;
149}
150
151void StatelessValidation::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
152 VkInstance *pInstance) {
153 auto instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), layer_data_map);
154 // Copy extension data into local object
155 this->instance_extensions = instance_data->instance_extensions;
156}
157
158void StatelessValidation::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
159 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
160 auto device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
161 ValidationObject* validation_data = GetValidationObject(device_data->object_dispatch, LayerObjectTypeParameterValidation);
162 StatelessValidation *stateless_validation = static_cast<StatelessValidation*>(validation_data);
163
164 // Store queue family data
165 if ((pCreateInfo != nullptr) && (pCreateInfo->pQueueCreateInfos != nullptr)) {
166 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
167 stateless_validation->queueFamilyIndexMap.insert(std::make_pair(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex,
168 pCreateInfo->pQueueCreateInfos[i].queueCount));
169 }
170 }
171
172 // Parmeter validation also uses extension data
173 stateless_validation->device_extensions = this->device_extensions;
174
175 VkPhysicalDeviceProperties device_properties = {};
176 // Need to get instance and do a getlayerdata call...
177 ValidationObject *instance_object = GetLayerDataPtr(get_dispatch_key(physicalDevice), layer_data_map);
178 instance_object->instance_dispatch_table.GetPhysicalDeviceProperties(physicalDevice, &device_properties);
179 memcpy(&stateless_validation->device_limits, &device_properties.limits, sizeof(VkPhysicalDeviceLimits));
180
181 if (device_extensions.vk_nv_shading_rate_image) {
182 // Get the needed shading rate image limits
183 auto shading_rate_image_props = lvl_init_struct<VkPhysicalDeviceShadingRateImagePropertiesNV>();
184 auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&shading_rate_image_props);
185 instance_object->instance_dispatch_table.GetPhysicalDeviceProperties2KHR(physicalDevice, &prop2);
186 phys_dev_ext_props.shading_rate_image_props = shading_rate_image_props;
187 }
188
189 if (device_extensions.vk_nv_mesh_shader) {
190 // Get the needed mesh shader limits
191 auto mesh_shader_props = lvl_init_struct<VkPhysicalDeviceMeshShaderPropertiesNV>();
192 auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&mesh_shader_props);
193 instance_object->instance_dispatch_table.GetPhysicalDeviceProperties2KHR(physicalDevice, &prop2);
194 phys_dev_ext_props.mesh_shader_props = mesh_shader_props;
195 }
196
197 // Save app-enabled features in this device's validation object
198 // The enabled features can come from either pEnabledFeatures, or from the pNext chain
199 const VkPhysicalDeviceFeatures *enabled_features_found = pCreateInfo->pEnabledFeatures;
200 if ((nullptr == enabled_features_found) && device_extensions.vk_khr_get_physical_device_properties_2) {
201 const auto *features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2KHR>(pCreateInfo->pNext);
202 if (features2) {
203 enabled_features_found = &(features2->features);
204 }
205 }
206 if (enabled_features_found) {
207 stateless_validation->physical_device_features = *enabled_features_found;
208 } else {
209 memset(&stateless_validation->physical_device_features, 0, sizeof(VkPhysicalDeviceFeatures));
210 }
211}
212
213
214
215bool StatelessValidation::manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
216 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600217 bool skip = false;
John Zulauf620755c2018-04-16 11:00:43 -0600218 bool maint1 = false;
219 bool negative_viewport = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600220
221 if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) {
222 for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700223 skip |= validate_string("vkCreateDevice", "pCreateInfo->ppEnabledLayerNames",
Mark Lobodzinskiebee3552018-05-29 09:55:54 -0600224 "VUID-VkDeviceCreateInfo-ppEnabledLayerNames-parameter", pCreateInfo->ppEnabledLayerNames[i]);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600225 }
226 }
227
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600228 if ((pCreateInfo->enabledExtensionCount > 0) && (pCreateInfo->ppEnabledExtensionNames != NULL)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700229 maint1 = extension_state_by_name(device_extensions, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
230 negative_viewport = extension_state_by_name(device_extensions, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME);
John Zulauf620755c2018-04-16 11:00:43 -0600231
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600232 for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700233 skip |= validate_string("vkCreateDevice", "pCreateInfo->ppEnabledExtensionNames",
Mark Lobodzinskiebee3552018-05-29 09:55:54 -0600234 "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-parameter",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600235 pCreateInfo->ppEnabledExtensionNames[i]);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700236 skip |= validate_extension_reqs(device_extensions, "VUID-vkCreateDevice-ppEnabledExtensionNames-01387",
Dave Houlton413a6782018-05-22 13:01:54 -0600237 "device", pCreateInfo->ppEnabledExtensionNames[i]);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600238 }
239 }
240
241 if (maint1 && negative_viewport) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700242 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600243 "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-00374",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600244 "VkDeviceCreateInfo->ppEnabledExtensionNames must not simultaneously include VK_KHR_maintenance1 and "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600245 "VK_AMD_negative_viewport_height.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600246 }
247
248 if (pCreateInfo->pNext != NULL && pCreateInfo->pEnabledFeatures) {
249 // Check for get_physical_device_properties2 struct
John Zulaufde972ac2017-10-26 12:07:05 -0600250 const auto *features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2KHR>(pCreateInfo->pNext);
251 if (features2) {
252 // Cannot include VkPhysicalDeviceFeatures2KHR and have non-null pEnabledFeatures
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700253 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600254 kVUID_PVError_InvalidUsage,
John Zulaufde972ac2017-10-26 12:07:05 -0600255 "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2KHR struct when "
256 "pCreateInfo->pEnabledFeatures is non-NULL.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600257 }
258 }
259
260 // Validate pCreateInfo->pQueueCreateInfos
261 if (pCreateInfo->pQueueCreateInfos) {
262 std::unordered_set<uint32_t> set;
263
264 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
265 const uint32_t requested_queue_family = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
266 if (requested_queue_family == VK_QUEUE_FAMILY_IGNORED) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700267 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600268 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(physicalDevice),
Dave Houlton413a6782018-05-22 13:01:54 -0600269 "VUID-VkDeviceQueueCreateInfo-queueFamilyIndex-00381",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600270 "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -0700271 "].queueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, but it is required to provide a valid queue family "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600272 "index value.",
273 i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600274 } else if (set.count(requested_queue_family)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700275 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600276 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(physicalDevice),
Dave Houlton413a6782018-05-22 13:01:54 -0600277 "VUID-VkDeviceCreateInfo-queueFamilyIndex-00372",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600278 "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600279 ") is not unique within pCreateInfo->pQueueCreateInfos array.",
280 i, requested_queue_family);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600281 } else {
282 set.insert(requested_queue_family);
283 }
284
285 if (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities != nullptr) {
286 for (uint32_t j = 0; j < pCreateInfo->pQueueCreateInfos[i].queueCount; ++j) {
287 const float queue_priority = pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j];
288 if (!(queue_priority >= 0.f) || !(queue_priority <= 1.f)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700289 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600290 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(physicalDevice),
Dave Houlton413a6782018-05-22 13:01:54 -0600291 "VUID-VkDeviceQueueCreateInfo-pQueuePriorities-00383",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600292 "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].pQueuePriorities[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600293 "] (=%f) is not between 0 and 1 (inclusive).",
294 i, j, queue_priority);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600295 }
296 }
297 }
298 }
299 }
300
301 return skip;
302}
303
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700304bool StatelessValidation::require_device_extension(bool flag, char const *function_name, char const *extension_name) {
305 if (!flag) {
306 return log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
307 kVUID_PVError_ExtensionNotEnabled,
308 "%s() called even though the %s extension was not enabled for this VkDevice.", function_name,
309 extension_name);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600310 }
311
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700312 return false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600313}
314
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700315bool StatelessValidation::manual_PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600316 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600317
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700318 skip |= ValidateDeviceQueueFamily(queueFamilyIndex, "vkGetDeviceQueue", "queueFamilyIndex",
Dave Houlton413a6782018-05-22 13:01:54 -0600319 "VUID-vkGetDeviceQueue-queueFamilyIndex-00384");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700320 const auto &queue_data = queueFamilyIndexMap.find(queueFamilyIndex);
321 if (queue_data != queueFamilyIndexMap.end() && queue_data->second <= queueIndex) {
322 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -0600323 HandleToUint64(device), "VUID-vkGetDeviceQueue-queueIndex-00385",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600324 "vkGetDeviceQueue: queueIndex (=%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -0700325 ") is not less than the number of queues requested from queueFamilyIndex (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600326 ") when the device was created (i.e. is not less than %" PRIu32 ").",
327 queueIndex, queueFamilyIndex, queue_data->second);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600328 }
329 return skip;
330}
331
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700332bool StatelessValidation::manual_PreCallValidateCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
333 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
Petr Krause91f7a12017-12-14 20:57:36 +0100334 bool skip = false;
335
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700336 const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, VK_NULL_HANDLE, "vkCreateBuffer"};
Petr Krause5c37652018-01-05 04:05:12 +0100337
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600338 if (pCreateInfo != nullptr) {
Dave Houlton413a6782018-05-22 13:01:54 -0600339 skip |= ValidateGreaterThanZero(pCreateInfo->size, "pCreateInfo->size", "VUID-VkBufferCreateInfo-size-00912", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600340
341 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
342 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
343 // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
344 if (pCreateInfo->queueFamilyIndexCount <= 1) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600345 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600346 "VUID-VkBufferCreateInfo-sharingMode-00914",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600347 "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600348 "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600349 }
350
351 // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
352 // queueFamilyIndexCount uint32_t values
353 if (pCreateInfo->pQueueFamilyIndices == nullptr) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600354 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600355 "VUID-VkBufferCreateInfo-sharingMode-00913",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600356 "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
357 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600358 "pCreateInfo->queueFamilyIndexCount uint32_t values.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600359 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700360 skip |= ValidateQueueFamilies(pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices,
Dave Houlton413a6782018-05-22 13:01:54 -0600361 "vkCreateBuffer", "pCreateInfo->pQueueFamilyIndices", kVUID_PVError_InvalidUsage,
362 kVUID_PVError_InvalidUsage, false);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600363 }
364 }
365
366 // If flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain
367 // VK_BUFFER_CREATE_SPARSE_BINDING_BIT
368 if (((pCreateInfo->flags & (VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
369 ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600370 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600371 "VUID-VkBufferCreateInfo-flags-00918",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600372 "vkCreateBuffer: if pCreateInfo->flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600373 "VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600374 }
375 }
376
377 return skip;
378}
379
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700380bool StatelessValidation::manual_PreCallValidateCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
381 const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600382 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600383
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700384 const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE, "vkCreateImage"};
Petr Krause5c37652018-01-05 04:05:12 +0100385
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600386 if (pCreateInfo != nullptr) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600387 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
388 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
389 // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
390 if (pCreateInfo->queueFamilyIndexCount <= 1) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600391 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600392 "VUID-VkImageCreateInfo-sharingMode-00942",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600393 "vkCreateImage(): if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600394 "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600395 }
396
397 // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
398 // queueFamilyIndexCount uint32_t values
399 if (pCreateInfo->pQueueFamilyIndices == nullptr) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600400 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600401 "VUID-VkImageCreateInfo-sharingMode-00941",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600402 "vkCreateImage(): if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
403 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600404 "pCreateInfo->queueFamilyIndexCount uint32_t values.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600405 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700406 skip |= ValidateQueueFamilies(pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices,
Dave Houlton413a6782018-05-22 13:01:54 -0600407 "vkCreateImage", "pCreateInfo->pQueueFamilyIndices", kVUID_PVError_InvalidUsage,
408 kVUID_PVError_InvalidUsage, false);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600409 }
410 }
411
Dave Houlton413a6782018-05-22 13:01:54 -0600412 skip |= ValidateGreaterThanZero(pCreateInfo->extent.width, "pCreateInfo->extent.width",
413 "VUID-VkImageCreateInfo-extent-00944", log_misc);
414 skip |= ValidateGreaterThanZero(pCreateInfo->extent.height, "pCreateInfo->extent.height",
415 "VUID-VkImageCreateInfo-extent-00945", log_misc);
416 skip |= ValidateGreaterThanZero(pCreateInfo->extent.depth, "pCreateInfo->extent.depth",
417 "VUID-VkImageCreateInfo-extent-00946", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600418
Dave Houlton413a6782018-05-22 13:01:54 -0600419 skip |= ValidateGreaterThanZero(pCreateInfo->mipLevels, "pCreateInfo->mipLevels", "VUID-VkImageCreateInfo-mipLevels-00947",
420 log_misc);
421 skip |= ValidateGreaterThanZero(pCreateInfo->arrayLayers, "pCreateInfo->arrayLayers",
422 "VUID-VkImageCreateInfo-arrayLayers-00948", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600423
Dave Houlton130c0212018-01-29 13:39:56 -0700424 // InitialLayout must be PREINITIALIZED or UNDEFINED
Dave Houltone19e20d2018-02-02 16:32:41 -0700425 if ((pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED) &&
426 (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED)) {
427 skip |= log_msg(
Dave Houlton413a6782018-05-22 13:01:54 -0600428 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
429 "VUID-VkImageCreateInfo-initialLayout-00993",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600430 "vkCreateImage(): initialLayout is %s, must be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED.",
431 string_VkImageLayout(pCreateInfo->initialLayout));
Dave Houlton130c0212018-01-29 13:39:56 -0700432 }
433
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600434 // If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1
Petr Kraus3ac9e812018-03-13 12:31:08 +0100435 if ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) &&
436 ((pCreateInfo->extent.height != 1) || (pCreateInfo->extent.depth != 1))) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600437 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600438 "VUID-VkImageCreateInfo-imageType-00956",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700439 "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_1D, both pCreateInfo->extent.height and "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600440 "pCreateInfo->extent.depth must be 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600441 }
442
443 if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D) {
Petr Kraus3f433212018-03-13 12:31:27 +0100444 if (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) {
445 if (pCreateInfo->extent.width != pCreateInfo->extent.height) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600446 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -0600447 VK_NULL_HANDLE, "VUID-VkImageCreateInfo-imageType-00954",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600448 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, but "
449 "pCreateInfo->extent.width (=%" PRIu32 ") and pCreateInfo->extent.height (=%" PRIu32
450 ") are not equal.",
451 pCreateInfo->extent.width, pCreateInfo->extent.height);
Petr Kraus3f433212018-03-13 12:31:27 +0100452 }
453
454 if (pCreateInfo->arrayLayers < 6) {
455 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -0600456 VK_NULL_HANDLE, "VUID-VkImageCreateInfo-imageType-00954",
Petr Kraus3f433212018-03-13 12:31:27 +0100457 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, but "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600458 "pCreateInfo->arrayLayers (=%" PRIu32 ") is not greater than or equal to 6.",
459 pCreateInfo->arrayLayers);
Petr Kraus3f433212018-03-13 12:31:27 +0100460 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600461 }
462
463 if (pCreateInfo->extent.depth != 1) {
Mark Lobodzinski88529492018-04-01 10:38:15 -0600464 skip |=
465 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600466 "VUID-VkImageCreateInfo-imageType-00957",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600467 "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_2D, pCreateInfo->extent.depth must be 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600468 }
469 }
470
Dave Houlton130c0212018-01-29 13:39:56 -0700471 // 3D image may have only 1 layer
472 if ((pCreateInfo->imageType == VK_IMAGE_TYPE_3D) && (pCreateInfo->arrayLayers != 1)) {
Mark Lobodzinski88529492018-04-01 10:38:15 -0600473 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600474 "VUID-VkImageCreateInfo-imageType-00961",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600475 "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_3D, pCreateInfo->arrayLayers must be 1.");
Dave Houlton130c0212018-01-29 13:39:56 -0700476 }
477
478 // If multi-sample, validate type, usage, tiling and mip levels.
479 if ((pCreateInfo->samples != VK_SAMPLE_COUNT_1_BIT) &&
480 ((pCreateInfo->imageType != VK_IMAGE_TYPE_2D) || (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ||
Shannon McPhersona886c2a2018-10-12 14:38:20 -0600481 (pCreateInfo->mipLevels != 1) || (pCreateInfo->tiling != VK_IMAGE_TILING_OPTIMAL))) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600482 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Shannon McPhersona886c2a2018-10-12 14:38:20 -0600483 "VUID-VkImageCreateInfo-samples-02257",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600484 "vkCreateImage(): Multi-sample image with incompatible type, usage, tiling, or mips.");
Dave Houlton130c0212018-01-29 13:39:56 -0700485 }
486
487 if (0 != (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
488 VkImageUsageFlags legal_flags = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
489 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
490 // At least one of the legal attachment bits must be set
491 if (0 == (pCreateInfo->usage & legal_flags)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600492 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600493 "VUID-VkImageCreateInfo-usage-00966",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600494 "vkCreateImage(): Transient attachment image without a compatible attachment flag set.");
Dave Houlton130c0212018-01-29 13:39:56 -0700495 }
496 // No flags other than the legal attachment bits may be set
497 legal_flags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
498 if (0 != (pCreateInfo->usage & ~legal_flags)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600499 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600500 "VUID-VkImageCreateInfo-usage-00963",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600501 "vkCreateImage(): Transient attachment image with incompatible usage flags set.");
Dave Houlton130c0212018-01-29 13:39:56 -0700502 }
503 }
504
Jeff Bolzef40fec2018-09-01 22:04:34 -0500505 // mipLevels must be less than or equal to the number of levels in the complete mipmap chain
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600506 uint32_t maxDim = std::max(std::max(pCreateInfo->extent.width, pCreateInfo->extent.height), pCreateInfo->extent.depth);
Jeff Bolzef40fec2018-09-01 22:04:34 -0500507 // Max mip levels is different for corner-sampled images vs normal images.
Dave Houlton142c4cb2018-10-17 15:04:41 -0600508 uint32_t maxMipLevels = (pCreateInfo->flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) ? (uint32_t)(ceil(log2(maxDim)))
509 : (uint32_t)(floor(log2(maxDim)) + 1);
Jeff Bolzef40fec2018-09-01 22:04:34 -0500510 if (maxDim > 0 && pCreateInfo->mipLevels > maxMipLevels) {
Dave Houlton413a6782018-05-22 13:01:54 -0600511 skip |=
512 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
513 "VUID-VkImageCreateInfo-mipLevels-00958",
514 "vkCreateImage(): pCreateInfo->mipLevels must be less than or equal to "
515 "floor(log2(max(pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth)))+1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600516 }
517
Mark Lobodzinski69259c52018-09-18 15:14:58 -0600518 if ((pCreateInfo->flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT) && (pCreateInfo->imageType != VK_IMAGE_TYPE_3D)) {
519 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE,
520 "VUID-VkImageCreateInfo-flags-00950",
521 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT but "
522 "pCreateInfo->imageType is not VK_IMAGE_TYPE_3D.");
523 }
524
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700525 if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && (!physical_device_features.sparseBinding)) {
Petr Krausb6f97802018-03-13 12:31:39 +0100526 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE,
Dave Houlton413a6782018-05-22 13:01:54 -0600527 "VUID-VkImageCreateInfo-flags-00969",
Petr Krausb6f97802018-03-13 12:31:39 +0100528 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_BINDING_BIT, but the "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600529 "VkPhysicalDeviceFeatures::sparseBinding feature is disabled.");
Petr Krausb6f97802018-03-13 12:31:39 +0100530 }
531
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600532 // If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain
533 // VK_IMAGE_CREATE_SPARSE_BINDING_BIT
534 if (((pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
535 ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600536 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600537 "VUID-VkImageCreateInfo-flags-00987",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600538 "vkCreateImage: if pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600539 "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600540 }
541
542 // Check for combinations of attributes that are incompatible with having VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set
543 if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) {
544 // Linear tiling is unsupported
545 if (VK_IMAGE_TILING_LINEAR == pCreateInfo->tiling) {
Dave Houlton413a6782018-05-22 13:01:54 -0600546 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
547 kVUID_PVError_InvalidUsage,
548 "vkCreateImage: if pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then image "
549 "tiling of VK_IMAGE_TILING_LINEAR is not supported");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600550 }
551
552 // Sparse 1D image isn't valid
553 if (VK_IMAGE_TYPE_1D == pCreateInfo->imageType) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600554 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600555 "VUID-VkImageCreateInfo-imageType-00970",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600556 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 1D image.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600557 }
558
559 // Sparse 2D image when device doesn't support it
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700560 if ((VK_FALSE == physical_device_features.sparseResidencyImage2D) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600561 (VK_IMAGE_TYPE_2D == pCreateInfo->imageType)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600562 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600563 "VUID-VkImageCreateInfo-imageType-00971",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600564 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 2D image if corresponding "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600565 "feature is not enabled on the device.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600566 }
567
568 // Sparse 3D image when device doesn't support it
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700569 if ((VK_FALSE == physical_device_features.sparseResidencyImage3D) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600570 (VK_IMAGE_TYPE_3D == pCreateInfo->imageType)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600571 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600572 "VUID-VkImageCreateInfo-imageType-00972",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600573 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 3D image if corresponding "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600574 "feature is not enabled on the device.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600575 }
576
577 // Multi-sample 2D image when device doesn't support it
578 if (VK_IMAGE_TYPE_2D == pCreateInfo->imageType) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700579 if ((VK_FALSE == physical_device_features.sparseResidency2Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600580 (VK_SAMPLE_COUNT_2_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700581 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600582 "VUID-VkImageCreateInfo-imageType-00973",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700583 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 2-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600584 "corresponding feature is not enabled on the device.");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700585 } else if ((VK_FALSE == physical_device_features.sparseResidency4Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600586 (VK_SAMPLE_COUNT_4_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700587 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600588 "VUID-VkImageCreateInfo-imageType-00974",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700589 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 4-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600590 "corresponding feature is not enabled on the device.");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700591 } else if ((VK_FALSE == physical_device_features.sparseResidency8Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600592 (VK_SAMPLE_COUNT_8_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700593 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600594 "VUID-VkImageCreateInfo-imageType-00975",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700595 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 8-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600596 "corresponding feature is not enabled on the device.");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700597 } else if ((VK_FALSE == physical_device_features.sparseResidency16Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600598 (VK_SAMPLE_COUNT_16_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700599 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600600 "VUID-VkImageCreateInfo-imageType-00976",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700601 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 16-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600602 "corresponding feature is not enabled on the device.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600603 }
604 }
605 }
Jeff Bolzef40fec2018-09-01 22:04:34 -0500606
Jeff Bolz9af91c52018-09-01 21:53:57 -0500607 if (pCreateInfo->usage & VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV) {
608 if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D) {
609 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
610 "VUID-VkImageCreateInfo-imageType-02082",
611 "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
612 "imageType must be VK_IMAGE_TYPE_2D.");
613 }
614 if (pCreateInfo->samples != VK_SAMPLE_COUNT_1_BIT) {
615 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
616 "VUID-VkImageCreateInfo-samples-02083",
617 "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
618 "samples must be VK_SAMPLE_COUNT_1_BIT.");
619 }
620 if (pCreateInfo->tiling != VK_IMAGE_TILING_OPTIMAL) {
621 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
622 "VUID-VkImageCreateInfo-tiling-02084",
623 "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
624 "tiling must be VK_IMAGE_TILING_OPTIMAL.");
625 }
626 }
Jeff Bolzef40fec2018-09-01 22:04:34 -0500627
628 if (pCreateInfo->flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) {
Dave Houlton142c4cb2018-10-17 15:04:41 -0600629 if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D && pCreateInfo->imageType != VK_IMAGE_TYPE_3D) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500630 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
631 "VUID-VkImageCreateInfo-flags-02050",
632 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV, "
633 "imageType must be VK_IMAGE_TYPE_2D or VK_IMAGE_TYPE_3D.");
634 }
635
Dave Houlton142c4cb2018-10-17 15:04:41 -0600636 if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || FormatIsDepthOrStencil(pCreateInfo->format)) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500637 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
638 "VUID-VkImageCreateInfo-flags-02051",
639 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV, "
640 "it must not also contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT and format must "
641 "not be a depth/stencil format.");
642 }
643
Dave Houlton142c4cb2018-10-17 15:04:41 -0600644 if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D && (pCreateInfo->extent.width == 1 || pCreateInfo->extent.height == 1)) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500645 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
646 "VUID-VkImageCreateInfo-flags-02052",
647 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and "
648 "imageType is VK_IMAGE_TYPE_2D, extent.width and extent.height must be "
649 "greater than 1.");
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500650 } else if (pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
Dave Houlton142c4cb2018-10-17 15:04:41 -0600651 (pCreateInfo->extent.width == 1 || pCreateInfo->extent.height == 1 || pCreateInfo->extent.depth == 1)) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500652 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
653 "VUID-VkImageCreateInfo-flags-02053",
654 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and "
655 "imageType is VK_IMAGE_TYPE_3D, extent.width, extent.height, and extent.depth "
656 "must be greater than 1.");
Jeff Bolzef40fec2018-09-01 22:04:34 -0500657 }
658 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600659 }
Jeff Bolzef40fec2018-09-01 22:04:34 -0500660
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600661 return skip;
662}
663
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700664bool StatelessValidation::manual_PreCallValidateCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
665 const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600666 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600667
668 if (pCreateInfo != nullptr) {
Dave Houltonbd2e2622018-04-10 16:41:14 -0600669 // Validate chained VkImageViewUsageCreateInfo struct, if present
670 if (nullptr != pCreateInfo->pNext) {
671 auto chained_ivuci_struct = lvl_find_in_chain<VkImageViewUsageCreateInfoKHR>(pCreateInfo->pNext);
672 if (chained_ivuci_struct) {
673 if (0 == chained_ivuci_struct->usage) {
674 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600675 "VUID-VkImageViewUsageCreateInfo-usage-requiredbitmask",
Dave Houlton0f3795b2018-04-13 15:04:35 -0600676 "vkCreateImageView: Chained VkImageViewUsageCreateInfo usage field must not be 0.");
Dave Houltonbd2e2622018-04-10 16:41:14 -0600677 } else if (chained_ivuci_struct->usage & ~AllVkImageUsageFlagBits) {
678 std::stringstream ss;
679 ss << "vkCreateImageView: Chained VkImageViewUsageCreateInfo usage field (0x" << std::hex
680 << chained_ivuci_struct->usage << ") contains invalid flag bits.";
681 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -0600682 "VUID-VkImageViewUsageCreateInfo-usage-parameter", "%s", ss.str().c_str());
Dave Houltonbd2e2622018-04-10 16:41:14 -0600683 }
684 }
685 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600686 }
687 return skip;
688}
689
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700690bool StatelessValidation::manual_PreCallValidateViewport(const VkViewport &viewport, const char *fn_name,
691 const char *param_name, VkDebugReportObjectTypeEXT object_type, uint64_t object = 0) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100692 bool skip = false;
Petr Krausb3fcdb42018-01-09 22:09:09 +0100693
694 // Note: for numerical correctness
695 // - float comparisons should expect NaN (comparison always false).
696 // - VkPhysicalDeviceLimits::maxViewportDimensions is uint32_t, not float -> careful.
697
698 const auto f_lte_u32_exact = [](const float v1_f, const uint32_t v2_u32) {
John Zulaufac0876c2018-02-19 10:09:35 -0700699 if (std::isnan(v1_f)) return false;
Petr Krausb3fcdb42018-01-09 22:09:09 +0100700 if (v1_f <= 0.0f) return true;
701
702 float intpart;
703 const float fract = modff(v1_f, &intpart);
704
705 assert(std::numeric_limits<float>::radix == 2);
706 const float u32_max_plus1 = ldexpf(1.0f, 32); // hopefully exact
707 if (intpart >= u32_max_plus1) return false;
708
709 uint32_t v1_u32 = static_cast<uint32_t>(intpart);
710 if (v1_u32 < v2_u32)
711 return true;
712 else if (v1_u32 == v2_u32 && fract == 0.0f)
713 return true;
714 else
715 return false;
716 };
717
718 const auto f_lte_u32_direct = [](const float v1_f, const uint32_t v2_u32) {
719 const float v2_f = static_cast<float>(v2_u32); // not accurate for > radix^digits; and undefined rounding mode
720 return (v1_f <= v2_f);
721 };
722
723 // width
724 bool width_healthy = true;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700725 const auto max_w = device_limits.maxViewportDimensions[0];
Petr Krausb3fcdb42018-01-09 22:09:09 +0100726
727 if (!(viewport.width > 0.0f)) {
728 width_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600729 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-width-01770",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600730 "%s: %s.width (=%f) is not greater than 0.0.", fn_name, param_name, viewport.width);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100731 } else if (!(f_lte_u32_exact(viewport.width, max_w) || f_lte_u32_direct(viewport.width, max_w))) {
732 width_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600733 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-width-01771",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600734 "%s: %s.width (=%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[0] (=%" PRIu32 ").", fn_name,
735 param_name, viewport.width, max_w);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100736 } else if (!f_lte_u32_exact(viewport.width, max_w) && f_lte_u32_direct(viewport.width, max_w)) {
Dave Houlton413a6782018-05-22 13:01:54 -0600737 skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, object_type, object, kVUID_PVError_NONE,
Petr Krausb3fcdb42018-01-09 22:09:09 +0100738 "%s: %s.width (=%f) technically exceeds VkPhysicalDeviceLimits::maxViewportDimensions[0] (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600739 "), but it is within the static_cast<float>(maxViewportDimensions[0]) limit.",
740 fn_name, param_name, viewport.width, max_w);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100741 }
742
743 // height
744 bool height_healthy = true;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700745 const bool negative_height_enabled = api_version >= VK_API_VERSION_1_1 ||
746 device_extensions.vk_khr_maintenance1 ||
747 device_extensions.vk_amd_negative_viewport_height;
748 const auto max_h = device_limits.maxViewportDimensions[1];
Petr Krausb3fcdb42018-01-09 22:09:09 +0100749
750 if (!negative_height_enabled && !(viewport.height > 0.0f)) {
751 height_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600752 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-height-01772",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600753 "%s: %s.height (=%f) is not greater 0.0.", fn_name, param_name, viewport.height);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100754 } else if (!(f_lte_u32_exact(fabsf(viewport.height), max_h) || f_lte_u32_direct(fabsf(viewport.height), max_h))) {
755 height_healthy = false;
756
Dave Houlton413a6782018-05-22 13:01:54 -0600757 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-height-01773",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600758 "%s: Absolute value of %s.height (=%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[1] (=%" PRIu32
759 ").",
760 fn_name, param_name, viewport.height, max_h);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100761 } else if (!f_lte_u32_exact(fabsf(viewport.height), max_h) && f_lte_u32_direct(fabsf(viewport.height), max_h)) {
762 height_healthy = false;
763
764 skip |= log_msg(
Dave Houlton413a6782018-05-22 13:01:54 -0600765 report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, object_type, object, kVUID_PVError_NONE,
Petr Krausb3fcdb42018-01-09 22:09:09 +0100766 "%s: Absolute value of %s.height (=%f) technically exceeds VkPhysicalDeviceLimits::maxViewportDimensions[1] (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600767 "), but it is within the static_cast<float>(maxViewportDimensions[1]) limit.",
768 fn_name, param_name, viewport.height, max_h);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100769 }
770
771 // x
772 bool x_healthy = true;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700773 if (!(viewport.x >= device_limits.viewportBoundsRange[0])) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100774 x_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600775 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-x-01774",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600776 "%s: %s.x (=%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name, param_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700777 viewport.x, device_limits.viewportBoundsRange[0]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100778 }
779
780 // x + width
781 if (x_healthy && width_healthy) {
782 const float right_bound = viewport.x + viewport.width;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700783 if (!(right_bound <= device_limits.viewportBoundsRange[1])) {
Mark Lobodzinski88529492018-04-01 10:38:15 -0600784 skip |=
Dave Houlton413a6782018-05-22 13:01:54 -0600785 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-x-01232",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600786 "%s: %s.x + %s.width (=%f + %f = %f) is greater than VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).",
787 fn_name, param_name, param_name, viewport.x, viewport.width, right_bound,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700788 device_limits.viewportBoundsRange[1]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100789 }
790 }
791
792 // y
793 bool y_healthy = true;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700794 if (!(viewport.y >= device_limits.viewportBoundsRange[0])) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100795 y_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600796 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01775",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600797 "%s: %s.y (=%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name, param_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700798 viewport.y, device_limits.viewportBoundsRange[0]);
799 } else if (negative_height_enabled && !(viewport.y <= device_limits.viewportBoundsRange[1])) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100800 y_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600801 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01776",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600802 "%s: %s.y (=%f) exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).", fn_name, param_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700803 viewport.y, device_limits.viewportBoundsRange[1]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100804 }
805
806 // y + height
807 if (y_healthy && height_healthy) {
808 const float boundary = viewport.y + viewport.height;
809
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700810 if (!(boundary <= device_limits.viewportBoundsRange[1])) {
Dave Houlton413a6782018-05-22 13:01:54 -0600811 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01233",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600812 "%s: %s.y + %s.height (=%f + %f = %f) exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).",
813 fn_name, param_name, param_name, viewport.y, viewport.height, boundary,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700814 device_limits.viewportBoundsRange[1]);
815 } else if (negative_height_enabled && !(boundary >= device_limits.viewportBoundsRange[0])) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100816 skip |= log_msg(
Dave Houlton413a6782018-05-22 13:01:54 -0600817 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01777",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600818 "%s: %s.y + %s.height (=%f + %f = %f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700819 param_name, param_name, viewport.y, viewport.height, boundary, device_limits.viewportBoundsRange[0]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100820 }
821 }
822
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700823 if (!device_extensions.vk_ext_depth_range_unrestricted) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100824 // minDepth
825 if (!(viewport.minDepth >= 0.0) || !(viewport.minDepth <= 1.0)) {
Dave Houlton413a6782018-05-22 13:01:54 -0600826 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-minDepth-01234",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600827
Petr Krausb3fcdb42018-01-09 22:09:09 +0100828 "%s: VK_EXT_depth_range_unrestricted extension is not enabled and %s.minDepth (=%f) is not within the "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600829 "[0.0, 1.0] range.",
830 fn_name, param_name, viewport.minDepth);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100831 }
832
833 // maxDepth
834 if (!(viewport.maxDepth >= 0.0) || !(viewport.maxDepth <= 1.0)) {
Dave Houlton413a6782018-05-22 13:01:54 -0600835 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-maxDepth-01235",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600836
Petr Krausb3fcdb42018-01-09 22:09:09 +0100837 "%s: VK_EXT_depth_range_unrestricted extension is not enabled and %s.maxDepth (=%f) is not within the "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600838 "[0.0, 1.0] range.",
839 fn_name, param_name, viewport.maxDepth);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100840 }
841 }
842
843 return skip;
844}
845
Dave Houlton142c4cb2018-10-17 15:04:41 -0600846struct SampleOrderInfo {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500847 VkShadingRatePaletteEntryNV shadingRate;
848 uint32_t width;
849 uint32_t height;
850};
851
852// All palette entries with more than one pixel per fragment
Dave Houlton142c4cb2018-10-17 15:04:41 -0600853static SampleOrderInfo sampleOrderInfos[] = {
854 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 1, 2},
855 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV, 2, 1},
856 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV, 2, 2},
857 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV, 4, 2},
858 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV, 2, 4},
859 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 4},
Jeff Bolz9af91c52018-09-01 21:53:57 -0500860};
861
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700862bool StatelessValidation::ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV *order) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500863 bool skip = false;
Jeff Bolz9af91c52018-09-01 21:53:57 -0500864
Jeff Bolz45bf7d62018-09-18 15:39:58 -0500865 SampleOrderInfo *sampleOrderInfo;
Jeff Bolz9af91c52018-09-01 21:53:57 -0500866 uint32_t infoIdx = 0;
Jeff Bolz45bf7d62018-09-18 15:39:58 -0500867 for (sampleOrderInfo = nullptr; infoIdx < ARRAY_SIZE(sampleOrderInfos); ++infoIdx) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500868 if (sampleOrderInfos[infoIdx].shadingRate == order->shadingRate) {
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500869 sampleOrderInfo = &sampleOrderInfos[infoIdx];
Jeff Bolz9af91c52018-09-01 21:53:57 -0500870 break;
871 }
872 }
873
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500874 if (sampleOrderInfo == nullptr) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500875 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
876 "VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073",
877 "VkCoarseSampleOrderCustomNV shadingRate must be a shading rate "
878 "that generates fragments with more than one pixel.");
879 return skip;
880 }
881
Dave Houlton142c4cb2018-10-17 15:04:41 -0600882 if (order->sampleCount == 0 || (order->sampleCount & (order->sampleCount - 1)) ||
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700883 !(order->sampleCount & device_limits.framebufferNoAttachmentsSampleCounts)) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500884 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
885 "VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074",
Dave Houlton142c4cb2018-10-17 15:04:41 -0600886 "VkCoarseSampleOrderCustomNV sampleCount (=%" PRIu32
887 ") must "
Jeff Bolz9af91c52018-09-01 21:53:57 -0500888 "correspond to a sample count enumerated in VkSampleCountFlags whose corresponding bit "
889 "is set in framebufferNoAttachmentsSampleCounts.",
890 order->sampleCount);
891 }
892
Jeff Bolz9af91c52018-09-01 21:53:57 -0500893 if (order->sampleLocationCount != order->sampleCount * sampleOrderInfo->width * sampleOrderInfo->height) {
894 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
895 "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075",
Dave Houlton142c4cb2018-10-17 15:04:41 -0600896 "VkCoarseSampleOrderCustomNV sampleLocationCount (=%" PRIu32
897 ") must "
898 "be equal to the product of sampleCount (=%" PRIu32
899 "), the fragment width for shadingRate "
Jeff Bolz9af91c52018-09-01 21:53:57 -0500900 "(=%" PRIu32 "), and the fragment height for shadingRate (=%" PRIu32 ").",
901 order->sampleLocationCount, order->sampleCount, sampleOrderInfo->width, sampleOrderInfo->height);
902 }
903
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700904 if (order->sampleLocationCount > phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples) {
Dave Houlton142c4cb2018-10-17 15:04:41 -0600905 skip |= log_msg(
906 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
907 "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076",
908 "VkCoarseSampleOrderCustomNV sampleLocationCount (=%" PRIu32
909 ") must "
910 "be less than or equal to VkPhysicalDeviceShadingRateImagePropertiesNV shadingRateMaxCoarseSamples (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700911 order->sampleLocationCount, phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples);
Jeff Bolz9af91c52018-09-01 21:53:57 -0500912 }
Jeff Bolz9af91c52018-09-01 21:53:57 -0500913
914 // Accumulate a bitmask tracking which (x,y,sample) tuples are seen. Expect
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500915 // the first width*height*sampleCount bits to all be set. Note: There is no
916 // guarantee that 64 bits is enough, but practically it's unlikely for an
917 // implementation to support more than 32 bits for samplemask.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700918 assert(phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples <= 64);
Jeff Bolz9af91c52018-09-01 21:53:57 -0500919 uint64_t sampleLocationsMask = 0;
920 for (uint32_t i = 0; i < order->sampleLocationCount; ++i) {
921 const VkCoarseSampleLocationNV *sampleLoc = &order->pSampleLocations[i];
922 if (sampleLoc->pixelX >= sampleOrderInfo->width) {
923 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
924 "VUID-VkCoarseSampleLocationNV-pixelX-02078",
925 "pixelX must be less than the width (in pixels) of the fragment.");
926 }
927 if (sampleLoc->pixelY >= sampleOrderInfo->height) {
928 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
929 "VUID-VkCoarseSampleLocationNV-pixelY-02079",
930 "pixelY must be less than the height (in pixels) of the fragment.");
931 }
932 if (sampleLoc->sample >= order->sampleCount) {
933 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
934 "VUID-VkCoarseSampleLocationNV-sample-02080",
935 "sample must be less than the number of coverage samples in each pixel belonging to the fragment.");
936 }
937 uint32_t idx = sampleLoc->sample + order->sampleCount * (sampleLoc->pixelX + sampleOrderInfo->width * sampleLoc->pixelY);
938 sampleLocationsMask |= 1ULL << idx;
939 }
940
941 uint64_t expectedMask = (order->sampleLocationCount == 64) ? ~0ULL : ((1ULL << order->sampleLocationCount) - 1);
942 if (sampleLocationsMask != expectedMask) {
Dave Houlton142c4cb2018-10-17 15:04:41 -0600943 skip |= log_msg(
944 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
945 "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077",
946 "The array pSampleLocations must contain exactly one entry for "
947 "every combination of valid values for pixelX, pixelY, and sample in the structure VkCoarseSampleOrderCustomNV.");
Jeff Bolz9af91c52018-09-01 21:53:57 -0500948 }
949
950 return skip;
951}
952
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700953bool StatelessValidation::manual_PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
954 const VkGraphicsPipelineCreateInfo *pCreateInfos,
955 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600956 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600957
958 if (pCreateInfos != nullptr) {
959 for (uint32_t i = 0; i < createInfoCount; ++i) {
Petr Kraus299ba622017-11-24 03:09:03 +0100960 bool has_dynamic_viewport = false;
961 bool has_dynamic_scissor = false;
962 bool has_dynamic_line_width = false;
Jeremy Kniager71fd5f02017-11-15 13:27:03 -0700963 bool has_dynamic_viewport_w_scaling_nv = false;
964 bool has_dynamic_discard_rectangle_ext = false;
965 bool has_dynamic_sample_locations_ext = false;
Jeff Bolz3e71f782018-08-29 23:15:45 -0500966 bool has_dynamic_exclusive_scissor_nv = false;
Jeff Bolz9af91c52018-09-01 21:53:57 -0500967 bool has_dynamic_shading_rate_palette_nv = false;
Petr Kraus299ba622017-11-24 03:09:03 +0100968 if (pCreateInfos[i].pDynamicState != nullptr) {
969 const auto &dynamic_state_info = *pCreateInfos[i].pDynamicState;
970 for (uint32_t state_index = 0; state_index < dynamic_state_info.dynamicStateCount; ++state_index) {
971 const auto &dynamic_state = dynamic_state_info.pDynamicStates[state_index];
972 if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT) has_dynamic_viewport = true;
973 if (dynamic_state == VK_DYNAMIC_STATE_SCISSOR) has_dynamic_scissor = true;
974 if (dynamic_state == VK_DYNAMIC_STATE_LINE_WIDTH) has_dynamic_line_width = true;
Jeremy Kniager71fd5f02017-11-15 13:27:03 -0700975 if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV) has_dynamic_viewport_w_scaling_nv = true;
976 if (dynamic_state == VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT) has_dynamic_discard_rectangle_ext = true;
977 if (dynamic_state == VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT) has_dynamic_sample_locations_ext = true;
Jeff Bolz3e71f782018-08-29 23:15:45 -0500978 if (dynamic_state == VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV) has_dynamic_exclusive_scissor_nv = true;
Dave Houlton142c4cb2018-10-17 15:04:41 -0600979 if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV)
980 has_dynamic_shading_rate_palette_nv = true;
Petr Kraus299ba622017-11-24 03:09:03 +0100981 }
982 }
983
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600984 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
985 if (pCreateInfos[i].pVertexInputState != nullptr) {
986 auto const &vertex_input_state = pCreateInfos[i].pVertexInputState;
Peter Kohautc7d9d392018-07-15 00:34:07 +0200987
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700988 if (vertex_input_state->vertexBindingDescriptionCount > device_limits.maxVertexInputBindings) {
Peter Kohautc7d9d392018-07-15 00:34:07 +0200989 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
990 "VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613",
991 "vkCreateGraphicsPipelines: pararameter "
992 "pCreateInfo[%d].pVertexInputState->vertexBindingDescriptionCount (%u) is "
993 "greater than VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
994 i, vertex_input_state->vertexBindingDescriptionCount,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700995 device_limits.maxVertexInputBindings);
Peter Kohautc7d9d392018-07-15 00:34:07 +0200996 }
997
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700998 if (vertex_input_state->vertexAttributeDescriptionCount > device_limits.maxVertexInputAttributes) {
Peter Kohautc7d9d392018-07-15 00:34:07 +0200999 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1000 "VUID-VkPipelineVertexInputStateCreateInfo-vertexAttributeDescriptionCount-00614",
1001 "vkCreateGraphicsPipelines: pararameter "
Peter Kohaut9e92c5c2018-07-17 10:32:17 +02001002 "pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptionCount (%u) is "
Peter Kohautc7d9d392018-07-15 00:34:07 +02001003 "greater than VkPhysicalDeviceLimits::maxVertexInputAttributes (%u).",
1004 i, vertex_input_state->vertexBindingDescriptionCount,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001005 device_limits.maxVertexInputAttributes);
Peter Kohautc7d9d392018-07-15 00:34:07 +02001006 }
1007
1008 std::unordered_set<uint32_t> vertex_bindings(vertex_input_state->vertexBindingDescriptionCount);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001009 for (uint32_t d = 0; d < vertex_input_state->vertexBindingDescriptionCount; ++d) {
1010 auto const &vertex_bind_desc = vertex_input_state->pVertexBindingDescriptions[d];
Peter Kohautc7d9d392018-07-15 00:34:07 +02001011 auto const &binding_it = vertex_bindings.find(vertex_bind_desc.binding);
1012 if (binding_it != vertex_bindings.cend()) {
1013 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1014 "VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616",
1015 "vkCreateGraphicsPipelines: parameter "
1016 "pCreateInfo[%d].pVertexInputState->pVertexBindingDescription[%d].binding "
1017 "(%" PRIu32 ") is not distinct.",
1018 i, d, vertex_bind_desc.binding);
1019 }
1020 vertex_bindings.insert(vertex_bind_desc.binding);
1021
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001022 if (vertex_bind_desc.binding >= device_limits.maxVertexInputBindings) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001023 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001024 "VUID-VkVertexInputBindingDescription-binding-00618",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001025 "vkCreateGraphicsPipelines: parameter "
1026 "pCreateInfos[%u].pVertexInputState->pVertexBindingDescriptions[%u].binding (%u) is "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001027 "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001028 i, d, vertex_bind_desc.binding, device_limits.maxVertexInputBindings);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001029 }
1030
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001031 if (vertex_bind_desc.stride > device_limits.maxVertexInputBindingStride) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001032 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001033 "VUID-VkVertexInputBindingDescription-stride-00619",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001034 "vkCreateGraphicsPipelines: parameter "
1035 "pCreateInfos[%u].pVertexInputState->pVertexBindingDescriptions[%u].stride (%u) is greater "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001036 "than VkPhysicalDeviceLimits::maxVertexInputBindingStride (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001037 i, d, vertex_bind_desc.stride, device_limits.maxVertexInputBindingStride);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001038 }
1039 }
1040
Peter Kohautc7d9d392018-07-15 00:34:07 +02001041 std::unordered_set<uint32_t> attribute_locations(vertex_input_state->vertexAttributeDescriptionCount);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001042 for (uint32_t d = 0; d < vertex_input_state->vertexAttributeDescriptionCount; ++d) {
1043 auto const &vertex_attrib_desc = vertex_input_state->pVertexAttributeDescriptions[d];
Peter Kohautc7d9d392018-07-15 00:34:07 +02001044 auto const &location_it = attribute_locations.find(vertex_attrib_desc.location);
1045 if (location_it != attribute_locations.cend()) {
1046 skip |= log_msg(
1047 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1048 "VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-00617",
1049 "vkCreateGraphicsPipelines: parameter "
1050 "pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].location (%u) is not distinct.",
1051 i, d, vertex_attrib_desc.location);
1052 }
1053 attribute_locations.insert(vertex_attrib_desc.location);
1054
1055 auto const &binding_it = vertex_bindings.find(vertex_attrib_desc.binding);
1056 if (binding_it == vertex_bindings.cend()) {
1057 skip |= log_msg(
1058 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1059 "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615",
1060 "vkCreateGraphicsPipelines: parameter "
1061 " pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].binding (%u) does not exist "
1062 "in any pCreateInfo[%d].pVertexInputState->pVertexBindingDescription.",
1063 i, d, vertex_attrib_desc.binding, i);
1064 }
1065
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001066 if (vertex_attrib_desc.location >= device_limits.maxVertexInputAttributes) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001067 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001068 "VUID-VkVertexInputAttributeDescription-location-00620",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001069 "vkCreateGraphicsPipelines: parameter "
1070 "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].location (%u) is "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001071 "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001072 i, d, vertex_attrib_desc.location, device_limits.maxVertexInputAttributes);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001073 }
1074
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001075 if (vertex_attrib_desc.binding >= device_limits.maxVertexInputBindings) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001076 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001077 "VUID-VkVertexInputAttributeDescription-binding-00621",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001078 "vkCreateGraphicsPipelines: parameter "
1079 "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].binding (%u) is "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001080 "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001081 i, d, vertex_attrib_desc.binding, device_limits.maxVertexInputBindings);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001082 }
1083
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001084 if (vertex_attrib_desc.offset > device_limits.maxVertexInputAttributeOffset) {
Mark Lobodzinski88529492018-04-01 10:38:15 -06001085 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001086 "VUID-VkVertexInputAttributeDescription-offset-00622",
Mark Lobodzinski88529492018-04-01 10:38:15 -06001087 "vkCreateGraphicsPipelines: parameter "
1088 "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].offset (%u) is "
1089 "greater than VkPhysicalDeviceLimits::maxVertexInputAttributeOffset (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001090 i, d, vertex_attrib_desc.offset, device_limits.maxVertexInputAttributeOffset);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001091 }
1092 }
1093 }
1094
1095 if (pCreateInfos[i].pStages != nullptr) {
1096 bool has_control = false;
1097 bool has_eval = false;
1098
1099 for (uint32_t stage_index = 0; stage_index < pCreateInfos[i].stageCount; ++stage_index) {
1100 if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
1101 has_control = true;
1102 } else if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
1103 has_eval = true;
1104 }
1105 }
1106
1107 // pTessellationState is ignored without both tessellation control and tessellation evaluation shaders stages
1108 if (has_control && has_eval) {
1109 if (pCreateInfos[i].pTessellationState == nullptr) {
1110 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001111 "VUID-VkGraphicsPipelineCreateInfo-pStages-00731",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001112 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pStages includes a tessellation control "
1113 "shader stage and a tessellation evaluation shader stage, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001114 "pCreateInfos[%d].pTessellationState must not be NULL.",
1115 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001116 } else {
1117 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001118 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001119 ParameterName("pCreateInfos[%i].pTessellationState->pNext", ParameterName::IndexVector{i}), NULL,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001120 pCreateInfos[i].pTessellationState->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06001121 "VUID-VkGraphicsPipelineCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001122
1123 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001124 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001125 ParameterName("pCreateInfos[%i].pTessellationState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001126 pCreateInfos[i].pTessellationState->flags,
1127 "VUID-VkPipelineTessellationStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001128
1129 if (pCreateInfos[i].pTessellationState->sType !=
1130 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) {
1131 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001132 "VUID-VkPipelineTessellationStateCreateInfo-sType-sType",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001133 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pTessellationState->sType must "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001134 "be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO.",
1135 i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001136 }
1137
1138 if (pCreateInfos[i].pTessellationState->patchControlPoints == 0 ||
1139 pCreateInfos[i].pTessellationState->patchControlPoints >
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001140 device_limits.maxTessellationPatchSize) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001141 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001142 "VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001143 "vkCreateGraphicsPipelines: invalid parameter "
1144 "pCreateInfos[%d].pTessellationState->patchControlPoints value %u. patchControlPoints "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001145 "should be >0 and <=%u.",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001146 i, pCreateInfos[i].pTessellationState->patchControlPoints,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001147 device_limits.maxTessellationPatchSize);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001148 }
1149 }
1150 }
1151 }
1152
1153 // pViewportState, pMultisampleState, pDepthStencilState, and pColorBlendState ignored when rasterization is disabled
1154 if ((pCreateInfos[i].pRasterizationState != nullptr) &&
1155 (pCreateInfos[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
1156 if (pCreateInfos[i].pViewportState == nullptr) {
Petr Krausa6103552017-11-16 21:21:58 +01001157 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001158 VK_NULL_HANDLE, "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750",
Petr Krausa6103552017-11-16 21:21:58 +01001159 "vkCreateGraphicsPipelines: Rasterization is enabled (pCreateInfos[%" PRIu32
1160 "].pRasterizationState->rasterizerDiscardEnable is VK_FALSE), but pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001161 "].pViewportState (=NULL) is not a valid pointer.",
1162 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001163 } else {
Petr Krausa6103552017-11-16 21:21:58 +01001164 const auto &viewport_state = *pCreateInfos[i].pViewportState;
1165
1166 if (viewport_state.sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) {
1167 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001168 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-sType-sType",
Petr Krausa6103552017-11-16 21:21:58 +01001169 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001170 "].pViewportState->sType is not VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO.",
1171 i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001172 }
1173
Petr Krausa6103552017-11-16 21:21:58 +01001174 const VkStructureType allowed_structs_VkPipelineViewportStateCreateInfo[] = {
1175 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV,
Jeff Bolz3e71f782018-08-29 23:15:45 -05001176 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV,
1177 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV,
Jeff Bolz9af91c52018-09-01 21:53:57 -05001178 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV,
1179 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV,
Jeff Bolz3e71f782018-08-29 23:15:45 -05001180 };
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001181 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001182 "vkCreateGraphicsPipelines",
Petr Krausa6103552017-11-16 21:21:58 +01001183 ParameterName("pCreateInfos[%i].pViewportState->pNext", ParameterName::IndexVector{i}),
Jeff Bolz9af91c52018-09-01 21:53:57 -05001184 "VkPipelineViewportSwizzleStateCreateInfoNV, VkPipelineViewportWScalingStateCreateInfoNV, "
Jeff Bolzb8a8dd02018-09-18 02:39:24 -05001185 "VkPipelineViewportExclusiveScissorStateCreateInfoNV, VkPipelineViewportShadingRateImageStateCreateInfoNV, "
1186 "VkPipelineViewportCoarseSampleOrderStateCreateInfoNV",
Petr Krausa6103552017-11-16 21:21:58 +01001187 viewport_state.pNext, ARRAY_SIZE(allowed_structs_VkPipelineViewportStateCreateInfo),
Dave Houlton413a6782018-05-22 13:01:54 -06001188 allowed_structs_VkPipelineViewportStateCreateInfo, 65,
1189 "VUID-VkPipelineViewportStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001190
1191 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001192 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001193 ParameterName("pCreateInfos[%i].pViewportState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001194 viewport_state.flags, "VUID-VkPipelineViewportStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001195
Dave Houlton142c4cb2018-10-17 15:04:41 -06001196 auto exclusive_scissor_struct = lvl_find_in_chain<VkPipelineViewportExclusiveScissorStateCreateInfoNV>(
1197 pCreateInfos[i].pViewportState->pNext);
1198 auto shading_rate_image_struct = lvl_find_in_chain<VkPipelineViewportShadingRateImageStateCreateInfoNV>(
1199 pCreateInfos[i].pViewportState->pNext);
1200 auto coarse_sample_order_struct = lvl_find_in_chain<VkPipelineViewportCoarseSampleOrderStateCreateInfoNV>(
1201 pCreateInfos[i].pViewportState->pNext);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001202
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001203 if (!physical_device_features.multiViewport) {
Petr Krausa6103552017-11-16 21:21:58 +01001204 if (viewport_state.viewportCount != 1) {
1205 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001206 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
Petr Krausa6103552017-11-16 21:21:58 +01001207 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1208 "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001209 ") is not 1.",
1210 i, viewport_state.viewportCount);
Petr Krausa6103552017-11-16 21:21:58 +01001211 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001212
Petr Krausa6103552017-11-16 21:21:58 +01001213 if (viewport_state.scissorCount != 1) {
1214 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001215 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
Petr Krausa6103552017-11-16 21:21:58 +01001216 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1217 "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->scissorCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001218 ") is not 1.",
1219 i, viewport_state.scissorCount);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001220 }
Jeff Bolz3e71f782018-08-29 23:15:45 -05001221
Dave Houlton142c4cb2018-10-17 15:04:41 -06001222 if (exclusive_scissor_struct && (exclusive_scissor_struct->exclusiveScissorCount != 0 &&
1223 exclusive_scissor_struct->exclusiveScissorCount != 1)) {
1224 skip |=
1225 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1226 VK_NULL_HANDLE,
1227 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
1228 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1229 "disabled, but pCreateInfos[%" PRIu32
1230 "] VkPipelineViewportExclusiveScissorStateCreateInfoNV::exclusiveScissorCount (=%" PRIu32
1231 ") is not 1.",
1232 i, exclusive_scissor_struct->exclusiveScissorCount);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001233 }
1234
Jeff Bolz9af91c52018-09-01 21:53:57 -05001235 if (shading_rate_image_struct &&
1236 (shading_rate_image_struct->viewportCount != 0 && shading_rate_image_struct->viewportCount != 1)) {
1237 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton142c4cb2018-10-17 15:04:41 -06001238 VK_NULL_HANDLE,
1239 "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054",
Jeff Bolz9af91c52018-09-01 21:53:57 -05001240 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
Dave Houlton142c4cb2018-10-17 15:04:41 -06001241 "disabled, but pCreateInfos[%" PRIu32
1242 "] VkPipelineViewportShadingRateImageStateCreateInfoNV::viewportCount (=%" PRIu32
Jeff Bolzb8a8dd02018-09-18 02:39:24 -05001243 ") is neither 0 nor 1.",
Jeff Bolz9af91c52018-09-01 21:53:57 -05001244 i, shading_rate_image_struct->viewportCount);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001245 }
1246
Petr Krausa6103552017-11-16 21:21:58 +01001247 } else { // multiViewport enabled
1248 if (viewport_state.viewportCount == 0) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001249 skip |= log_msg(
1250 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001251 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001252 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->viewportCount is 0.", i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001253 } else if (viewport_state.viewportCount > device_limits.maxViewports) {
Petr Krausa6103552017-11-16 21:21:58 +01001254 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001255 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
Petr Krausa6103552017-11-16 21:21:58 +01001256 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1257 "].pViewportState->viewportCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001258 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001259 i, viewport_state.viewportCount, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001260 }
Petr Krausa6103552017-11-16 21:21:58 +01001261
1262 if (viewport_state.scissorCount == 0) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001263 skip |= log_msg(
1264 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001265 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001266 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->scissorCount is 0.", i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001267 } else if (viewport_state.scissorCount > device_limits.maxViewports) {
Petr Krausa6103552017-11-16 21:21:58 +01001268 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001269 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219",
Petr Krausa6103552017-11-16 21:21:58 +01001270 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1271 "].pViewportState->scissorCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001272 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001273 i, viewport_state.scissorCount, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001274 }
1275 }
1276
Jeff Bolz3e71f782018-08-29 23:15:45 -05001277 if (exclusive_scissor_struct &&
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001278 exclusive_scissor_struct->exclusiveScissorCount > device_limits.maxViewports) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001279 skip |= log_msg(
1280 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1281 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
1282 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "] exclusiveScissorCount (=%" PRIu32
1283 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001284 i, exclusive_scissor_struct->exclusiveScissorCount, device_limits.maxViewports);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001285 }
1286
Jeff Bolz9af91c52018-09-01 21:53:57 -05001287 if (shading_rate_image_struct &&
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001288 shading_rate_image_struct->viewportCount > device_limits.maxViewports) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001289 skip |=
1290 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1291 VK_NULL_HANDLE, "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02055",
1292 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1293 "] VkPipelineViewportShadingRateImageStateCreateInfoNV viewportCount (=%" PRIu32
1294 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001295 i, shading_rate_image_struct->viewportCount, device_limits.maxViewports);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001296 }
1297
Petr Krausa6103552017-11-16 21:21:58 +01001298 if (viewport_state.scissorCount != viewport_state.viewportCount) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001299 skip |=
1300 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001301 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001302 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->scissorCount (=%" PRIu32
1303 ") is not identical to pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32 ").",
1304 i, viewport_state.scissorCount, i, viewport_state.viewportCount);
Petr Krausa6103552017-11-16 21:21:58 +01001305 }
1306
Dave Houlton142c4cb2018-10-17 15:04:41 -06001307 if (exclusive_scissor_struct && exclusive_scissor_struct->exclusiveScissorCount != 0 &&
Jeff Bolz3e71f782018-08-29 23:15:45 -05001308 exclusive_scissor_struct->exclusiveScissorCount != viewport_state.viewportCount) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001309 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1310 VK_NULL_HANDLE,
1311 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029",
1312 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "] exclusiveScissorCount (=%" PRIu32
1313 ") must be zero or identical to pCreateInfos[%" PRIu32
1314 "].pViewportState->viewportCount (=%" PRIu32 ").",
1315 i, exclusive_scissor_struct->exclusiveScissorCount, i, viewport_state.viewportCount);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001316 }
1317
Dave Houlton142c4cb2018-10-17 15:04:41 -06001318 if (shading_rate_image_struct && shading_rate_image_struct->shadingRateImageEnable &&
Jeff Bolz9af91c52018-09-01 21:53:57 -05001319 shading_rate_image_struct->viewportCount != viewport_state.viewportCount) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001320 skip |= log_msg(
1321 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1322 "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056",
1323 "vkCreateGraphicsPipelines: If shadingRateImageEnable is enabled, pCreateInfos[%" PRIu32
1324 "] "
1325 "VkPipelineViewportShadingRateImageStateCreateInfoNV viewportCount (=%" PRIu32
1326 ") must identical to pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32 ").",
1327 i, shading_rate_image_struct->viewportCount, i, viewport_state.viewportCount);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001328 }
1329
Petr Krausa6103552017-11-16 21:21:58 +01001330 if (!has_dynamic_viewport && viewport_state.viewportCount > 0 && viewport_state.pViewports == nullptr) {
1331 skip |= log_msg(
1332 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
Dave Houlton413a6782018-05-22 13:01:54 -06001333 "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747",
Petr Krausa6103552017-11-16 21:21:58 +01001334 "vkCreateGraphicsPipelines: The viewport state is static (pCreateInfos[%" PRIu32
1335 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_VIEWPORT), but pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001336 "].pViewportState->pViewports (=NULL) is an invalid pointer.",
1337 i, i);
Petr Krausa6103552017-11-16 21:21:58 +01001338 }
1339
1340 if (!has_dynamic_scissor && viewport_state.scissorCount > 0 && viewport_state.pScissors == nullptr) {
1341 skip |= log_msg(
1342 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
Dave Houlton413a6782018-05-22 13:01:54 -06001343 "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748",
Petr Krausa6103552017-11-16 21:21:58 +01001344 "vkCreateGraphicsPipelines: The scissor state is static (pCreateInfos[%" PRIu32
1345 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_SCISSOR), but pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001346 "].pViewportState->pScissors (=NULL) is an invalid pointer.",
1347 i, i);
Petr Krausa6103552017-11-16 21:21:58 +01001348 }
1349
Jeff Bolz3e71f782018-08-29 23:15:45 -05001350 if (!has_dynamic_exclusive_scissor_nv && exclusive_scissor_struct &&
Dave Houlton142c4cb2018-10-17 15:04:41 -06001351 exclusive_scissor_struct->exclusiveScissorCount > 0 &&
1352 exclusive_scissor_struct->pExclusiveScissors == nullptr) {
1353 skip |=
1354 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1355 VK_NULL_HANDLE, "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-pDynamicStates-02030",
1356 "vkCreateGraphicsPipelines: The exclusive scissor state is static (pCreateInfos[%" PRIu32
1357 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV), but "
1358 "pCreateInfos[%" PRIu32 "] pExclusiveScissors (=NULL) is an invalid pointer.",
1359 i, i);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001360 }
1361
Jeff Bolz9af91c52018-09-01 21:53:57 -05001362 if (!has_dynamic_shading_rate_palette_nv && shading_rate_image_struct &&
Dave Houlton142c4cb2018-10-17 15:04:41 -06001363 shading_rate_image_struct->viewportCount > 0 &&
1364 shading_rate_image_struct->pShadingRatePalettes == nullptr) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05001365 skip |= log_msg(
1366 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1367 "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-pDynamicStates-02057",
1368 "vkCreateGraphicsPipelines: The shading rate palette state is static (pCreateInfos[%" PRIu32
Dave Houlton142c4cb2018-10-17 15:04:41 -06001369 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV), "
1370 "but pCreateInfos[%" PRIu32 "] pShadingRatePalettes (=NULL) is an invalid pointer.",
Jeff Bolz9af91c52018-09-01 21:53:57 -05001371 i, i);
1372 }
1373
Petr Krausb3fcdb42018-01-09 22:09:09 +01001374 // validate the VkViewports
1375 if (!has_dynamic_viewport && viewport_state.pViewports) {
1376 for (uint32_t viewport_i = 0; viewport_i < viewport_state.viewportCount; ++viewport_i) {
1377 const auto &viewport = viewport_state.pViewports[viewport_i]; // will crash on invalid ptr
1378 const char fn_name[] = "vkCreateGraphicsPipelines";
1379 const std::string param_name = "pCreateInfos[" + std::to_string(i) + "].pViewportState->pViewports[" +
1380 std::to_string(viewport_i) + "]";
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001381 skip |= manual_PreCallValidateViewport(viewport, fn_name, param_name.c_str(),
Petr Krausb3fcdb42018-01-09 22:09:09 +01001382 VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
1383 }
1384 }
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001385
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001386 if (has_dynamic_viewport_w_scaling_nv && !device_extensions.vk_nv_clip_space_w_scaling) {
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001387 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001388 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001389 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -07001390 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, but "
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001391 "VK_NV_clip_space_w_scaling extension is not enabled.",
1392 i);
1393 }
1394
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001395 if (has_dynamic_discard_rectangle_ext && !device_extensions.vk_ext_discard_rectangles) {
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001396 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001397 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001398 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -07001399 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, but "
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001400 "VK_EXT_discard_rectangles extension is not enabled.",
1401 i);
1402 }
1403
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001404 if (has_dynamic_sample_locations_ext && !device_extensions.vk_ext_sample_locations) {
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001405 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001406 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001407 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -07001408 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, but "
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001409 "VK_EXT_sample_locations extension is not enabled.",
1410 i);
1411 }
Jeff Bolz3e71f782018-08-29 23:15:45 -05001412
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001413 if (has_dynamic_exclusive_scissor_nv && !device_extensions.vk_nv_scissor_exclusive) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05001414 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1415 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
1416 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1417 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV, but "
1418 "VK_NV_scissor_exclusive extension is not enabled.",
1419 i);
1420 }
Jeff Bolz9af91c52018-09-01 21:53:57 -05001421
1422 if (coarse_sample_order_struct &&
1423 coarse_sample_order_struct->sampleOrderType != VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV &&
1424 coarse_sample_order_struct->customSampleOrderCount != 0) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001425 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1426 VK_NULL_HANDLE,
1427 "VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-sampleOrderType-02072",
1428 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1429 "] "
1430 "VkPipelineViewportCoarseSampleOrderStateCreateInfoNV sampleOrderType is not "
1431 "VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV and customSampleOrderCount is not 0.",
1432 i);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001433 }
1434
1435 if (coarse_sample_order_struct) {
1436 for (uint32_t order_i = 0; order_i < coarse_sample_order_struct->customSampleOrderCount; ++order_i) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001437 skip |= ValidateCoarseSampleOrderCustomNV(&coarse_sample_order_struct->pCustomSampleOrders[order_i]);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001438 }
1439 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001440 }
1441
1442 if (pCreateInfos[i].pMultisampleState == nullptr) {
1443 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001444 "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001445 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pRasterizationState->rasterizerDiscardEnable "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001446 "is VK_FALSE, pCreateInfos[%d].pMultisampleState must not be NULL.",
1447 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001448 } else {
Dave Houltonb3bbec72018-01-17 10:13:33 -07001449 const VkStructureType valid_next_stypes[] = {LvlTypeMap<VkPipelineCoverageModulationStateCreateInfoNV>::kSType,
1450 LvlTypeMap<VkPipelineCoverageToColorStateCreateInfoNV>::kSType,
1451 LvlTypeMap<VkPipelineSampleLocationsStateCreateInfoEXT>::kSType};
Mike Schuchardt97662b02017-12-06 13:31:29 -07001452 const char *valid_struct_names =
Dave Houltona9df0ce2018-02-07 10:51:23 -07001453 "VkPipelineCoverageModulationStateCreateInfoNV, VkPipelineCoverageToColorStateCreateInfoNV, "
John Zulauf96b0e422017-11-14 11:43:19 -07001454 "VkPipelineSampleLocationsStateCreateInfoEXT";
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001455 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001456 "vkCreateGraphicsPipelines",
John Zulauf96b0e422017-11-14 11:43:19 -07001457 ParameterName("pCreateInfos[%i].pMultisampleState->pNext", ParameterName::IndexVector{i}),
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001458 valid_struct_names, pCreateInfos[i].pMultisampleState->pNext, 3, valid_next_stypes, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06001459 "VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001460
1461 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001462 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001463 ParameterName("pCreateInfos[%i].pMultisampleState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001464 pCreateInfos[i].pMultisampleState->flags, "VUID-VkPipelineMultisampleStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001465
1466 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001467 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001468 ParameterName("pCreateInfos[%i].pMultisampleState->sampleShadingEnable", ParameterName::IndexVector{i}),
1469 pCreateInfos[i].pMultisampleState->sampleShadingEnable);
1470
1471 skip |= validate_array(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001472 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001473 ParameterName("pCreateInfos[%i].pMultisampleState->rasterizationSamples", ParameterName::IndexVector{i}),
1474 ParameterName("pCreateInfos[%i].pMultisampleState->pSampleMask", ParameterName::IndexVector{i}),
Gabríel Arthúr Pétursson092b29b2018-03-21 22:44:11 +00001475 pCreateInfos[i].pMultisampleState->rasterizationSamples, &pCreateInfos[i].pMultisampleState->pSampleMask,
Dave Houlton413a6782018-05-22 13:01:54 -06001476 true, false, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001477
1478 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001479 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001480 ParameterName("pCreateInfos[%i].pMultisampleState->alphaToCoverageEnable", ParameterName::IndexVector{i}),
1481 pCreateInfos[i].pMultisampleState->alphaToCoverageEnable);
1482
1483 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001484 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001485 ParameterName("pCreateInfos[%i].pMultisampleState->alphaToOneEnable", ParameterName::IndexVector{i}),
1486 pCreateInfos[i].pMultisampleState->alphaToOneEnable);
1487
1488 if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) {
1489 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001490 kVUID_PVError_InvalidStructSType,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001491 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pMultisampleState->sType must be "
1492 "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO",
1493 i);
1494 }
John Zulauf7acac592017-11-06 11:15:53 -07001495 if (pCreateInfos[i].pMultisampleState->sampleShadingEnable == VK_TRUE) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001496 if (!physical_device_features.sampleRateShading) {
John Zulauf7acac592017-11-06 11:15:53 -07001497 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001498 "VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784",
John Zulauf7acac592017-11-06 11:15:53 -07001499 "vkCreateGraphicsPipelines(): parameter "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001500 "pCreateInfos[%d].pMultisampleState->sampleShadingEnable.",
1501 i);
John Zulauf7acac592017-11-06 11:15:53 -07001502 }
1503 // TODO Add documentation issue about when minSampleShading must be in range and when it is ignored
1504 // For now a "least noise" test *only* when sampleShadingEnable is VK_TRUE.
1505 if (!in_inclusive_range(pCreateInfos[i].pMultisampleState->minSampleShading, 0.F, 1.0F)) {
1506 skip |= log_msg(
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001507 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001508 "VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786",
Mark Lobodzinski88529492018-04-01 10:38:15 -06001509 "vkCreateGraphicsPipelines(): parameter pCreateInfos[%d].pMultisampleState->minSampleShading.", i);
John Zulauf7acac592017-11-06 11:15:53 -07001510 }
1511 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001512 }
1513
Petr Krause91f7a12017-12-14 20:57:36 +01001514 bool uses_color_attachment = false;
1515 bool uses_depthstencil_attachment = false;
1516 {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001517 const auto subpasses_uses_it = renderpasses_states.find(pCreateInfos[i].renderPass);
1518 if (subpasses_uses_it != renderpasses_states.end()) {
Petr Krause91f7a12017-12-14 20:57:36 +01001519 const auto &subpasses_uses = subpasses_uses_it->second;
1520 if (subpasses_uses.subpasses_using_color_attachment.count(pCreateInfos[i].subpass))
1521 uses_color_attachment = true;
1522 if (subpasses_uses.subpasses_using_depthstencil_attachment.count(pCreateInfos[i].subpass))
1523 uses_depthstencil_attachment = true;
1524 }
1525 }
1526
1527 if (pCreateInfos[i].pDepthStencilState != nullptr && uses_depthstencil_attachment) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001528 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001529 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001530 ParameterName("pCreateInfos[%i].pDepthStencilState->pNext", ParameterName::IndexVector{i}), NULL,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001531 pCreateInfos[i].pDepthStencilState->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06001532 "VUID-VkPipelineDepthStencilStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001533
1534 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001535 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001536 ParameterName("pCreateInfos[%i].pDepthStencilState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001537 pCreateInfos[i].pDepthStencilState->flags, "VUID-VkPipelineDepthStencilStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001538
1539 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001540 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001541 ParameterName("pCreateInfos[%i].pDepthStencilState->depthTestEnable", ParameterName::IndexVector{i}),
1542 pCreateInfos[i].pDepthStencilState->depthTestEnable);
1543
1544 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001545 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001546 ParameterName("pCreateInfos[%i].pDepthStencilState->depthWriteEnable", ParameterName::IndexVector{i}),
1547 pCreateInfos[i].pDepthStencilState->depthWriteEnable);
1548
1549 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001550 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001551 ParameterName("pCreateInfos[%i].pDepthStencilState->depthCompareOp", ParameterName::IndexVector{i}),
1552 "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->depthCompareOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001553 "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001554
1555 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001556 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001557 ParameterName("pCreateInfos[%i].pDepthStencilState->depthBoundsTestEnable", ParameterName::IndexVector{i}),
1558 pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable);
1559
1560 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001561 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001562 ParameterName("pCreateInfos[%i].pDepthStencilState->stencilTestEnable", ParameterName::IndexVector{i}),
1563 pCreateInfos[i].pDepthStencilState->stencilTestEnable);
1564
1565 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001566 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001567 ParameterName("pCreateInfos[%i].pDepthStencilState->front.failOp", ParameterName::IndexVector{i}),
1568 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.failOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001569 "VUID-VkStencilOpState-failOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001570
1571 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001572 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001573 ParameterName("pCreateInfos[%i].pDepthStencilState->front.passOp", ParameterName::IndexVector{i}),
1574 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.passOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001575 "VUID-VkStencilOpState-passOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001576
1577 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001578 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001579 ParameterName("pCreateInfos[%i].pDepthStencilState->front.depthFailOp", ParameterName::IndexVector{i}),
1580 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.depthFailOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001581 "VUID-VkStencilOpState-depthFailOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001582
1583 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001584 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001585 ParameterName("pCreateInfos[%i].pDepthStencilState->front.compareOp", ParameterName::IndexVector{i}),
1586 "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->front.compareOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001587 "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001588
1589 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001590 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001591 ParameterName("pCreateInfos[%i].pDepthStencilState->back.failOp", ParameterName::IndexVector{i}),
1592 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.failOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001593 "VUID-VkStencilOpState-failOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001594
1595 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001596 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001597 ParameterName("pCreateInfos[%i].pDepthStencilState->back.passOp", ParameterName::IndexVector{i}),
1598 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.passOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001599 "VUID-VkStencilOpState-passOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001600
1601 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001602 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001603 ParameterName("pCreateInfos[%i].pDepthStencilState->back.depthFailOp", ParameterName::IndexVector{i}),
1604 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.depthFailOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001605 "VUID-VkStencilOpState-depthFailOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001606
1607 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001608 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001609 ParameterName("pCreateInfos[%i].pDepthStencilState->back.compareOp", ParameterName::IndexVector{i}),
1610 "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->back.compareOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001611 "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001612
1613 if (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) {
1614 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001615 kVUID_PVError_InvalidStructSType,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001616 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pDepthStencilState->sType must be "
1617 "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO",
1618 i);
1619 }
1620 }
1621
Shannon McPherson9b9532b2018-10-24 12:00:09 -06001622 const VkStructureType allowed_structs_VkPipelineColorBlendStateCreateInfo[] = {
1623 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT};
1624
Petr Krause91f7a12017-12-14 20:57:36 +01001625 if (pCreateInfos[i].pColorBlendState != nullptr && uses_color_attachment) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001626 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001627 "vkCreateGraphicsPipelines",
Shannon McPherson9b9532b2018-10-24 12:00:09 -06001628 ParameterName("pCreateInfos[%i].pColorBlendState->pNext", ParameterName::IndexVector{i}),
1629 "VkPipelineColorBlendAdvancedStateCreateInfoEXT", pCreateInfos[i].pColorBlendState->pNext,
1630 ARRAY_SIZE(allowed_structs_VkPipelineColorBlendStateCreateInfo),
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001631 allowed_structs_VkPipelineColorBlendStateCreateInfo, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06001632 "VUID-VkPipelineColorBlendStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001633
1634 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001635 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001636 ParameterName("pCreateInfos[%i].pColorBlendState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001637 pCreateInfos[i].pColorBlendState->flags, "VUID-VkPipelineColorBlendStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001638
1639 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001640 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001641 ParameterName("pCreateInfos[%i].pColorBlendState->logicOpEnable", ParameterName::IndexVector{i}),
1642 pCreateInfos[i].pColorBlendState->logicOpEnable);
1643
1644 skip |= validate_array(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001645 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001646 ParameterName("pCreateInfos[%i].pColorBlendState->attachmentCount", ParameterName::IndexVector{i}),
1647 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments", ParameterName::IndexVector{i}),
Gabríel Arthúr Pétursson092b29b2018-03-21 22:44:11 +00001648 pCreateInfos[i].pColorBlendState->attachmentCount, &pCreateInfos[i].pColorBlendState->pAttachments, false,
Dave Houlton413a6782018-05-22 13:01:54 -06001649 true, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001650
1651 if (pCreateInfos[i].pColorBlendState->pAttachments != NULL) {
1652 for (uint32_t attachmentIndex = 0; attachmentIndex < pCreateInfos[i].pColorBlendState->attachmentCount;
1653 ++attachmentIndex) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001654 skip |= validate_bool32("vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001655 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].blendEnable",
1656 ParameterName::IndexVector{i, attachmentIndex}),
1657 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].blendEnable);
1658
1659 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001660 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001661 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].srcColorBlendFactor",
1662 ParameterName::IndexVector{i, attachmentIndex}),
1663 "VkBlendFactor", AllVkBlendFactorEnums,
1664 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcColorBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001665 "VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001666
1667 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001668 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001669 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].dstColorBlendFactor",
1670 ParameterName::IndexVector{i, attachmentIndex}),
1671 "VkBlendFactor", AllVkBlendFactorEnums,
1672 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstColorBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001673 "VUID-VkPipelineColorBlendAttachmentState-dstColorBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001674
1675 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001676 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001677 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].colorBlendOp",
1678 ParameterName::IndexVector{i, attachmentIndex}),
1679 "VkBlendOp", AllVkBlendOpEnums,
1680 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorBlendOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001681 "VUID-VkPipelineColorBlendAttachmentState-colorBlendOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001682
1683 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001684 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001685 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].srcAlphaBlendFactor",
1686 ParameterName::IndexVector{i, attachmentIndex}),
1687 "VkBlendFactor", AllVkBlendFactorEnums,
1688 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcAlphaBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001689 "VUID-VkPipelineColorBlendAttachmentState-srcAlphaBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001690
1691 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001692 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001693 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].dstAlphaBlendFactor",
1694 ParameterName::IndexVector{i, attachmentIndex}),
1695 "VkBlendFactor", AllVkBlendFactorEnums,
1696 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstAlphaBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001697 "VUID-VkPipelineColorBlendAttachmentState-dstAlphaBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001698
1699 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001700 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001701 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].alphaBlendOp",
1702 ParameterName::IndexVector{i, attachmentIndex}),
1703 "VkBlendOp", AllVkBlendOpEnums,
1704 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].alphaBlendOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001705 "VUID-VkPipelineColorBlendAttachmentState-alphaBlendOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001706
1707 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001708 validate_flags("vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001709 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].colorWriteMask",
1710 ParameterName::IndexVector{i, attachmentIndex}),
1711 "VkColorComponentFlagBits", AllVkColorComponentFlagBits,
1712 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorWriteMask,
Dave Houlton413a6782018-05-22 13:01:54 -06001713 false, false, "VUID-VkPipelineColorBlendAttachmentState-colorWriteMask-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001714 }
1715 }
1716
1717 if (pCreateInfos[i].pColorBlendState->sType != VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO) {
1718 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001719 kVUID_PVError_InvalidStructSType,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001720 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pColorBlendState->sType must be "
1721 "VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO",
1722 i);
1723 }
1724
1725 // If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value
1726 if (pCreateInfos[i].pColorBlendState->logicOpEnable == VK_TRUE) {
1727 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001728 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001729 ParameterName("pCreateInfos[%i].pColorBlendState->logicOp", ParameterName::IndexVector{i}), "VkLogicOp",
Dave Houlton413a6782018-05-22 13:01:54 -06001730 AllVkLogicOpEnums, pCreateInfos[i].pColorBlendState->logicOp,
1731 "VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001732 }
1733 }
1734 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001735
Petr Kraus9752aae2017-11-24 03:05:50 +01001736 if (pCreateInfos[i].flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) {
1737 if (pCreateInfos[i].basePipelineIndex != -1) {
1738 if (pCreateInfos[i].basePipelineHandle != VK_NULL_HANDLE) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001739 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001740 "VUID-VkGraphicsPipelineCreateInfo-flags-00724",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001741 "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineHandle, must be "
1742 "VK_NULL_HANDLE if pCreateInfos->flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001743 "and pCreateInfos->basePipelineIndex is not -1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001744 }
1745 }
1746
Petr Kraus9752aae2017-11-24 03:05:50 +01001747 if (pCreateInfos[i].basePipelineHandle != VK_NULL_HANDLE) {
1748 if (pCreateInfos[i].basePipelineIndex != -1) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001749 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001750 "VUID-VkGraphicsPipelineCreateInfo-flags-00725",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001751 "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineIndex, must be -1 if "
1752 "pCreateInfos->flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag and "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001753 "pCreateInfos->basePipelineHandle is not VK_NULL_HANDLE.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001754 }
1755 }
1756 }
1757
Petr Kraus9752aae2017-11-24 03:05:50 +01001758 if (pCreateInfos[i].pRasterizationState) {
1759 if ((pCreateInfos[i].pRasterizationState->polygonMode != VK_POLYGON_MODE_FILL) &&
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001760 (physical_device_features.fillModeNonSolid == false)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001761 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001762 kVUID_PVError_DeviceFeature,
Dave Houltona9df0ce2018-02-07 10:51:23 -07001763 "vkCreateGraphicsPipelines parameter, VkPolygonMode "
1764 "pCreateInfos->pRasterizationState->polygonMode cannot be VK_POLYGON_MODE_POINT or "
1765 "VK_POLYGON_MODE_LINE if VkPhysicalDeviceFeatures->fillModeNonSolid is false.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001766 }
Petr Kraus299ba622017-11-24 03:09:03 +01001767
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001768 if (!has_dynamic_line_width && !physical_device_features.wideLines &&
Petr Kraus299ba622017-11-24 03:09:03 +01001769 (pCreateInfos[i].pRasterizationState->lineWidth != 1.0f)) {
Dave Houlton413a6782018-05-22 13:01:54 -06001770 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001771 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001772 0, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00749",
1773 "The line width state is static (pCreateInfos[%" PRIu32
1774 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_LINE_WIDTH) and "
1775 "VkPhysicalDeviceFeatures::wideLines is disabled, but pCreateInfos[%" PRIu32
1776 "].pRasterizationState->lineWidth (=%f) is not 1.0.",
1777 i, i, pCreateInfos[i].pRasterizationState->lineWidth);
Petr Kraus299ba622017-11-24 03:09:03 +01001778 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001779 }
1780
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001781 for (size_t j = 0; j < pCreateInfos[i].stageCount; j++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001782 skip |= validate_string("vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001783 ParameterName("pCreateInfos[%i].pStages[%i].pName", ParameterName::IndexVector{i, j}),
Mark Lobodzinskiebee3552018-05-29 09:55:54 -06001784 "VUID-VkGraphicsPipelineCreateInfo-pStages-parameter", pCreateInfos[i].pStages[j].pName);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001785 }
1786 }
1787 }
1788
1789 return skip;
1790}
1791
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001792bool StatelessValidation::manual_PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
1793 const VkComputePipelineCreateInfo *pCreateInfos,
1794 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001795 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001796 for (uint32_t i = 0; i < createInfoCount; i++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001797 skip |= validate_string("vkCreateComputePipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001798 ParameterName("pCreateInfos[%i].stage.pName", ParameterName::IndexVector{i}),
Mark Lobodzinskiebee3552018-05-29 09:55:54 -06001799 "VUID-VkPipelineShaderStageCreateInfo-pName-parameter", pCreateInfos[i].stage.pName);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001800 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001801 return skip;
1802}
1803
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001804bool StatelessValidation::manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
1805 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001806 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001807
1808 if (pCreateInfo != nullptr) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001809 const auto &features = physical_device_features;
1810 const auto &limits = device_limits;
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001811
John Zulauf71968502017-10-26 13:51:15 -06001812 if (pCreateInfo->anisotropyEnable == VK_TRUE) {
1813 if (!in_inclusive_range(pCreateInfo->maxAnisotropy, 1.0F, limits.maxSamplerAnisotropy)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001814 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001815 "VUID-VkSamplerCreateInfo-anisotropyEnable-01071",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001816 "vkCreateSampler(): value of %s must be in range [1.0, %f] %s, but %f found.",
John Zulauf71968502017-10-26 13:51:15 -06001817 "pCreateInfo->maxAnisotropy", limits.maxSamplerAnisotropy,
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001818 "VkPhysicalDeviceLimits::maxSamplerAnistropy", pCreateInfo->maxAnisotropy);
John Zulauf71968502017-10-26 13:51:15 -06001819 }
1820
1821 // Anistropy cannot be enabled in sampler unless enabled as a feature
1822 if (features.samplerAnisotropy == VK_FALSE) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001823 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001824 "VUID-VkSamplerCreateInfo-anisotropyEnable-01070",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001825 "vkCreateSampler(): Anisotropic sampling feature is not enabled, %s must be VK_FALSE.",
1826 "pCreateInfo->anisotropyEnable");
John Zulauf71968502017-10-26 13:51:15 -06001827 }
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001828 }
John Zulauf71968502017-10-26 13:51:15 -06001829
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001830 if (pCreateInfo->unnormalizedCoordinates == VK_TRUE) {
1831 if (pCreateInfo->minFilter != pCreateInfo->magFilter) {
1832 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1833 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01072",
1834 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1835 "pCreateInfo->minFilter (%s) and pCreateInfo->magFilter (%s) must be equal.",
1836 string_VkFilter(pCreateInfo->minFilter), string_VkFilter(pCreateInfo->magFilter));
1837 }
1838 if (pCreateInfo->mipmapMode != VK_SAMPLER_MIPMAP_MODE_NEAREST) {
1839 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1840 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01073",
1841 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1842 "pCreateInfo->mipmapMode (%s) must be VK_SAMPLER_MIPMAP_MODE_NEAREST.",
1843 string_VkSamplerMipmapMode(pCreateInfo->mipmapMode));
1844 }
1845 if (pCreateInfo->minLod != 0.0f || pCreateInfo->maxLod != 0.0f) {
1846 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1847 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01074",
1848 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1849 "pCreateInfo->minLod (%f) and pCreateInfo->maxLod (%f) must both be zero.",
1850 pCreateInfo->minLod, pCreateInfo->maxLod);
1851 }
1852 if ((pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
1853 pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1854 (pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
1855 pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
1856 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1857 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01075",
1858 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1859 "pCreateInfo->addressModeU (%s) and pCreateInfo->addressModeV (%s) must both be "
1860 "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER.",
1861 string_VkSamplerAddressMode(pCreateInfo->addressModeU),
1862 string_VkSamplerAddressMode(pCreateInfo->addressModeV));
1863 }
1864 if (pCreateInfo->anisotropyEnable == VK_TRUE) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001865 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001866 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01076",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001867 "vkCreateSampler(): pCreateInfo->anisotropyEnable and pCreateInfo->unnormalizedCoordinates must "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001868 "not both be VK_TRUE.");
John Zulauf71968502017-10-26 13:51:15 -06001869 }
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001870 if (pCreateInfo->compareEnable == VK_TRUE) {
1871 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1872 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01077",
1873 "vkCreateSampler(): pCreateInfo->compareEnable and pCreateInfo->unnormalizedCoordinates must "
1874 "not both be VK_TRUE.");
1875 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001876 }
1877
1878 // If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value
1879 if (pCreateInfo->compareEnable == VK_TRUE) {
Dave Houlton413a6782018-05-22 13:01:54 -06001880 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001881 validate_ranged_enum("vkCreateSampler", "pCreateInfo->compareOp", "VkCompareOp", AllVkCompareOpEnums,
Dave Houlton413a6782018-05-22 13:01:54 -06001882 pCreateInfo->compareOp, "VUID-VkSamplerCreateInfo-compareEnable-01080");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001883 }
1884
1885 // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor must be a
1886 // valid VkBorderColor value
1887 if ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1888 (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1889 (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001890 skip |= validate_ranged_enum("vkCreateSampler", "pCreateInfo->borderColor", "VkBorderColor",
Dave Houlton413a6782018-05-22 13:01:54 -06001891 AllVkBorderColorEnums, pCreateInfo->borderColor,
1892 "VUID-VkSamplerCreateInfo-addressModeU-01078");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001893 }
1894
1895 // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, the
1896 // VK_KHR_sampler_mirror_clamp_to_edge extension must be enabled
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001897 if (!device_extensions.vk_khr_sampler_mirror_clamp_to_edge &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001898 ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) ||
1899 (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) ||
1900 (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE))) {
Dave Houlton413a6782018-05-22 13:01:54 -06001901 skip |=
1902 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1903 "VUID-VkSamplerCreateInfo-addressModeU-01079",
1904 "vkCreateSampler(): A VkSamplerAddressMode value is set to VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE "
1905 "but the VK_KHR_sampler_mirror_clamp_to_edge extension has not been enabled.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001906 }
John Zulauf275805c2017-10-26 15:34:49 -06001907
1908 // Checks for the IMG cubic filtering extension
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001909 if (device_extensions.vk_img_filter_cubic) {
John Zulauf275805c2017-10-26 15:34:49 -06001910 if ((pCreateInfo->anisotropyEnable == VK_TRUE) &&
1911 ((pCreateInfo->minFilter == VK_FILTER_CUBIC_IMG) || (pCreateInfo->magFilter == VK_FILTER_CUBIC_IMG))) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001912 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001913 "VUID-VkSamplerCreateInfo-magFilter-01081",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001914 "vkCreateSampler(): Anisotropic sampling must not be VK_TRUE when either minFilter or magFilter "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001915 "are VK_FILTER_CUBIC_IMG.");
John Zulauf275805c2017-10-26 15:34:49 -06001916 }
1917 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001918 }
1919
1920 return skip;
1921}
1922
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001923bool StatelessValidation::manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
1924 const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001925 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001926
1927 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
1928 if ((pCreateInfo != nullptr) && (pCreateInfo->pBindings != nullptr)) {
1929 for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
1930 if (pCreateInfo->pBindings[i].descriptorCount != 0) {
1931 // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and descriptorCount
1932 // is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a pointer to an array of descriptorCount
1933 // valid VkSampler handles
1934 if (((pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
1935 (pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) &&
1936 (pCreateInfo->pBindings[i].pImmutableSamplers != nullptr)) {
1937 for (uint32_t descriptor_index = 0; descriptor_index < pCreateInfo->pBindings[i].descriptorCount;
1938 ++descriptor_index) {
1939 if (pCreateInfo->pBindings[i].pImmutableSamplers[descriptor_index] == VK_NULL_HANDLE) {
1940 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001941 kVUID_PVError_RequiredParameter,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001942 "vkCreateDescriptorSetLayout: required parameter "
Dave Houltona9df0ce2018-02-07 10:51:23 -07001943 "pCreateInfo->pBindings[%d].pImmutableSamplers[%d] specified as VK_NULL_HANDLE",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001944 i, descriptor_index);
1945 }
1946 }
1947 }
1948
1949 // If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values
1950 if ((pCreateInfo->pBindings[i].stageFlags != 0) &&
1951 ((pCreateInfo->pBindings[i].stageFlags & (~AllVkShaderStageFlagBits)) != 0)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001952 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001953 "VUID-VkDescriptorSetLayoutBinding-descriptorCount-00283",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001954 "vkCreateDescriptorSetLayout(): if pCreateInfo->pBindings[%d].descriptorCount is not 0, "
1955 "pCreateInfo->pBindings[%d].stageFlags must be a valid combination of VkShaderStageFlagBits "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001956 "values.",
1957 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001958 }
1959 }
1960 }
1961 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001962 return skip;
1963}
1964
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001965bool StatelessValidation::manual_PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
1966 const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001967 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
1968 // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
1969 // validate_array()
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001970 return validate_array("vkFreeDescriptorSets", "descriptorSetCount", "pDescriptorSets", descriptorSetCount,
1971 &pDescriptorSets, true, true, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001972}
1973
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001974bool StatelessValidation::manual_PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
1975 const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount,
1976 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001977 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001978 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
1979 if (pDescriptorWrites != NULL) {
1980 for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
1981 // descriptorCount must be greater than 0
1982 if (pDescriptorWrites[i].descriptorCount == 0) {
1983 skip |=
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001984 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001985 "VUID-VkWriteDescriptorSet-descriptorCount-arraylength",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001986 "vkUpdateDescriptorSets(): parameter pDescriptorWrites[%d].descriptorCount must be greater than 0.", i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001987 }
1988
1989 // dstSet must be a valid VkDescriptorSet handle
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001990 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001991 ParameterName("pDescriptorWrites[%i].dstSet", ParameterName::IndexVector{i}),
1992 pDescriptorWrites[i].dstSet);
1993
1994 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
1995 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
1996 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
1997 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
1998 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
1999 // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
2000 // VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2001 // pImageInfo must be a pointer to an array of descriptorCount valid VkDescriptorImageInfo structures
2002 if (pDescriptorWrites[i].pImageInfo == nullptr) {
2003 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002004 "VUID-VkWriteDescriptorSet-descriptorType-00322",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002005 "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2006 "VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "
2007 "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002008 "VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pDescriptorWrites[%d].pImageInfo must not be NULL.",
2009 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002010 } else if (pDescriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER) {
2011 // If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
2012 // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout
2013 // members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively
2014 for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount;
2015 ++descriptor_index) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002016 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002017 ParameterName("pDescriptorWrites[%i].pImageInfo[%i].imageView",
2018 ParameterName::IndexVector{i, descriptor_index}),
2019 pDescriptorWrites[i].pImageInfo[descriptor_index].imageView);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002020 skip |= validate_ranged_enum("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002021 ParameterName("pDescriptorWrites[%i].pImageInfo[%i].imageLayout",
2022 ParameterName::IndexVector{i, descriptor_index}),
2023 "VkImageLayout", AllVkImageLayoutEnums,
Dave Houlton413a6782018-05-22 13:01:54 -06002024 pDescriptorWrites[i].pImageInfo[descriptor_index].imageLayout, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002025 }
2026 }
2027 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
2028 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
2029 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
2030 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
2031 // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2032 // VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a
2033 // pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures
2034 if (pDescriptorWrites[i].pBufferInfo == nullptr) {
2035 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002036 "VUID-VkWriteDescriptorSet-descriptorType-00324",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002037 "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2038 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "
2039 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002040 "pDescriptorWrites[%d].pBufferInfo must not be NULL.",
2041 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002042 } else {
2043 for (uint32_t descriptorIndex = 0; descriptorIndex < pDescriptorWrites[i].descriptorCount; ++descriptorIndex) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002044 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002045 ParameterName("pDescriptorWrites[%i].pBufferInfo[%i].buffer",
2046 ParameterName::IndexVector{i, descriptorIndex}),
2047 pDescriptorWrites[i].pBufferInfo[descriptorIndex].buffer);
2048 }
2049 }
2050 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
2051 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
2052 // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
2053 // pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles
2054 if (pDescriptorWrites[i].pTexelBufferView == nullptr) {
2055 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002056 "VUID-VkWriteDescriptorSet-descriptorType-00323",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002057 "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2058 "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002059 "pDescriptorWrites[%d].pTexelBufferView must not be NULL.",
2060 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002061 } else {
2062 for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount;
2063 ++descriptor_index) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002064 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002065 ParameterName("pDescriptorWrites[%i].pTexelBufferView[%i]",
2066 ParameterName::IndexVector{i, descriptor_index}),
2067 pDescriptorWrites[i].pTexelBufferView[descriptor_index]);
2068 }
2069 }
2070 }
2071
2072 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
2073 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002074 VkDeviceSize uniformAlignment = device_limits.minUniformBufferOffsetAlignment;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002075 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
2076 if (pDescriptorWrites[i].pBufferInfo != NULL) {
2077 if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
Mark Lobodzinski88529492018-04-01 10:38:15 -06002078 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002079 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002080 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
2081 "VUID-VkWriteDescriptorSet-descriptorType-00327",
Mark Lobodzinski88529492018-04-01 10:38:15 -06002082 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
2083 ") must be a multiple of device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64 ".",
2084 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002085 }
2086 }
2087 }
2088 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
2089 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002090 VkDeviceSize storageAlignment = device_limits.minStorageBufferOffsetAlignment;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002091 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
2092 if (pDescriptorWrites[i].pBufferInfo != NULL) {
2093 if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
Mark Lobodzinski88529492018-04-01 10:38:15 -06002094 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002095 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002096 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
2097 "VUID-VkWriteDescriptorSet-descriptorType-00328",
Mark Lobodzinski88529492018-04-01 10:38:15 -06002098 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
2099 ") must be a multiple of device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64 ".",
2100 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002101 }
2102 }
2103 }
2104 }
2105 }
2106 }
2107 return skip;
2108}
2109
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002110bool StatelessValidation::manual_PreCallValidateCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
2111 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
2112 return CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_1);
2113}
2114
2115bool StatelessValidation::manual_PreCallValidateCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
2116 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
2117 return CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_2);
2118}
2119
2120bool StatelessValidation::manual_PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
2121 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002122 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002123
2124 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2125 // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
2126 // validate_array()
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002127 skip |= validate_array("vkFreeCommandBuffers", "commandBufferCount", "pCommandBuffers", commandBufferCount,
Dave Houlton413a6782018-05-22 13:01:54 -06002128 &pCommandBuffers, true, true, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002129 return skip;
2130}
2131
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002132bool StatelessValidation::manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002133 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002134 const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
2135
2136 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2137 // TODO: pBeginInfo->pInheritanceInfo must not be NULL if commandBuffer is a secondary command buffer
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002138 skip |= validate_struct_type("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002139 "VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO", pBeginInfo->pInheritanceInfo,
Mark Lobodzinskia16ebc72018-06-15 14:47:39 -06002140 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, false,
2141 "VUID_vkBeginCommandBuffer-pBeginInfo-parameter", "VUID_VkCommandBufferBeginInfo-sType-sType");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002142
2143 if (pBeginInfo->pInheritanceInfo != NULL) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002144 skip |= validate_struct_pnext("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pNext", NULL,
2145 pBeginInfo->pInheritanceInfo->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06002146 "VUID-VkCommandBufferBeginInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002147
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002148 skip |= validate_bool32("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->occlusionQueryEnable",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002149 pBeginInfo->pInheritanceInfo->occlusionQueryEnable);
2150
2151 // TODO: This only needs to be validated when the inherited queries feature is enabled
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002152 // skip |= validate_flags("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->queryFlags",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002153 // "VkQueryControlFlagBits", AllVkQueryControlFlagBits, pBeginInfo->pInheritanceInfo->queryFlags, false);
2154
2155 // TODO: This must be 0 if the pipeline statistics queries feature is not enabled
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002156 skip |= validate_flags("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pipelineStatistics",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002157 "VkQueryPipelineStatisticFlagBits", AllVkQueryPipelineStatisticFlagBits,
Dave Houlton413a6782018-05-22 13:01:54 -06002158 pBeginInfo->pInheritanceInfo->pipelineStatistics, false, false, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002159 }
2160
2161 if (pInfo != NULL) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002162 if ((physical_device_features.inheritedQueries == VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE)) {
2163 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002164 HandleToUint64(commandBuffer), "VUID-VkCommandBufferInheritanceInfo-occlusionQueryEnable-00056",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002165 "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002166 "inheritedQueries.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002167 }
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002168 if ((physical_device_features.inheritedQueries != VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE)) {
2169 skip |= validate_flags("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->queryFlags",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002170 "VkQueryControlFlagBits", AllVkQueryControlFlagBits, pInfo->queryFlags, false, false,
Dave Houlton413a6782018-05-22 13:01:54 -06002171 "VUID-VkCommandBufferInheritanceInfo-queryFlags-00057");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002172 }
2173 }
2174
2175 return skip;
2176}
2177
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002178bool StatelessValidation::manual_PreCallValidateCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
2179 const VkViewport *pViewports) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002180 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002181
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002182 if (!physical_device_features.multiViewport) {
Petr Krausd55e77c2018-01-09 22:09:25 +01002183 if (firstViewport != 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002184 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002185 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-firstViewport-01224",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002186 "vkCmdSetViewport: The multiViewport feature is disabled, but firstViewport (=%" PRIu32 ") is not 0.",
2187 firstViewport);
Petr Krausd55e77c2018-01-09 22:09:25 +01002188 }
2189 if (viewportCount > 1) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002190 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002191 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-viewportCount-01225",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002192 "vkCmdSetViewport: The multiViewport feature is disabled, but viewportCount (=%" PRIu32 ") is not 1.",
2193 viewportCount);
Petr Krausd55e77c2018-01-09 22:09:25 +01002194 }
2195 } else { // multiViewport enabled
Petr Kraus7dfeed12018-02-27 20:51:20 +01002196 const uint64_t sum = static_cast<uint64_t>(firstViewport) + static_cast<uint64_t>(viewportCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002197 if (sum > device_limits.maxViewports) {
2198 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002199 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-firstViewport-01223",
Petr Krausd55e77c2018-01-09 22:09:25 +01002200 "vkCmdSetViewport: firstViewport + viewportCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002201 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002202 firstViewport, viewportCount, sum, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002203 }
2204 }
Petr Krausb3fcdb42018-01-09 22:09:09 +01002205
2206 if (pViewports) {
2207 for (uint32_t viewport_i = 0; viewport_i < viewportCount; ++viewport_i) {
2208 const auto &viewport = pViewports[viewport_i]; // will crash on invalid ptr
2209 const char fn_name[] = "vkCmdSetViewport";
2210 const std::string param_name = "pViewports[" + std::to_string(viewport_i) + "]";
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002211 skip |= manual_PreCallValidateViewport(viewport, fn_name, param_name.c_str(),
Petr Krausb3fcdb42018-01-09 22:09:09 +01002212 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer));
2213 }
2214 }
2215
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002216 return skip;
2217}
2218
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002219bool StatelessValidation::manual_PreCallValidateCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
2220 const VkRect2D *pScissors) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002221 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002222
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002223 if (!physical_device_features.multiViewport) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002224 if (firstScissor != 0) {
Petr Kraus6260f0a2018-02-27 21:15:55 +01002225 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002226 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-firstScissor-00593",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002227 "vkCmdSetScissor: The multiViewport feature is disabled, but firstScissor (=%" PRIu32 ") is not 0.",
2228 firstScissor);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002229 }
2230 if (scissorCount > 1) {
2231 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002232 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-scissorCount-00594",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002233 "vkCmdSetScissor: The multiViewport feature is disabled, but scissorCount (=%" PRIu32 ") is not 1.",
2234 scissorCount);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002235 }
2236 } else { // multiViewport enabled
2237 const uint64_t sum = static_cast<uint64_t>(firstScissor) + static_cast<uint64_t>(scissorCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002238 if (sum > device_limits.maxViewports) {
2239 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002240 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-firstScissor-00592",
Petr Kraus6260f0a2018-02-27 21:15:55 +01002241 "vkCmdSetScissor: firstScissor + scissorCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002242 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002243 firstScissor, scissorCount, sum, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002244 }
2245 }
2246
Petr Kraus6260f0a2018-02-27 21:15:55 +01002247 if (pScissors) {
2248 for (uint32_t scissor_i = 0; scissor_i < scissorCount; ++scissor_i) {
2249 const auto &scissor = pScissors[scissor_i]; // will crash on invalid ptr
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002250
Petr Kraus6260f0a2018-02-27 21:15:55 +01002251 if (scissor.offset.x < 0) {
2252 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002253 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-x-00595",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002254 "vkCmdSetScissor: pScissors[%" PRIu32 "].offset.x (=%" PRIi32 ") is negative.", scissor_i,
2255 scissor.offset.x);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002256 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002257
Petr Kraus6260f0a2018-02-27 21:15:55 +01002258 if (scissor.offset.y < 0) {
2259 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002260 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-x-00595",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002261 "vkCmdSetScissor: pScissors[%" PRIu32 "].offset.y (=%" PRIi32 ") is negative.", scissor_i,
2262 scissor.offset.y);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002263 }
2264
2265 const int64_t x_sum = static_cast<int64_t>(scissor.offset.x) + static_cast<int64_t>(scissor.extent.width);
2266 if (x_sum > INT32_MAX) {
2267 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002268 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-offset-00596",
Petr Kraus6260f0a2018-02-27 21:15:55 +01002269 "vkCmdSetScissor: offset.x + extent.width (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002270 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2271 scissor.offset.x, scissor.extent.width, x_sum, scissor_i);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002272 }
2273
2274 const int64_t y_sum = static_cast<int64_t>(scissor.offset.y) + static_cast<int64_t>(scissor.extent.height);
2275 if (y_sum > INT32_MAX) {
2276 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002277 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-offset-00597",
Petr Kraus6260f0a2018-02-27 21:15:55 +01002278 "vkCmdSetScissor: offset.y + extent.height (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002279 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2280 scissor.offset.y, scissor.extent.height, y_sum, scissor_i);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002281 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002282 }
2283 }
Petr Kraus6260f0a2018-02-27 21:15:55 +01002284
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002285 return skip;
2286}
2287
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002288bool StatelessValidation::manual_PreCallValidateCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
Petr Kraus299ba622017-11-24 03:09:03 +01002289 bool skip = false;
Petr Kraus299ba622017-11-24 03:09:03 +01002290
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002291 if (!physical_device_features.wideLines && (lineWidth != 1.0f)) {
Petr Kraus299ba622017-11-24 03:09:03 +01002292 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002293 HandleToUint64(commandBuffer), "VUID-vkCmdSetLineWidth-lineWidth-00788",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002294 "VkPhysicalDeviceFeatures::wideLines is disabled, but lineWidth (=%f) is not 1.0.", lineWidth);
Petr Kraus299ba622017-11-24 03:09:03 +01002295 }
2296
2297 return skip;
2298}
2299
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002300bool StatelessValidation::manual_PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
2301 uint32_t firstVertex, uint32_t firstInstance) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002302 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002303 if (vertexCount == 0) {
2304 // TODO: Verify against Valid Usage section. I don't see a non-zero vertexCount listed, may need to add that and make
2305 // this an error or leave as is.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002306 skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002307 kVUID_PVError_RequiredParameter, "vkCmdDraw parameter, uint32_t vertexCount, is 0");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002308 }
2309
2310 if (instanceCount == 0) {
2311 // TODO: Verify against Valid Usage section. I don't see a non-zero instanceCount listed, may need to add that and make
2312 // this an error or leave as is.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002313 skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002314 kVUID_PVError_RequiredParameter, "vkCmdDraw parameter, uint32_t instanceCount, is 0");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002315 }
2316 return skip;
2317}
2318
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002319bool StatelessValidation::manual_PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
2320 uint32_t stride) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002321 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002322
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002323 if (!physical_device_features.multiDrawIndirect && ((count > 1))) {
2324 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002325 kVUID_PVError_DeviceFeature,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002326 "CmdDrawIndirect(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d", count);
2327 }
2328 return skip;
2329}
2330
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002331bool StatelessValidation::manual_PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
2332 uint32_t count, uint32_t stride) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002333 bool skip = false;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002334 if (!physical_device_features.multiDrawIndirect && ((count > 1))) {
Dave Houlton413a6782018-05-22 13:01:54 -06002335 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002336 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002337 kVUID_PVError_DeviceFeature,
2338 "CmdDrawIndexedIndirect(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d", count);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002339 }
2340 return skip;
2341}
2342
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002343bool StatelessValidation::manual_PreCallValidateCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
2344 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
2345 const VkImageCopy *pRegions) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002346 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002347
Dave Houltonf5217612018-02-02 16:18:52 -07002348 VkImageAspectFlags legal_aspect_flags =
2349 VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002350 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002351 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2352 }
2353
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002354 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002355 if ((pRegions->srcSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002356 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002357 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002358 "VUID-VkImageSubresourceLayers-aspectMask-parameter",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002359 "vkCmdCopyImage() parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002360 }
Dave Houltonf5217612018-02-02 16:18:52 -07002361 if ((pRegions->dstSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002362 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002363 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002364 "VUID-VkImageSubresourceLayers-aspectMask-parameter",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002365 "vkCmdCopyImage() parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002366 }
2367 }
2368 return skip;
2369}
2370
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002371bool StatelessValidation::manual_PreCallValidateCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
2372 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
2373 const VkImageBlit *pRegions, VkFilter filter) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002374 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002375
Dave Houltonf5217612018-02-02 16:18:52 -07002376 VkImageAspectFlags legal_aspect_flags =
2377 VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002378 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002379 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2380 }
2381
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002382 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002383 if ((pRegions->srcSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002384 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002385 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002386 kVUID_PVError_UnrecognizedValue,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002387 "vkCmdBlitImage() parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator");
2388 }
Dave Houltonf5217612018-02-02 16:18:52 -07002389 if ((pRegions->dstSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002390 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002391 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002392 kVUID_PVError_UnrecognizedValue,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002393 "vkCmdBlitImage() parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator");
2394 }
2395 }
2396 return skip;
2397}
2398
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002399bool StatelessValidation::manual_PreCallValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
2400 VkImageLayout dstImageLayout, uint32_t regionCount,
2401 const VkBufferImageCopy *pRegions) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002402 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002403
Dave Houltonf5217612018-02-02 16:18:52 -07002404 VkImageAspectFlags legal_aspect_flags =
2405 VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002406 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002407 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2408 }
2409
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002410 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002411 if ((pRegions->imageSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002412 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002413 kVUID_PVError_UnrecognizedValue,
Dave Houltona9df0ce2018-02-07 10:51:23 -07002414 "vkCmdCopyBufferToImage() parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an "
2415 "unrecognized enumerator");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002416 }
2417 }
2418 return skip;
2419}
2420
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002421bool StatelessValidation::manual_PreCallValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
2422 VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002423 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002424
Dave Houltonf5217612018-02-02 16:18:52 -07002425 VkImageAspectFlags legal_aspect_flags =
2426 VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002427 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002428 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2429 }
2430
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002431 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002432 if ((pRegions->imageSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002433 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002434 kVUID_PVError_UnrecognizedValue,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002435 "vkCmdCopyImageToBuffer parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an unrecognized "
2436 "enumerator");
2437 }
2438 }
2439 return skip;
2440}
2441
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002442bool StatelessValidation::manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
2443 VkDeviceSize dataSize, const void *pData) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002444 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002445
2446 if (dstOffset & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002447 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002448 "VUID-vkCmdUpdateBuffer-dstOffset-00036",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002449 "vkCmdUpdateBuffer() parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
2450 dstOffset);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002451 }
2452
2453 if ((dataSize <= 0) || (dataSize > 65536)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002454 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002455 "VUID-vkCmdUpdateBuffer-dataSize-00037",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002456 "vkCmdUpdateBuffer() parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002457 "), must be greater than zero and less than or equal to 65536.",
2458 dataSize);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002459 } else if (dataSize & 3) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002460 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002461 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002462 "VUID-vkCmdUpdateBuffer-dataSize-00038",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002463 "vkCmdUpdateBuffer() parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 "), is not a multiple of 4.", dataSize);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002464 }
2465 return skip;
2466}
2467
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002468bool StatelessValidation::manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
2469 VkDeviceSize size, uint32_t data) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002470 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002471
2472 if (dstOffset & 3) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002473 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002474 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002475 "VUID-vkCmdFillBuffer-dstOffset-00025",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002476 "vkCmdFillBuffer() parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4.", dstOffset);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002477 }
2478
2479 if (size != VK_WHOLE_SIZE) {
2480 if (size <= 0) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002481 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002482 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002483 "VUID-vkCmdFillBuffer-size-00026",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002484 "vkCmdFillBuffer() parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), must be greater than zero.", size);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002485 } else if (size & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002486 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002487 "VUID-vkCmdFillBuffer-size-00028",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002488 "vkCmdFillBuffer() parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), is not a multiple of 4.", size);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002489 }
2490 }
2491 return skip;
2492}
2493
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002494bool StatelessValidation::manual_PreCallValidateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
2495 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002496 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002497
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002498 const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, VK_NULL_HANDLE,
Petr Krause5c37652018-01-05 04:05:12 +01002499 "vkCreateSwapchainKHR"};
2500
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002501 if (pCreateInfo != nullptr) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002502 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2503 if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
2504 // If imageSharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
2505 if (pCreateInfo->queueFamilyIndexCount <= 1) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06002506 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002507 "VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002508 "vkCreateSwapchainKHR(): if pCreateInfo->imageSharingMode is VK_SHARING_MODE_CONCURRENT, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002509 "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002510 }
2511
2512 // If imageSharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
2513 // queueFamilyIndexCount uint32_t values
2514 if (pCreateInfo->pQueueFamilyIndices == nullptr) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06002515 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002516 "VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01277",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002517 "vkCreateSwapchainKHR(): if pCreateInfo->imageSharingMode is VK_SHARING_MODE_CONCURRENT, "
2518 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002519 "pCreateInfo->queueFamilyIndexCount uint32_t values.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002520 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002521 skip |= ValidateQueueFamilies(pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices,
Dave Houlton413a6782018-05-22 13:01:54 -06002522 "vkCreateSwapchainKHR", "pCreateInfo->pQueueFamilyIndices",
2523 kVUID_PVError_InvalidUsage, kVUID_PVError_InvalidUsage, false);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002524 }
2525 }
2526
Dave Houlton413a6782018-05-22 13:01:54 -06002527 skip |= ValidateGreaterThanZero(pCreateInfo->imageArrayLayers, "pCreateInfo->imageArrayLayers",
2528 "VUID-VkSwapchainCreateInfoKHR-imageArrayLayers-01275", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002529 }
2530
2531 return skip;
2532}
2533
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002534bool StatelessValidation::manual_PreCallValidateQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002535 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002536
2537 if (pPresentInfo && pPresentInfo->pNext) {
John Zulaufde972ac2017-10-26 12:07:05 -06002538 const auto *present_regions = lvl_find_in_chain<VkPresentRegionsKHR>(pPresentInfo->pNext);
2539 if (present_regions) {
2540 // TODO: This and all other pNext extension dependencies should be added to code-generation
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002541 skip |= require_device_extension(device_extensions.vk_khr_incremental_present, "vkQueuePresentKHR",
John Zulaufde972ac2017-10-26 12:07:05 -06002542 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
2543 if (present_regions->swapchainCount != pPresentInfo->swapchainCount) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002544 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002545 kVUID_PVError_InvalidUsage,
Dave Houltona9df0ce2018-02-07 10:51:23 -07002546 "QueuePresentKHR(): pPresentInfo->swapchainCount has a value of %i but VkPresentRegionsKHR "
2547 "extension swapchainCount is %i. These values must be equal.",
John Zulaufde972ac2017-10-26 12:07:05 -06002548 pPresentInfo->swapchainCount, present_regions->swapchainCount);
2549 }
Dave Houlton413a6782018-05-22 13:01:54 -06002550 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002551 validate_struct_pnext("QueuePresentKHR", "pCreateInfo->pNext->pNext", NULL,
2552 present_regions->pNext, 0, NULL, GeneratedVulkanHeaderVersion, "VUID-VkPresentInfoKHR-pNext-pNext");
2553 skip |= validate_array("QueuePresentKHR", "pCreateInfo->pNext->swapchainCount", "pCreateInfo->pNext->pRegions", present_regions->swapchainCount, &present_regions->pRegions, true, false, kVUIDUndefined, kVUIDUndefined);
John Zulaufde972ac2017-10-26 12:07:05 -06002554 for (uint32_t i = 0; i < present_regions->swapchainCount; ++i) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002555 skip |= validate_array("QueuePresentKHR", "pCreateInfo->pNext->pRegions[].rectangleCount",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002556 "pCreateInfo->pNext->pRegions[].pRectangles", present_regions->pRegions[i].rectangleCount,
Dave Houlton413a6782018-05-22 13:01:54 -06002557 &present_regions->pRegions[i].pRectangles, true, false, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002558 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002559 }
2560 }
2561
2562 return skip;
2563}
2564
2565#ifdef VK_USE_PLATFORM_WIN32_KHR
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002566bool StatelessValidation::manual_PreCallValidateCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
2567 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002568 bool skip = false;
2569
2570 if (pCreateInfo->hwnd == nullptr) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002571 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002572 "VUID-VkWin32SurfaceCreateInfoKHR-hwnd-01308",
2573 "vkCreateWin32SurfaceKHR(): hwnd must be a valid Win32 HWND but hwnd is NULL.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002574 }
2575
2576 return skip;
2577}
2578#endif // VK_USE_PLATFORM_WIN32_KHR
2579
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002580bool StatelessValidation::manual_PreCallValidateDebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002581 if (pNameInfo->pObjectName) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002582 report_data->debugObjectNameMap->insert(
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002583 std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->object, pNameInfo->pObjectName));
2584 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002585 report_data->debugObjectNameMap->erase(pNameInfo->object);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002586 }
2587 return false;
2588}
2589
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002590bool StatelessValidation::manual_PreCallValidateCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
2591 const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool) {
Petr Krausc8655be2017-09-27 18:56:51 +02002592 bool skip = false;
2593
2594 if (pCreateInfo) {
2595 if (pCreateInfo->maxSets <= 0) {
Dave Houlton413a6782018-05-22 13:01:54 -06002596 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002597 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002598 VK_NULL_HANDLE, "VUID-VkDescriptorPoolCreateInfo-maxSets-00301",
2599 "vkCreateDescriptorPool(): pCreateInfo->maxSets is not greater than 0.");
Petr Krausc8655be2017-09-27 18:56:51 +02002600 }
2601
2602 if (pCreateInfo->pPoolSizes) {
2603 for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; ++i) {
2604 if (pCreateInfo->pPoolSizes[i].descriptorCount <= 0) {
2605 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002606 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002607 VK_NULL_HANDLE, "VUID-VkDescriptorPoolSize-descriptorCount-00302",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002608 "vkCreateDescriptorPool(): pCreateInfo->pPoolSizes[%" PRIu32 "].descriptorCount is not greater than 0.", i);
Petr Krausc8655be2017-09-27 18:56:51 +02002609 }
Jeff Bolze54ae892018-09-08 12:16:29 -05002610 if (pCreateInfo->pPoolSizes[i].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
2611 (pCreateInfo->pPoolSizes[i].descriptorCount % 4) != 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002612 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
Dave Houlton142c4cb2018-10-17 15:04:41 -06002613 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, VK_NULL_HANDLE,
2614 "VUID-VkDescriptorPoolSize-type-02218",
2615 "vkCreateDescriptorPool(): pCreateInfo->pPoolSizes[%" PRIu32
2616 "].type is VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT "
2617 " and pCreateInfo->pPoolSizes[%" PRIu32 "].descriptorCount is not a multiple of 4.",
2618 i, i);
Jeff Bolze54ae892018-09-08 12:16:29 -05002619 }
Petr Krausc8655be2017-09-27 18:56:51 +02002620 }
2621 }
2622 }
2623
2624 return skip;
2625}
2626
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002627bool StatelessValidation::manual_PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY,
2628 uint32_t groupCountZ) {
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002629 bool skip = false;
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002630
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002631 if (groupCountX > device_limits.maxComputeWorkGroupCount[0]) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002632 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002633 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002634 HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountX-00386",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002635 "vkCmdDispatch(): groupCountX (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002636 groupCountX, device_limits.maxComputeWorkGroupCount[0]);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002637 }
2638
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002639 if (groupCountY > device_limits.maxComputeWorkGroupCount[1]) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002640 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002641 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002642 HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountY-00387",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002643 "vkCmdDispatch(): groupCountY (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002644 groupCountY, device_limits.maxComputeWorkGroupCount[1]);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002645 }
2646
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002647 if (groupCountZ > device_limits.maxComputeWorkGroupCount[2]) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002648 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002649 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002650 HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountZ-00388",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002651 "vkCmdDispatch(): groupCountZ (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002652 groupCountZ, device_limits.maxComputeWorkGroupCount[2]);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002653 }
2654
2655 return skip;
2656}
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002657
2658bool StatelessValidation::manual_PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
John Zulaufa999d1b2018-11-29 13:38:40 -07002659 bool skip = false;
John Zulaufa999d1b2018-11-29 13:38:40 -07002660
2661 if ((offset % 4) != 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002662 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
John Zulaufa999d1b2018-11-29 13:38:40 -07002663 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchIndirect-offset-00406",
2664 "vkCmdDispatchIndirect(): offset (%" PRIu64 ") must be a multiple of 4.", offset);
2665 }
2666 return skip;
2667}
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002668
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002669bool StatelessValidation::manual_PreCallValidateCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
2670 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
2671 uint32_t groupCountZ) {
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002672 bool skip = false;
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002673
2674 // Paired if {} else if {} tests used to avoid any possible uint underflow
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002675 uint32_t limit = device_limits.maxComputeWorkGroupCount[0];
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002676 if (baseGroupX >= limit) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002677 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002678 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupX-00421",
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002679 "vkCmdDispatch(): baseGroupX (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002680 ") equals or exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
2681 baseGroupX, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002682 } else if (groupCountX > (limit - baseGroupX)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002683 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002684 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountX-00424",
Mark Lobodzinskibf973a12018-03-01 08:50:21 -07002685 "vkCmdDispatchBaseKHR(): baseGroupX (%" PRIu32 ") + groupCountX (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002686 ") exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
2687 baseGroupX, groupCountX, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002688 }
2689
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002690 limit = device_limits.maxComputeWorkGroupCount[1];
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002691 if (baseGroupY >= limit) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002692 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002693 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupX-00422",
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002694 "vkCmdDispatch(): baseGroupY (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002695 ") equals or exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
2696 baseGroupY, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002697 } else if (groupCountY > (limit - baseGroupY)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002698 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002699 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountY-00425",
Mark Lobodzinskibf973a12018-03-01 08:50:21 -07002700 "vkCmdDispatchBaseKHR(): baseGroupY (%" PRIu32 ") + groupCountY (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002701 ") exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
2702 baseGroupY, groupCountY, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002703 }
2704
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002705 limit = device_limits.maxComputeWorkGroupCount[2];
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002706 if (baseGroupZ >= limit) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002707 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002708 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupZ-00423",
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002709 "vkCmdDispatch(): baseGroupZ (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002710 ") equals or exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
2711 baseGroupZ, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002712 } else if (groupCountZ > (limit - baseGroupZ)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002713 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06002714 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountZ-00426",
Mark Lobodzinskibf973a12018-03-01 08:50:21 -07002715 "vkCmdDispatchBaseKHR(): baseGroupZ (%" PRIu32 ") + groupCountZ (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002716 ") exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
2717 baseGroupZ, groupCountZ, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002718 }
2719
2720 return skip;
2721}
2722
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002723bool StatelessValidation::manual_PreCallValidateCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
2724 uint32_t exclusiveScissorCount, const VkRect2D *pExclusiveScissors) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05002725 bool skip = false;
2726
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002727 if (!physical_device_features.multiViewport) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05002728 if (firstExclusiveScissor != 0) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002729 skip |=
2730 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2731 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035",
2732 "vkCmdSetExclusiveScissorNV: The multiViewport feature is disabled, but firstExclusiveScissor (=%" PRIu32
2733 ") is not 0.",
2734 firstExclusiveScissor);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002735 }
2736 if (exclusiveScissorCount > 1) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002737 skip |=
2738 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2739 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036",
2740 "vkCmdSetExclusiveScissorNV: The multiViewport feature is disabled, but exclusiveScissorCount (=%" PRIu32
2741 ") is not 1.",
2742 exclusiveScissorCount);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002743 }
2744 } else { // multiViewport enabled
2745 const uint64_t sum = static_cast<uint64_t>(firstExclusiveScissor) + static_cast<uint64_t>(exclusiveScissorCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002746 if (sum > device_limits.maxViewports) {
2747 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Jeff Bolz3e71f782018-08-29 23:15:45 -05002748 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02034",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002749 "vkCmdSetExclusiveScissorNV: firstExclusiveScissor + exclusiveScissorCount (=%" PRIu32 " + %" PRIu32
2750 " = %" PRIu64 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002751 firstExclusiveScissor, exclusiveScissorCount, sum, device_limits.maxViewports);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002752 }
2753 }
2754
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002755 if (firstExclusiveScissor >= device_limits.maxViewports) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05002756 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2757 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02033",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002758 "vkCmdSetExclusiveScissorNV: firstExclusiveScissor (=%" PRIu32 ") must be less than maxViewports (=%" PRIu32
2759 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002760 firstExclusiveScissor, device_limits.maxViewports);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002761 }
2762
2763 if (pExclusiveScissors) {
2764 for (uint32_t scissor_i = 0; scissor_i < exclusiveScissorCount; ++scissor_i) {
2765 const auto &scissor = pExclusiveScissors[scissor_i]; // will crash on invalid ptr
2766
2767 if (scissor.offset.x < 0) {
2768 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2769 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-x-02037",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002770 "vkCmdSetExclusiveScissorNV: pScissors[%" PRIu32 "].offset.x (=%" PRIi32 ") is negative.",
2771 scissor_i, scissor.offset.x);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002772 }
2773
2774 if (scissor.offset.y < 0) {
2775 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2776 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-x-02037",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002777 "vkCmdSetExclusiveScissorNV: pScissors[%" PRIu32 "].offset.y (=%" PRIi32 ") is negative.",
2778 scissor_i, scissor.offset.y);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002779 }
2780
2781 const int64_t x_sum = static_cast<int64_t>(scissor.offset.x) + static_cast<int64_t>(scissor.extent.width);
2782 if (x_sum > INT32_MAX) {
2783 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2784 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-offset-02038",
2785 "vkCmdSetExclusiveScissorNV: offset.x + extent.width (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
2786 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2787 scissor.offset.x, scissor.extent.width, x_sum, scissor_i);
2788 }
2789
2790 const int64_t y_sum = static_cast<int64_t>(scissor.offset.y) + static_cast<int64_t>(scissor.extent.height);
2791 if (y_sum > INT32_MAX) {
2792 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2793 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-offset-02039",
2794 "vkCmdSetExclusiveScissorNV: offset.y + extent.height (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
2795 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2796 scissor.offset.y, scissor.extent.height, y_sum, scissor_i);
2797 }
2798 }
2799 }
2800
2801 return skip;
2802}
2803
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002804bool StatelessValidation::manual_PreCallValidateCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2805 uint32_t viewportCount,
2806 const VkShadingRatePaletteNV *pShadingRatePalettes) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002807 bool skip = false;
2808
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002809 if (!physical_device_features.multiViewport) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002810 if (firstViewport != 0) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002811 skip |=
2812 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2813 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068",
2814 "vkCmdSetViewportShadingRatePaletteNV: The multiViewport feature is disabled, but firstViewport (=%" PRIu32
2815 ") is not 0.",
2816 firstViewport);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002817 }
2818 if (viewportCount > 1) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002819 skip |=
2820 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2821 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069",
2822 "vkCmdSetViewportShadingRatePaletteNV: The multiViewport feature is disabled, but viewportCount (=%" PRIu32
2823 ") is not 1.",
2824 viewportCount);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002825 }
2826 }
2827
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002828 if (firstViewport >= device_limits.maxViewports) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002829 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2830 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02066",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002831 "vkCmdSetViewportShadingRatePaletteNV: firstViewport (=%" PRIu32
2832 ") must be less than maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002833 firstViewport, device_limits.maxViewports);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002834 }
2835
2836 const uint64_t sum = static_cast<uint64_t>(firstViewport) + static_cast<uint64_t>(viewportCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002837 if (sum > device_limits.maxViewports) {
2838 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Jeff Bolz9af91c52018-09-01 21:53:57 -05002839 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067",
2840 "vkCmdSetViewportShadingRatePaletteNV: firstViewport + viewportCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
2841 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002842 firstViewport, viewportCount, sum, device_limits.maxViewports);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002843 }
2844
2845 return skip;
2846}
2847
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002848bool StatelessValidation::manual_PreCallValidateCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType,
2849 uint32_t customSampleOrderCount,
2850 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002851 bool skip = false;
2852
Dave Houlton142c4cb2018-10-17 15:04:41 -06002853 if (sampleOrderType != VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV && customSampleOrderCount != 0) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002854 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2855 HandleToUint64(commandBuffer), "VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081",
2856 "vkCmdSetCoarseSampleOrderNV: If sampleOrderType is not VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, "
2857 "customSampleOrderCount must be 0.");
2858 }
2859
2860 for (uint32_t order_i = 0; order_i < customSampleOrderCount; ++order_i) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002861 skip |= ValidateCoarseSampleOrderCustomNV(&pCustomSampleOrders[order_i]);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002862 }
2863
2864 return skip;
2865}
2866
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002867bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002868 bool skip = false;
2869
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002870 if (taskCount > phys_dev_ext_props.mesh_shader_props.maxDrawMeshTasksCount) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002871 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002872 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton142c4cb2018-10-17 15:04:41 -06002873 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksNV-taskCount-02119",
2874 "vkCmdDrawMeshTasksNV() parameter, uint32_t taskCount (0x%" PRIxLEAST32
2875 "), must be less than or equal to VkPhysicalDeviceMeshShaderPropertiesNV::maxDrawMeshTasksCount (0x%" PRIxLEAST32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002876 taskCount, phys_dev_ext_props.mesh_shader_props.maxDrawMeshTasksCount);
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002877 }
2878
2879 return skip;
2880}
2881
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002882bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
2883 uint32_t drawCount, uint32_t stride) {
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002884 bool skip = false;
2885
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002886 if (offset & 3) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002887 skip |= log_msg(
2888 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2889 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-offset-02145",
2890 "vkCmdDrawMeshTasksIndirectNV() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.", offset);
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002891 }
2892
2893 if (drawCount > 1 && ((stride & 3) || stride < sizeof(VkDrawMeshTasksIndirectCommandNV))) {
2894 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2895 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146",
2896 "vkCmdDrawMeshTasksIndirectNV() parameter, uint32_t stride (0x%" PRIxLEAST32
2897 "), is not a multiple of 4 or smaller than sizeof (VkDrawMeshTasksIndirectCommandNV).",
2898 stride);
2899 }
2900
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002901 if (!physical_device_features.multiDrawIndirect && ((drawCount > 1))) {
Jeff Bolzb574c342018-11-08 15:36:57 -06002902 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2903 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02147",
2904 "vkCmdDrawMeshTasksIndirectNV(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d",
2905 drawCount);
2906 }
2907
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002908 return skip;
2909}
2910
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002911bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
2912 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
2913 uint32_t maxDrawCount, uint32_t stride) {
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002914 bool skip = false;
2915
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002916 if (offset & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002917 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002918 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-offset-02180",
2919 "vkCmdDrawMeshTasksIndirectCountNV() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
2920 "), is not a multiple of 4.",
2921 offset);
2922 }
2923
2924 if (countBufferOffset & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002925 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002926 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBufferOffset-02181",
2927 "vkCmdDrawMeshTasksIndirectCountNV() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
2928 "), is not a multiple of 4.",
2929 countBufferOffset);
2930 }
2931
2932 if ((stride & 3) || stride < sizeof(VkDrawMeshTasksIndirectCommandNV)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002933 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002934 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-stride-02182",
2935 "vkCmdDrawMeshTasksIndirectCountNV() parameter, uint32_t stride (0x%" PRIxLEAST32
2936 "), is not a multiple of 4 or smaller than sizeof (VkDrawMeshTasksIndirectCommandNV).",
2937 stride);
2938 }
2939
2940 return skip;
2941}
2942
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002943bool StatelessValidation::manual_PreCallValidateCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
2944 const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) {
2945 return ValidateDeviceQueueFamily(pCreateInfo->queueFamilyIndex, "vkCreateCommandPool",
2946 "pCreateInfo->queueFamilyIndex", "VUID-vkCreateCommandPool-queueFamilyIndex-01937");
2947}
2948
2949bool StatelessValidation::manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
2950 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
2951 bool skip = false;
2952
2953 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2954 if (pCreateInfo != nullptr) {
2955 // If queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, pipelineStatistics must be a valid combination of
2956 // VkQueryPipelineStatisticFlagBits values
2957 if ((pCreateInfo->queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) && (pCreateInfo->pipelineStatistics != 0) &&
2958 ((pCreateInfo->pipelineStatistics & (~AllVkQueryPipelineStatisticFlagBits)) != 0)) {
2959 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2960 "VUID-VkQueryPoolCreateInfo-queryType-00792",
2961 "vkCreateQueryPool(): if pCreateInfo->queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, "
2962 "pCreateInfo->pipelineStatistics must be a valid combination of VkQueryPipelineStatisticFlagBits "
2963 "values.");
2964 }
Mark Lobodzinskib7a26382018-07-02 13:14:26 -06002965 }
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002966 return skip;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002967}
2968
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002969bool StatelessValidation::manual_PreCallValidateEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
2970 uint32_t *pPropertyCount, VkExtensionProperties *pProperties) {
2971 return validate_array("vkEnumerateDeviceExtensionProperties", "pPropertyCount", "pProperties", pPropertyCount,
2972 &pProperties, true, false, false, kVUIDUndefined,
2973 "VUID-vkEnumerateDeviceExtensionProperties-pProperties-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002974}
2975
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002976void StatelessValidation::PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
2977 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
2978 RecordRenderPass(*pRenderPass, pCreateInfo);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002979}
2980
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002981void StatelessValidation::PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
2982 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
2983 // Track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments)
2984 RecordRenderPass(*pRenderPass, pCreateInfo);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002985}
2986
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002987void StatelessValidation::PostCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
2988 // Track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments)
2989 renderpasses_states.erase(renderPass);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002990}
2991