blob: 97f7fe03e9b002800290f1adb4847ec95b1eb40d [file] [log] [blame]
Shahbaz Youssefi6be11412019-01-10 15:29:30 -05001/* Copyright (c) 2015-2019 The Khronos Group Inc.
2 * Copyright (c) 2015-2019 Valve Corporation
3 * Copyright (c) 2015-2019 LunarG, Inc.
4 * Copyright (C) 2015-2019 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
Shahbaz Youssefi6be11412019-01-10 15:29:30 -050023
24#include <math.h>
25
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070026#include "chassis.h"
27#include "stateless_validation.h"
Tobias Hectord942eb92018-10-22 15:18:56 +010028
Mark Lobodzinskid4950072017-08-01 13:02:20 -060029static const int MaxParamCheckerStringLength = 256;
30
John Zulauf71968502017-10-26 13:51:15 -060031template <typename T>
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070032inline bool in_inclusive_range(const T &value, const T &min, const T &max) {
John Zulauf71968502017-10-26 13:51:15 -060033 // Using only < for generality and || for early abort
34 return !((value < min) || (max < value));
35}
36
Mark Lobodzinskibf599b92018-12-31 12:15:55 -070037bool StatelessValidation::validate_string(const char *apiName, const ParameterName &stringName, const std::string &vuid,
38 const char *validateString) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -060039 bool skip = false;
40
41 VkStringErrorFlags result = vk_string_validate(MaxParamCheckerStringLength, validateString);
42
43 if (result == VK_STRING_ERROR_NONE) {
44 return skip;
45 } else if (result & VK_STRING_ERROR_LENGTH) {
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 exceeds max length %d", apiName, stringName.get_name().c_str(), MaxParamCheckerStringLength);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060048 } else if (result & VK_STRING_ERROR_BAD_DATA) {
Mark Lobodzinskiebee3552018-05-29 09:55:54 -060049 skip = log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
50 "%s: string %s contains invalid characters or is badly formed", apiName, stringName.get_name().c_str());
Mark Lobodzinskid4950072017-08-01 13:02:20 -060051 }
52 return skip;
53}
54
Mark Lobodzinskibf599b92018-12-31 12:15:55 -070055bool StatelessValidation::ValidateDeviceQueueFamily(uint32_t queue_family, const char *cmd_name, const char *parameter_name,
56 const std::string &error_code, bool optional = false) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -060057 bool skip = false;
58
Mark Lobodzinskid4950072017-08-01 13:02:20 -060059 if (!optional && queue_family == VK_QUEUE_FAMILY_IGNORED) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -070060 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, HandleToUint64(device),
61 error_code,
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060062 "%s: %s is VK_QUEUE_FAMILY_IGNORED, but it is required to provide a valid queue family index value.",
63 cmd_name, parameter_name);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070064 } else if (queueFamilyIndexMap.find(queue_family) == queueFamilyIndexMap.end()) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -070065 skip |= log_msg(
66 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, HandleToUint64(device), error_code,
67 "%s: %s (= %" PRIu32
68 ") is not one of the queue families given via VkDeviceQueueCreateInfo structures when the device was created.",
69 cmd_name, parameter_name, queue_family);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060070 }
71
72 return skip;
73}
74
Mark Lobodzinskibf599b92018-12-31 12:15:55 -070075bool StatelessValidation::ValidateQueueFamilies(uint32_t queue_family_count, const uint32_t *queue_families, const char *cmd_name,
76 const char *array_parameter_name, const std::string &unique_error_code,
77 const std::string &valid_error_code, bool optional = false) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -060078 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -060079 if (queue_families) {
80 std::unordered_set<uint32_t> set;
81 for (uint32_t i = 0; i < queue_family_count; ++i) {
82 std::string parameter_name = std::string(array_parameter_name) + "[" + std::to_string(i) + "]";
83
84 if (set.count(queue_families[i])) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070085 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
86 HandleToUint64(device), "VUID-VkDeviceCreateInfo-queueFamilyIndex-00372",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -060087 "%s: %s (=%" PRIu32 ") is not unique within %s array.", cmd_name, parameter_name.c_str(),
88 queue_families[i], array_parameter_name);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060089 } else {
90 set.insert(queue_families[i]);
Mark Lobodzinskibf599b92018-12-31 12:15:55 -070091 skip |= ValidateDeviceQueueFamily(queue_families[i], cmd_name, parameter_name.c_str(), valid_error_code, optional);
Mark Lobodzinskid4950072017-08-01 13:02:20 -060092 }
93 }
94 }
95 return skip;
96}
97
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070098bool StatelessValidation::validate_api_version(uint32_t api_version, uint32_t effective_api_version) {
John Zulauf620755c2018-04-16 11:00:43 -060099 bool skip = false;
100 uint32_t api_version_nopatch = VK_MAKE_VERSION(VK_VERSION_MAJOR(api_version), VK_VERSION_MINOR(api_version), 0);
101 if (api_version_nopatch != effective_api_version) {
102 if (api_version_nopatch < VK_API_VERSION_1_0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700103 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
104 HandleToUint64(instance), kVUIDUndefined,
John Zulauf620755c2018-04-16 11:00:43 -0600105 "Invalid CreateInstance->pCreateInfo->pApplicationInfo.apiVersion number (0x%08x). "
106 "Using VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
107 api_version, VK_VERSION_MAJOR(effective_api_version), VK_VERSION_MINOR(effective_api_version));
108 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700109 skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
110 HandleToUint64(instance), kVUIDUndefined,
John Zulauf620755c2018-04-16 11:00:43 -0600111 "Unrecognized CreateInstance->pCreateInfo->pApplicationInfo.apiVersion number (0x%08x). "
112 "Assuming VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
113 api_version, VK_VERSION_MAJOR(effective_api_version), VK_VERSION_MINOR(effective_api_version));
114 }
115 }
116 return skip;
117}
118
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700119bool StatelessValidation::validate_instance_extensions(const VkInstanceCreateInfo *pCreateInfo) {
John Zulauf620755c2018-04-16 11:00:43 -0600120 bool skip = false;
121 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700122 skip |= validate_extension_reqs(instance_extensions, "VUID-vkCreateInstance-ppEnabledExtensionNames-01388", "instance",
123 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 Lobodzinskibf599b92018-12-31 12:15:55 -0700137bool StatelessValidation::manual_PreCallValidateCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
138 const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700139 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)
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700144 ? pCreateInfo->pApplicationInfo->apiVersion
145 : VK_API_VERSION_1_0;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700146 skip |= validate_api_version(local_api_version, api_version);
147 skip |= validate_instance_extensions(pCreateInfo);
148 return skip;
149}
150
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700151void StatelessValidation::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700152 const VkAllocationCallbacks *pAllocator, VkInstance *pInstance,
153 VkResult result) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700154 auto instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), layer_data_map);
155 // Copy extension data into local object
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700156 if (result != VK_SUCCESS) return;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700157 this->instance_extensions = instance_data->instance_extensions;
158}
159
160void StatelessValidation::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700161 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700162 auto device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -0700163 if (result != VK_SUCCESS) return;
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700164 ValidationObject *validation_data = GetValidationObject(device_data->object_dispatch, LayerObjectTypeParameterValidation);
165 StatelessValidation *stateless_validation = static_cast<StatelessValidation *>(validation_data);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700166
167 // Store queue family data
168 if ((pCreateInfo != nullptr) && (pCreateInfo->pQueueCreateInfos != nullptr)) {
169 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700170 stateless_validation->queueFamilyIndexMap.insert(
171 std::make_pair(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex, pCreateInfo->pQueueCreateInfos[i].queueCount));
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700172 }
173 }
174
175 // Parmeter validation also uses extension data
176 stateless_validation->device_extensions = this->device_extensions;
177
178 VkPhysicalDeviceProperties device_properties = {};
179 // Need to get instance and do a getlayerdata call...
180 ValidationObject *instance_object = GetLayerDataPtr(get_dispatch_key(physicalDevice), layer_data_map);
181 instance_object->instance_dispatch_table.GetPhysicalDeviceProperties(physicalDevice, &device_properties);
182 memcpy(&stateless_validation->device_limits, &device_properties.limits, sizeof(VkPhysicalDeviceLimits));
183
184 if (device_extensions.vk_nv_shading_rate_image) {
185 // Get the needed shading rate image limits
186 auto shading_rate_image_props = lvl_init_struct<VkPhysicalDeviceShadingRateImagePropertiesNV>();
187 auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&shading_rate_image_props);
188 instance_object->instance_dispatch_table.GetPhysicalDeviceProperties2KHR(physicalDevice, &prop2);
189 phys_dev_ext_props.shading_rate_image_props = shading_rate_image_props;
190 }
191
192 if (device_extensions.vk_nv_mesh_shader) {
193 // Get the needed mesh shader limits
194 auto mesh_shader_props = lvl_init_struct<VkPhysicalDeviceMeshShaderPropertiesNV>();
195 auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&mesh_shader_props);
196 instance_object->instance_dispatch_table.GetPhysicalDeviceProperties2KHR(physicalDevice, &prop2);
197 phys_dev_ext_props.mesh_shader_props = mesh_shader_props;
198 }
199
200 // Save app-enabled features in this device's validation object
201 // The enabled features can come from either pEnabledFeatures, or from the pNext chain
202 const VkPhysicalDeviceFeatures *enabled_features_found = pCreateInfo->pEnabledFeatures;
203 if ((nullptr == enabled_features_found) && device_extensions.vk_khr_get_physical_device_properties_2) {
204 const auto *features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2KHR>(pCreateInfo->pNext);
205 if (features2) {
206 enabled_features_found = &(features2->features);
207 }
208 }
209 if (enabled_features_found) {
210 stateless_validation->physical_device_features = *enabled_features_found;
211 } else {
212 memset(&stateless_validation->physical_device_features, 0, sizeof(VkPhysicalDeviceFeatures));
213 }
214}
215
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700216bool StatelessValidation::manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700217 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600218 bool skip = false;
John Zulauf620755c2018-04-16 11:00:43 -0600219 bool maint1 = false;
220 bool negative_viewport = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600221
222 if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) {
223 for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700224 skip |= validate_string("vkCreateDevice", "pCreateInfo->ppEnabledLayerNames",
Mark Lobodzinskiebee3552018-05-29 09:55:54 -0600225 "VUID-VkDeviceCreateInfo-ppEnabledLayerNames-parameter", pCreateInfo->ppEnabledLayerNames[i]);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600226 }
227 }
228
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600229 if ((pCreateInfo->enabledExtensionCount > 0) && (pCreateInfo->ppEnabledExtensionNames != NULL)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700230 maint1 = extension_state_by_name(device_extensions, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
231 negative_viewport = extension_state_by_name(device_extensions, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME);
John Zulauf620755c2018-04-16 11:00:43 -0600232
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600233 for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700234 skip |= validate_string("vkCreateDevice", "pCreateInfo->ppEnabledExtensionNames",
Mark Lobodzinskiebee3552018-05-29 09:55:54 -0600235 "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-parameter",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600236 pCreateInfo->ppEnabledExtensionNames[i]);
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700237 skip |= validate_extension_reqs(device_extensions, "VUID-vkCreateDevice-ppEnabledExtensionNames-01387", "device",
238 pCreateInfo->ppEnabledExtensionNames[i]);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600239 }
240 }
241
242 if (maint1 && negative_viewport) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700243 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 -0600244 "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-00374",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600245 "VkDeviceCreateInfo->ppEnabledExtensionNames must not simultaneously include VK_KHR_maintenance1 and "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600246 "VK_AMD_negative_viewport_height.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600247 }
248
249 if (pCreateInfo->pNext != NULL && pCreateInfo->pEnabledFeatures) {
250 // Check for get_physical_device_properties2 struct
John Zulaufde972ac2017-10-26 12:07:05 -0600251 const auto *features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2KHR>(pCreateInfo->pNext);
252 if (features2) {
253 // Cannot include VkPhysicalDeviceFeatures2KHR and have non-null pEnabledFeatures
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700254 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 -0600255 kVUID_PVError_InvalidUsage,
John Zulaufde972ac2017-10-26 12:07:05 -0600256 "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2KHR struct when "
257 "pCreateInfo->pEnabledFeatures is non-NULL.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600258 }
259 }
260
261 // Validate pCreateInfo->pQueueCreateInfos
262 if (pCreateInfo->pQueueCreateInfos) {
263 std::unordered_set<uint32_t> set;
264
265 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
266 const uint32_t requested_queue_family = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
267 if (requested_queue_family == VK_QUEUE_FAMILY_IGNORED) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700268 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
269 HandleToUint64(physicalDevice), "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 Lobodzinskibf599b92018-12-31 12:15:55 -0700275 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
276 HandleToUint64(physicalDevice), "VUID-VkDeviceCreateInfo-queueFamilyIndex-00372",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600277 "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600278 ") is not unique within pCreateInfo->pQueueCreateInfos array.",
279 i, requested_queue_family);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600280 } else {
281 set.insert(requested_queue_family);
282 }
283
284 if (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities != nullptr) {
285 for (uint32_t j = 0; j < pCreateInfo->pQueueCreateInfos[i].queueCount; ++j) {
286 const float queue_priority = pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j];
287 if (!(queue_priority >= 0.f) || !(queue_priority <= 1.f)) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700288 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
289 HandleToUint64(physicalDevice), "VUID-VkDeviceQueueCreateInfo-pQueuePriorities-00383",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600290 "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].pQueuePriorities[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600291 "] (=%f) is not between 0 and 1 (inclusive).",
292 i, j, queue_priority);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600293 }
294 }
295 }
296 }
297 }
298
299 return skip;
300}
301
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700302bool StatelessValidation::require_device_extension(bool flag, char const *function_name, char const *extension_name) {
303 if (!flag) {
304 return log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
305 kVUID_PVError_ExtensionNotEnabled,
306 "%s() called even though the %s extension was not enabled for this VkDevice.", function_name,
307 extension_name);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600308 }
309
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700310 return false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600311}
312
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700313bool StatelessValidation::manual_PreCallValidateGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
314 VkQueue *pQueue) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600315 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600316
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700317 skip |= ValidateDeviceQueueFamily(queueFamilyIndex, "vkGetDeviceQueue", "queueFamilyIndex",
Dave Houlton413a6782018-05-22 13:01:54 -0600318 "VUID-vkGetDeviceQueue-queueFamilyIndex-00384");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700319 const auto &queue_data = queueFamilyIndexMap.find(queueFamilyIndex);
320 if (queue_data != queueFamilyIndexMap.end() && queue_data->second <= queueIndex) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700321 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, HandleToUint64(device),
322 "VUID-vkGetDeviceQueue-queueIndex-00385",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600323 "vkGetDeviceQueue: queueIndex (=%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -0700324 ") is not less than the number of queues requested from queueFamilyIndex (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600325 ") when the device was created (i.e. is not less than %" PRIu32 ").",
326 queueIndex, queueFamilyIndex, queue_data->second);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600327 }
328 return skip;
329}
330
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700331bool StatelessValidation::manual_PreCallValidateCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700332 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
Petr Krause91f7a12017-12-14 20:57:36 +0100333 bool skip = false;
334
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700335 const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, VK_NULL_HANDLE, "vkCreateBuffer"};
Petr Krause5c37652018-01-05 04:05:12 +0100336
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600337 if (pCreateInfo != nullptr) {
Dave Houlton413a6782018-05-22 13:01:54 -0600338 skip |= ValidateGreaterThanZero(pCreateInfo->size, "pCreateInfo->size", "VUID-VkBufferCreateInfo-size-00912", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600339
340 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
341 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
342 // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
343 if (pCreateInfo->queueFamilyIndexCount <= 1) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600344 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 -0600345 "VUID-VkBufferCreateInfo-sharingMode-00914",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600346 "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600347 "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600348 }
349
350 // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
351 // queueFamilyIndexCount uint32_t values
352 if (pCreateInfo->pQueueFamilyIndices == nullptr) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600353 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 -0600354 "VUID-VkBufferCreateInfo-sharingMode-00913",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600355 "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
356 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600357 "pCreateInfo->queueFamilyIndexCount uint32_t values.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600358 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700359 skip |= ValidateQueueFamilies(pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices,
Dave Houlton413a6782018-05-22 13:01:54 -0600360 "vkCreateBuffer", "pCreateInfo->pQueueFamilyIndices", kVUID_PVError_InvalidUsage,
361 kVUID_PVError_InvalidUsage, false);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600362 }
363 }
364
365 // If flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain
366 // VK_BUFFER_CREATE_SPARSE_BINDING_BIT
367 if (((pCreateInfo->flags & (VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
368 ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600369 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 -0600370 "VUID-VkBufferCreateInfo-flags-00918",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600371 "vkCreateBuffer: if pCreateInfo->flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600372 "VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600373 }
374 }
375
376 return skip;
377}
378
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700379bool StatelessValidation::manual_PreCallValidateCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700380 const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600381 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600382
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700383 const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE, "vkCreateImage"};
Petr Krause5c37652018-01-05 04:05:12 +0100384
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600385 if (pCreateInfo != nullptr) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600386 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
387 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
388 // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
389 if (pCreateInfo->queueFamilyIndexCount <= 1) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600390 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 -0600391 "VUID-VkImageCreateInfo-sharingMode-00942",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600392 "vkCreateImage(): if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600393 "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600394 }
395
396 // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
397 // queueFamilyIndexCount uint32_t values
398 if (pCreateInfo->pQueueFamilyIndices == nullptr) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600399 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 -0600400 "VUID-VkImageCreateInfo-sharingMode-00941",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600401 "vkCreateImage(): if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
402 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600403 "pCreateInfo->queueFamilyIndexCount uint32_t values.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600404 } else {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700405 skip |= ValidateQueueFamilies(pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices, "vkCreateImage",
406 "pCreateInfo->pQueueFamilyIndices", kVUID_PVError_InvalidUsage,
Dave Houlton413a6782018-05-22 13:01:54 -0600407 kVUID_PVError_InvalidUsage, false);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600408 }
409 }
410
Dave Houlton413a6782018-05-22 13:01:54 -0600411 skip |= ValidateGreaterThanZero(pCreateInfo->extent.width, "pCreateInfo->extent.width",
412 "VUID-VkImageCreateInfo-extent-00944", log_misc);
413 skip |= ValidateGreaterThanZero(pCreateInfo->extent.height, "pCreateInfo->extent.height",
414 "VUID-VkImageCreateInfo-extent-00945", log_misc);
415 skip |= ValidateGreaterThanZero(pCreateInfo->extent.depth, "pCreateInfo->extent.depth",
416 "VUID-VkImageCreateInfo-extent-00946", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600417
Dave Houlton413a6782018-05-22 13:01:54 -0600418 skip |= ValidateGreaterThanZero(pCreateInfo->mipLevels, "pCreateInfo->mipLevels", "VUID-VkImageCreateInfo-mipLevels-00947",
419 log_misc);
420 skip |= ValidateGreaterThanZero(pCreateInfo->arrayLayers, "pCreateInfo->arrayLayers",
421 "VUID-VkImageCreateInfo-arrayLayers-00948", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600422
Dave Houlton130c0212018-01-29 13:39:56 -0700423 // InitialLayout must be PREINITIALIZED or UNDEFINED
Dave Houltone19e20d2018-02-02 16:32:41 -0700424 if ((pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED) &&
425 (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED)) {
426 skip |= log_msg(
Dave Houlton413a6782018-05-22 13:01:54 -0600427 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
428 "VUID-VkImageCreateInfo-initialLayout-00993",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600429 "vkCreateImage(): initialLayout is %s, must be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED.",
430 string_VkImageLayout(pCreateInfo->initialLayout));
Dave Houlton130c0212018-01-29 13:39:56 -0700431 }
432
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600433 // If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1
Petr Kraus3ac9e812018-03-13 12:31:08 +0100434 if ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) &&
435 ((pCreateInfo->extent.height != 1) || (pCreateInfo->extent.depth != 1))) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600436 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 -0600437 "VUID-VkImageCreateInfo-imageType-00956",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700438 "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_1D, both pCreateInfo->extent.height and "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600439 "pCreateInfo->extent.depth must be 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600440 }
441
442 if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D) {
Petr Kraus3f433212018-03-13 12:31:27 +0100443 if (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) {
444 if (pCreateInfo->extent.width != pCreateInfo->extent.height) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600445 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 -0600446 VK_NULL_HANDLE, "VUID-VkImageCreateInfo-imageType-00954",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600447 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, but "
448 "pCreateInfo->extent.width (=%" PRIu32 ") and pCreateInfo->extent.height (=%" PRIu32
449 ") are not equal.",
450 pCreateInfo->extent.width, pCreateInfo->extent.height);
Petr Kraus3f433212018-03-13 12:31:27 +0100451 }
452
453 if (pCreateInfo->arrayLayers < 6) {
454 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 -0600455 VK_NULL_HANDLE, "VUID-VkImageCreateInfo-imageType-00954",
Petr Kraus3f433212018-03-13 12:31:27 +0100456 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, but "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600457 "pCreateInfo->arrayLayers (=%" PRIu32 ") is not greater than or equal to 6.",
458 pCreateInfo->arrayLayers);
Petr Kraus3f433212018-03-13 12:31:27 +0100459 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600460 }
461
462 if (pCreateInfo->extent.depth != 1) {
Mark Lobodzinski88529492018-04-01 10:38:15 -0600463 skip |=
464 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 -0600465 "VUID-VkImageCreateInfo-imageType-00957",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600466 "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_2D, pCreateInfo->extent.depth must be 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600467 }
468 }
469
Dave Houlton130c0212018-01-29 13:39:56 -0700470 // 3D image may have only 1 layer
471 if ((pCreateInfo->imageType == VK_IMAGE_TYPE_3D) && (pCreateInfo->arrayLayers != 1)) {
Mark Lobodzinski88529492018-04-01 10:38:15 -0600472 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 -0600473 "VUID-VkImageCreateInfo-imageType-00961",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600474 "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_3D, pCreateInfo->arrayLayers must be 1.");
Dave Houlton130c0212018-01-29 13:39:56 -0700475 }
476
477 // If multi-sample, validate type, usage, tiling and mip levels.
478 if ((pCreateInfo->samples != VK_SAMPLE_COUNT_1_BIT) &&
479 ((pCreateInfo->imageType != VK_IMAGE_TYPE_2D) || (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ||
Shannon McPhersona886c2a2018-10-12 14:38:20 -0600480 (pCreateInfo->mipLevels != 1) || (pCreateInfo->tiling != VK_IMAGE_TILING_OPTIMAL))) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600481 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 -0600482 "VUID-VkImageCreateInfo-samples-02257",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600483 "vkCreateImage(): Multi-sample image with incompatible type, usage, tiling, or mips.");
Dave Houlton130c0212018-01-29 13:39:56 -0700484 }
485
486 if (0 != (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
487 VkImageUsageFlags legal_flags = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
488 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
489 // At least one of the legal attachment bits must be set
490 if (0 == (pCreateInfo->usage & legal_flags)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600491 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 -0600492 "VUID-VkImageCreateInfo-usage-00966",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600493 "vkCreateImage(): Transient attachment image without a compatible attachment flag set.");
Dave Houlton130c0212018-01-29 13:39:56 -0700494 }
495 // No flags other than the legal attachment bits may be set
496 legal_flags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
497 if (0 != (pCreateInfo->usage & ~legal_flags)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600498 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 -0600499 "VUID-VkImageCreateInfo-usage-00963",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600500 "vkCreateImage(): Transient attachment image with incompatible usage flags set.");
Dave Houlton130c0212018-01-29 13:39:56 -0700501 }
502 }
503
Jeff Bolzef40fec2018-09-01 22:04:34 -0500504 // mipLevels must be less than or equal to the number of levels in the complete mipmap chain
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600505 uint32_t maxDim = std::max(std::max(pCreateInfo->extent.width, pCreateInfo->extent.height), pCreateInfo->extent.depth);
Jeff Bolzef40fec2018-09-01 22:04:34 -0500506 // Max mip levels is different for corner-sampled images vs normal images.
Dave Houlton142c4cb2018-10-17 15:04:41 -0600507 uint32_t maxMipLevels = (pCreateInfo->flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) ? (uint32_t)(ceil(log2(maxDim)))
508 : (uint32_t)(floor(log2(maxDim)) + 1);
Jeff Bolzef40fec2018-09-01 22:04:34 -0500509 if (maxDim > 0 && pCreateInfo->mipLevels > maxMipLevels) {
Dave Houlton413a6782018-05-22 13:01:54 -0600510 skip |=
511 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
512 "VUID-VkImageCreateInfo-mipLevels-00958",
513 "vkCreateImage(): pCreateInfo->mipLevels must be less than or equal to "
514 "floor(log2(max(pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth)))+1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600515 }
516
Mark Lobodzinski69259c52018-09-18 15:14:58 -0600517 if ((pCreateInfo->flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT) && (pCreateInfo->imageType != VK_IMAGE_TYPE_3D)) {
518 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE,
519 "VUID-VkImageCreateInfo-flags-00950",
520 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT but "
521 "pCreateInfo->imageType is not VK_IMAGE_TYPE_3D.");
522 }
523
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700524 if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && (!physical_device_features.sparseBinding)) {
Petr Krausb6f97802018-03-13 12:31:39 +0100525 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 -0600526 "VUID-VkImageCreateInfo-flags-00969",
Petr Krausb6f97802018-03-13 12:31:39 +0100527 "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_BINDING_BIT, but the "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600528 "VkPhysicalDeviceFeatures::sparseBinding feature is disabled.");
Petr Krausb6f97802018-03-13 12:31:39 +0100529 }
530
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600531 // If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain
532 // VK_IMAGE_CREATE_SPARSE_BINDING_BIT
533 if (((pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
534 ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600535 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 -0600536 "VUID-VkImageCreateInfo-flags-00987",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600537 "vkCreateImage: if pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600538 "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600539 }
540
541 // Check for combinations of attributes that are incompatible with having VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set
542 if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) {
543 // Linear tiling is unsupported
544 if (VK_IMAGE_TILING_LINEAR == pCreateInfo->tiling) {
Dave Houlton413a6782018-05-22 13:01:54 -0600545 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
546 kVUID_PVError_InvalidUsage,
547 "vkCreateImage: if pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then image "
548 "tiling of VK_IMAGE_TILING_LINEAR is not supported");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600549 }
550
551 // Sparse 1D image isn't valid
552 if (VK_IMAGE_TYPE_1D == pCreateInfo->imageType) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600553 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 -0600554 "VUID-VkImageCreateInfo-imageType-00970",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600555 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 1D image.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600556 }
557
558 // Sparse 2D image when device doesn't support it
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700559 if ((VK_FALSE == physical_device_features.sparseResidencyImage2D) && (VK_IMAGE_TYPE_2D == pCreateInfo->imageType)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600560 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 -0600561 "VUID-VkImageCreateInfo-imageType-00971",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600562 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 2D image if corresponding "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600563 "feature is not enabled on the device.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600564 }
565
566 // Sparse 3D image when device doesn't support it
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700567 if ((VK_FALSE == physical_device_features.sparseResidencyImage3D) && (VK_IMAGE_TYPE_3D == pCreateInfo->imageType)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -0600568 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 -0600569 "VUID-VkImageCreateInfo-imageType-00972",
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600570 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 3D image if corresponding "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600571 "feature is not enabled on the device.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600572 }
573
574 // Multi-sample 2D image when device doesn't support it
575 if (VK_IMAGE_TYPE_2D == pCreateInfo->imageType) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700576 if ((VK_FALSE == physical_device_features.sparseResidency2Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600577 (VK_SAMPLE_COUNT_2_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700578 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 -0600579 "VUID-VkImageCreateInfo-imageType-00973",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700580 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 2-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600581 "corresponding feature is not enabled on the device.");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700582 } else if ((VK_FALSE == physical_device_features.sparseResidency4Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600583 (VK_SAMPLE_COUNT_4_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700584 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 -0600585 "VUID-VkImageCreateInfo-imageType-00974",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700586 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 4-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600587 "corresponding feature is not enabled on the device.");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700588 } else if ((VK_FALSE == physical_device_features.sparseResidency8Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600589 (VK_SAMPLE_COUNT_8_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700590 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 -0600591 "VUID-VkImageCreateInfo-imageType-00975",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700592 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 8-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600593 "corresponding feature is not enabled on the device.");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700594 } else if ((VK_FALSE == physical_device_features.sparseResidency16Samples) &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600595 (VK_SAMPLE_COUNT_16_BIT == pCreateInfo->samples)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -0700596 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 -0600597 "VUID-VkImageCreateInfo-imageType-00976",
Dave Houltona9df0ce2018-02-07 10:51:23 -0700598 "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 16-sample image if "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600599 "corresponding feature is not enabled on the device.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600600 }
601 }
602 }
Jeff Bolzef40fec2018-09-01 22:04:34 -0500603
Jeff Bolz9af91c52018-09-01 21:53:57 -0500604 if (pCreateInfo->usage & VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV) {
605 if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D) {
606 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
607 "VUID-VkImageCreateInfo-imageType-02082",
608 "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
609 "imageType must be VK_IMAGE_TYPE_2D.");
610 }
611 if (pCreateInfo->samples != VK_SAMPLE_COUNT_1_BIT) {
612 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
613 "VUID-VkImageCreateInfo-samples-02083",
614 "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
615 "samples must be VK_SAMPLE_COUNT_1_BIT.");
616 }
617 if (pCreateInfo->tiling != VK_IMAGE_TILING_OPTIMAL) {
618 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
619 "VUID-VkImageCreateInfo-tiling-02084",
620 "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
621 "tiling must be VK_IMAGE_TILING_OPTIMAL.");
622 }
623 }
Jeff Bolzef40fec2018-09-01 22:04:34 -0500624
625 if (pCreateInfo->flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) {
Dave Houlton142c4cb2018-10-17 15:04:41 -0600626 if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D && pCreateInfo->imageType != VK_IMAGE_TYPE_3D) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500627 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
628 "VUID-VkImageCreateInfo-flags-02050",
629 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV, "
630 "imageType must be VK_IMAGE_TYPE_2D or VK_IMAGE_TYPE_3D.");
631 }
632
Dave Houlton142c4cb2018-10-17 15:04:41 -0600633 if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || FormatIsDepthOrStencil(pCreateInfo->format)) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500634 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
635 "VUID-VkImageCreateInfo-flags-02051",
636 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV, "
637 "it must not also contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT and format must "
638 "not be a depth/stencil format.");
639 }
640
Dave Houlton142c4cb2018-10-17 15:04:41 -0600641 if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D && (pCreateInfo->extent.width == 1 || pCreateInfo->extent.height == 1)) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500642 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
643 "VUID-VkImageCreateInfo-flags-02052",
644 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and "
645 "imageType is VK_IMAGE_TYPE_2D, extent.width and extent.height must be "
646 "greater than 1.");
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500647 } else if (pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
Dave Houlton142c4cb2018-10-17 15:04:41 -0600648 (pCreateInfo->extent.width == 1 || pCreateInfo->extent.height == 1 || pCreateInfo->extent.depth == 1)) {
Jeff Bolzef40fec2018-09-01 22:04:34 -0500649 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
650 "VUID-VkImageCreateInfo-flags-02053",
651 "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and "
652 "imageType is VK_IMAGE_TYPE_3D, extent.width, extent.height, and extent.depth "
653 "must be greater than 1.");
Jeff Bolzef40fec2018-09-01 22:04:34 -0500654 }
655 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600656 }
Jeff Bolzef40fec2018-09-01 22:04:34 -0500657
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600658 return skip;
659}
660
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700661bool StatelessValidation::manual_PreCallValidateCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700662 const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600663 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600664
665 if (pCreateInfo != nullptr) {
Dave Houltonbd2e2622018-04-10 16:41:14 -0600666 // Validate chained VkImageViewUsageCreateInfo struct, if present
667 if (nullptr != pCreateInfo->pNext) {
668 auto chained_ivuci_struct = lvl_find_in_chain<VkImageViewUsageCreateInfoKHR>(pCreateInfo->pNext);
669 if (chained_ivuci_struct) {
670 if (0 == chained_ivuci_struct->usage) {
671 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 -0600672 "VUID-VkImageViewUsageCreateInfo-usage-requiredbitmask",
Dave Houlton0f3795b2018-04-13 15:04:35 -0600673 "vkCreateImageView: Chained VkImageViewUsageCreateInfo usage field must not be 0.");
Dave Houltonbd2e2622018-04-10 16:41:14 -0600674 } else if (chained_ivuci_struct->usage & ~AllVkImageUsageFlagBits) {
675 std::stringstream ss;
676 ss << "vkCreateImageView: Chained VkImageViewUsageCreateInfo usage field (0x" << std::hex
677 << chained_ivuci_struct->usage << ") contains invalid flag bits.";
678 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 -0600679 "VUID-VkImageViewUsageCreateInfo-usage-parameter", "%s", ss.str().c_str());
Dave Houltonbd2e2622018-04-10 16:41:14 -0600680 }
681 }
682 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600683 }
684 return skip;
685}
686
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700687bool StatelessValidation::manual_PreCallValidateViewport(const VkViewport &viewport, const char *fn_name, const char *param_name,
688 VkDebugReportObjectTypeEXT object_type, uint64_t object = 0) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100689 bool skip = false;
Petr Krausb3fcdb42018-01-09 22:09:09 +0100690
691 // Note: for numerical correctness
692 // - float comparisons should expect NaN (comparison always false).
693 // - VkPhysicalDeviceLimits::maxViewportDimensions is uint32_t, not float -> careful.
694
695 const auto f_lte_u32_exact = [](const float v1_f, const uint32_t v2_u32) {
John Zulaufac0876c2018-02-19 10:09:35 -0700696 if (std::isnan(v1_f)) return false;
Petr Krausb3fcdb42018-01-09 22:09:09 +0100697 if (v1_f <= 0.0f) return true;
698
699 float intpart;
700 const float fract = modff(v1_f, &intpart);
701
702 assert(std::numeric_limits<float>::radix == 2);
703 const float u32_max_plus1 = ldexpf(1.0f, 32); // hopefully exact
704 if (intpart >= u32_max_plus1) return false;
705
706 uint32_t v1_u32 = static_cast<uint32_t>(intpart);
707 if (v1_u32 < v2_u32)
708 return true;
709 else if (v1_u32 == v2_u32 && fract == 0.0f)
710 return true;
711 else
712 return false;
713 };
714
715 const auto f_lte_u32_direct = [](const float v1_f, const uint32_t v2_u32) {
716 const float v2_f = static_cast<float>(v2_u32); // not accurate for > radix^digits; and undefined rounding mode
717 return (v1_f <= v2_f);
718 };
719
720 // width
721 bool width_healthy = true;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700722 const auto max_w = device_limits.maxViewportDimensions[0];
Petr Krausb3fcdb42018-01-09 22:09:09 +0100723
724 if (!(viewport.width > 0.0f)) {
725 width_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600726 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 -0600727 "%s: %s.width (=%f) is not greater than 0.0.", fn_name, param_name, viewport.width);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100728 } else if (!(f_lte_u32_exact(viewport.width, max_w) || f_lte_u32_direct(viewport.width, max_w))) {
729 width_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600730 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 -0600731 "%s: %s.width (=%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[0] (=%" PRIu32 ").", fn_name,
732 param_name, viewport.width, max_w);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100733 } 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 -0600734 skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, object_type, object, kVUID_PVError_NONE,
Petr Krausb3fcdb42018-01-09 22:09:09 +0100735 "%s: %s.width (=%f) technically exceeds VkPhysicalDeviceLimits::maxViewportDimensions[0] (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600736 "), but it is within the static_cast<float>(maxViewportDimensions[0]) limit.",
737 fn_name, param_name, viewport.width, max_w);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100738 }
739
740 // height
741 bool height_healthy = true;
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700742 const bool negative_height_enabled = api_version >= VK_API_VERSION_1_1 || device_extensions.vk_khr_maintenance1 ||
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700743 device_extensions.vk_amd_negative_viewport_height;
744 const auto max_h = device_limits.maxViewportDimensions[1];
Petr Krausb3fcdb42018-01-09 22:09:09 +0100745
746 if (!negative_height_enabled && !(viewport.height > 0.0f)) {
747 height_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600748 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 -0600749 "%s: %s.height (=%f) is not greater 0.0.", fn_name, param_name, viewport.height);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100750 } else if (!(f_lte_u32_exact(fabsf(viewport.height), max_h) || f_lte_u32_direct(fabsf(viewport.height), max_h))) {
751 height_healthy = false;
752
Dave Houlton413a6782018-05-22 13:01:54 -0600753 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 -0600754 "%s: Absolute value of %s.height (=%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[1] (=%" PRIu32
755 ").",
756 fn_name, param_name, viewport.height, max_h);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100757 } else if (!f_lte_u32_exact(fabsf(viewport.height), max_h) && f_lte_u32_direct(fabsf(viewport.height), max_h)) {
758 height_healthy = false;
759
760 skip |= log_msg(
Dave Houlton413a6782018-05-22 13:01:54 -0600761 report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, object_type, object, kVUID_PVError_NONE,
Petr Krausb3fcdb42018-01-09 22:09:09 +0100762 "%s: Absolute value of %s.height (=%f) technically exceeds VkPhysicalDeviceLimits::maxViewportDimensions[1] (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600763 "), but it is within the static_cast<float>(maxViewportDimensions[1]) limit.",
764 fn_name, param_name, viewport.height, max_h);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100765 }
766
767 // x
768 bool x_healthy = true;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700769 if (!(viewport.x >= device_limits.viewportBoundsRange[0])) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100770 x_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600771 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 -0600772 "%s: %s.x (=%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name, param_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700773 viewport.x, device_limits.viewportBoundsRange[0]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100774 }
775
776 // x + width
777 if (x_healthy && width_healthy) {
778 const float right_bound = viewport.x + viewport.width;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700779 if (!(right_bound <= device_limits.viewportBoundsRange[1])) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700780 skip |= log_msg(
781 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-x-01232",
782 "%s: %s.x + %s.width (=%f + %f = %f) is greater than VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).",
783 fn_name, param_name, param_name, viewport.x, viewport.width, right_bound, device_limits.viewportBoundsRange[1]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100784 }
785 }
786
787 // y
788 bool y_healthy = true;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700789 if (!(viewport.y >= device_limits.viewportBoundsRange[0])) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100790 y_healthy = false;
Dave Houlton413a6782018-05-22 13:01:54 -0600791 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 -0600792 "%s: %s.y (=%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name, param_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700793 viewport.y, device_limits.viewportBoundsRange[0]);
794 } else if (negative_height_enabled && !(viewport.y <= device_limits.viewportBoundsRange[1])) {
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-01776",
Mark Lobodzinski88529492018-04-01 10:38:15 -0600797 "%s: %s.y (=%f) exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).", fn_name, param_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700798 viewport.y, device_limits.viewportBoundsRange[1]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100799 }
800
801 // y + height
802 if (y_healthy && height_healthy) {
803 const float boundary = viewport.y + viewport.height;
804
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700805 if (!(boundary <= device_limits.viewportBoundsRange[1])) {
Dave Houlton413a6782018-05-22 13:01:54 -0600806 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 -0600807 "%s: %s.y + %s.height (=%f + %f = %f) exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).",
808 fn_name, param_name, param_name, viewport.y, viewport.height, boundary,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700809 device_limits.viewportBoundsRange[1]);
810 } else if (negative_height_enabled && !(boundary >= device_limits.viewportBoundsRange[0])) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100811 skip |= log_msg(
Dave Houlton413a6782018-05-22 13:01:54 -0600812 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01777",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -0600813 "%s: %s.y + %s.height (=%f + %f = %f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700814 param_name, param_name, viewport.y, viewport.height, boundary, device_limits.viewportBoundsRange[0]);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100815 }
816 }
817
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700818 if (!device_extensions.vk_ext_depth_range_unrestricted) {
Petr Krausb3fcdb42018-01-09 22:09:09 +0100819 // minDepth
820 if (!(viewport.minDepth >= 0.0) || !(viewport.minDepth <= 1.0)) {
Dave Houlton413a6782018-05-22 13:01:54 -0600821 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 -0600822
Petr Krausb3fcdb42018-01-09 22:09:09 +0100823 "%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 -0600824 "[0.0, 1.0] range.",
825 fn_name, param_name, viewport.minDepth);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100826 }
827
828 // maxDepth
829 if (!(viewport.maxDepth >= 0.0) || !(viewport.maxDepth <= 1.0)) {
Dave Houlton413a6782018-05-22 13:01:54 -0600830 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 -0600831
Petr Krausb3fcdb42018-01-09 22:09:09 +0100832 "%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 -0600833 "[0.0, 1.0] range.",
834 fn_name, param_name, viewport.maxDepth);
Petr Krausb3fcdb42018-01-09 22:09:09 +0100835 }
836 }
837
838 return skip;
839}
840
Dave Houlton142c4cb2018-10-17 15:04:41 -0600841struct SampleOrderInfo {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500842 VkShadingRatePaletteEntryNV shadingRate;
843 uint32_t width;
844 uint32_t height;
845};
846
847// All palette entries with more than one pixel per fragment
Dave Houlton142c4cb2018-10-17 15:04:41 -0600848static SampleOrderInfo sampleOrderInfos[] = {
849 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 1, 2},
850 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV, 2, 1},
851 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV, 2, 2},
852 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV, 4, 2},
853 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV, 2, 4},
854 {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 4},
Jeff Bolz9af91c52018-09-01 21:53:57 -0500855};
856
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700857bool StatelessValidation::ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV *order) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500858 bool skip = false;
Jeff Bolz9af91c52018-09-01 21:53:57 -0500859
Jeff Bolz45bf7d62018-09-18 15:39:58 -0500860 SampleOrderInfo *sampleOrderInfo;
Jeff Bolz9af91c52018-09-01 21:53:57 -0500861 uint32_t infoIdx = 0;
Jeff Bolz45bf7d62018-09-18 15:39:58 -0500862 for (sampleOrderInfo = nullptr; infoIdx < ARRAY_SIZE(sampleOrderInfos); ++infoIdx) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500863 if (sampleOrderInfos[infoIdx].shadingRate == order->shadingRate) {
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500864 sampleOrderInfo = &sampleOrderInfos[infoIdx];
Jeff Bolz9af91c52018-09-01 21:53:57 -0500865 break;
866 }
867 }
868
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500869 if (sampleOrderInfo == nullptr) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500870 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
871 "VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073",
872 "VkCoarseSampleOrderCustomNV shadingRate must be a shading rate "
873 "that generates fragments with more than one pixel.");
874 return skip;
875 }
876
Dave Houlton142c4cb2018-10-17 15:04:41 -0600877 if (order->sampleCount == 0 || (order->sampleCount & (order->sampleCount - 1)) ||
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700878 !(order->sampleCount & device_limits.framebufferNoAttachmentsSampleCounts)) {
Jeff Bolz9af91c52018-09-01 21:53:57 -0500879 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
880 "VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074",
Dave Houlton142c4cb2018-10-17 15:04:41 -0600881 "VkCoarseSampleOrderCustomNV sampleCount (=%" PRIu32
882 ") must "
Jeff Bolz9af91c52018-09-01 21:53:57 -0500883 "correspond to a sample count enumerated in VkSampleCountFlags whose corresponding bit "
884 "is set in framebufferNoAttachmentsSampleCounts.",
885 order->sampleCount);
886 }
887
Jeff Bolz9af91c52018-09-01 21:53:57 -0500888 if (order->sampleLocationCount != order->sampleCount * sampleOrderInfo->width * sampleOrderInfo->height) {
889 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
890 "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075",
Dave Houlton142c4cb2018-10-17 15:04:41 -0600891 "VkCoarseSampleOrderCustomNV sampleLocationCount (=%" PRIu32
892 ") must "
893 "be equal to the product of sampleCount (=%" PRIu32
894 "), the fragment width for shadingRate "
Jeff Bolz9af91c52018-09-01 21:53:57 -0500895 "(=%" PRIu32 "), and the fragment height for shadingRate (=%" PRIu32 ").",
896 order->sampleLocationCount, order->sampleCount, sampleOrderInfo->width, sampleOrderInfo->height);
897 }
898
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700899 if (order->sampleLocationCount > phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples) {
Dave Houlton142c4cb2018-10-17 15:04:41 -0600900 skip |= log_msg(
901 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
902 "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076",
903 "VkCoarseSampleOrderCustomNV sampleLocationCount (=%" PRIu32
904 ") must "
905 "be less than or equal to VkPhysicalDeviceShadingRateImagePropertiesNV shadingRateMaxCoarseSamples (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700906 order->sampleLocationCount, phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples);
Jeff Bolz9af91c52018-09-01 21:53:57 -0500907 }
Jeff Bolz9af91c52018-09-01 21:53:57 -0500908
909 // Accumulate a bitmask tracking which (x,y,sample) tuples are seen. Expect
Jeff Bolzb8a8dd02018-09-18 02:39:24 -0500910 // the first width*height*sampleCount bits to all be set. Note: There is no
911 // guarantee that 64 bits is enough, but practically it's unlikely for an
912 // implementation to support more than 32 bits for samplemask.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700913 assert(phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples <= 64);
Jeff Bolz9af91c52018-09-01 21:53:57 -0500914 uint64_t sampleLocationsMask = 0;
915 for (uint32_t i = 0; i < order->sampleLocationCount; ++i) {
916 const VkCoarseSampleLocationNV *sampleLoc = &order->pSampleLocations[i];
917 if (sampleLoc->pixelX >= sampleOrderInfo->width) {
918 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
919 "VUID-VkCoarseSampleLocationNV-pixelX-02078",
920 "pixelX must be less than the width (in pixels) of the fragment.");
921 }
922 if (sampleLoc->pixelY >= sampleOrderInfo->height) {
923 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
924 "VUID-VkCoarseSampleLocationNV-pixelY-02079",
925 "pixelY must be less than the height (in pixels) of the fragment.");
926 }
927 if (sampleLoc->sample >= order->sampleCount) {
928 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
929 "VUID-VkCoarseSampleLocationNV-sample-02080",
930 "sample must be less than the number of coverage samples in each pixel belonging to the fragment.");
931 }
932 uint32_t idx = sampleLoc->sample + order->sampleCount * (sampleLoc->pixelX + sampleOrderInfo->width * sampleLoc->pixelY);
933 sampleLocationsMask |= 1ULL << idx;
934 }
935
936 uint64_t expectedMask = (order->sampleLocationCount == 64) ? ~0ULL : ((1ULL << order->sampleLocationCount) - 1);
937 if (sampleLocationsMask != expectedMask) {
Dave Houlton142c4cb2018-10-17 15:04:41 -0600938 skip |= log_msg(
939 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
940 "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077",
941 "The array pSampleLocations must contain exactly one entry for "
942 "every combination of valid values for pixelX, pixelY, and sample in the structure VkCoarseSampleOrderCustomNV.");
Jeff Bolz9af91c52018-09-01 21:53:57 -0500943 }
944
945 return skip;
946}
947
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700948bool StatelessValidation::manual_PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache,
949 uint32_t createInfoCount,
950 const VkGraphicsPipelineCreateInfo *pCreateInfos,
951 const VkAllocationCallbacks *pAllocator,
952 VkPipeline *pPipelines) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600953 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600954
955 if (pCreateInfos != nullptr) {
956 for (uint32_t i = 0; i < createInfoCount; ++i) {
Petr Kraus299ba622017-11-24 03:09:03 +0100957 bool has_dynamic_viewport = false;
958 bool has_dynamic_scissor = false;
959 bool has_dynamic_line_width = false;
Jeremy Kniager71fd5f02017-11-15 13:27:03 -0700960 bool has_dynamic_viewport_w_scaling_nv = false;
961 bool has_dynamic_discard_rectangle_ext = false;
962 bool has_dynamic_sample_locations_ext = false;
Jeff Bolz3e71f782018-08-29 23:15:45 -0500963 bool has_dynamic_exclusive_scissor_nv = false;
Jeff Bolz9af91c52018-09-01 21:53:57 -0500964 bool has_dynamic_shading_rate_palette_nv = false;
Petr Kraus299ba622017-11-24 03:09:03 +0100965 if (pCreateInfos[i].pDynamicState != nullptr) {
966 const auto &dynamic_state_info = *pCreateInfos[i].pDynamicState;
967 for (uint32_t state_index = 0; state_index < dynamic_state_info.dynamicStateCount; ++state_index) {
968 const auto &dynamic_state = dynamic_state_info.pDynamicStates[state_index];
969 if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT) has_dynamic_viewport = true;
970 if (dynamic_state == VK_DYNAMIC_STATE_SCISSOR) has_dynamic_scissor = true;
971 if (dynamic_state == VK_DYNAMIC_STATE_LINE_WIDTH) has_dynamic_line_width = true;
Jeremy Kniager71fd5f02017-11-15 13:27:03 -0700972 if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV) has_dynamic_viewport_w_scaling_nv = true;
973 if (dynamic_state == VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT) has_dynamic_discard_rectangle_ext = true;
974 if (dynamic_state == VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT) has_dynamic_sample_locations_ext = true;
Jeff Bolz3e71f782018-08-29 23:15:45 -0500975 if (dynamic_state == VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV) has_dynamic_exclusive_scissor_nv = true;
Dave Houlton142c4cb2018-10-17 15:04:41 -0600976 if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV)
977 has_dynamic_shading_rate_palette_nv = true;
Petr Kraus299ba622017-11-24 03:09:03 +0100978 }
979 }
980
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600981 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
982 if (pCreateInfos[i].pVertexInputState != nullptr) {
983 auto const &vertex_input_state = pCreateInfos[i].pVertexInputState;
Peter Kohautc7d9d392018-07-15 00:34:07 +0200984
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700985 if (vertex_input_state->vertexBindingDescriptionCount > device_limits.maxVertexInputBindings) {
Peter Kohautc7d9d392018-07-15 00:34:07 +0200986 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
987 "VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613",
988 "vkCreateGraphicsPipelines: pararameter "
989 "pCreateInfo[%d].pVertexInputState->vertexBindingDescriptionCount (%u) is "
990 "greater than VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700991 i, vertex_input_state->vertexBindingDescriptionCount, device_limits.maxVertexInputBindings);
Peter Kohautc7d9d392018-07-15 00:34:07 +0200992 }
993
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700994 if (vertex_input_state->vertexAttributeDescriptionCount > device_limits.maxVertexInputAttributes) {
Peter Kohautc7d9d392018-07-15 00:34:07 +0200995 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
996 "VUID-VkPipelineVertexInputStateCreateInfo-vertexAttributeDescriptionCount-00614",
997 "vkCreateGraphicsPipelines: pararameter "
Peter Kohaut9e92c5c2018-07-17 10:32:17 +0200998 "pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptionCount (%u) is "
Peter Kohautc7d9d392018-07-15 00:34:07 +0200999 "greater than VkPhysicalDeviceLimits::maxVertexInputAttributes (%u).",
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001000 i, vertex_input_state->vertexBindingDescriptionCount, device_limits.maxVertexInputAttributes);
Peter Kohautc7d9d392018-07-15 00:34:07 +02001001 }
1002
1003 std::unordered_set<uint32_t> vertex_bindings(vertex_input_state->vertexBindingDescriptionCount);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001004 for (uint32_t d = 0; d < vertex_input_state->vertexBindingDescriptionCount; ++d) {
1005 auto const &vertex_bind_desc = vertex_input_state->pVertexBindingDescriptions[d];
Peter Kohautc7d9d392018-07-15 00:34:07 +02001006 auto const &binding_it = vertex_bindings.find(vertex_bind_desc.binding);
1007 if (binding_it != vertex_bindings.cend()) {
1008 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1009 "VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616",
1010 "vkCreateGraphicsPipelines: parameter "
1011 "pCreateInfo[%d].pVertexInputState->pVertexBindingDescription[%d].binding "
1012 "(%" PRIu32 ") is not distinct.",
1013 i, d, vertex_bind_desc.binding);
1014 }
1015 vertex_bindings.insert(vertex_bind_desc.binding);
1016
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001017 if (vertex_bind_desc.binding >= device_limits.maxVertexInputBindings) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001018 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 -06001019 "VUID-VkVertexInputBindingDescription-binding-00618",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001020 "vkCreateGraphicsPipelines: parameter "
1021 "pCreateInfos[%u].pVertexInputState->pVertexBindingDescriptions[%u].binding (%u) is "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001022 "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001023 i, d, vertex_bind_desc.binding, device_limits.maxVertexInputBindings);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001024 }
1025
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001026 if (vertex_bind_desc.stride > device_limits.maxVertexInputBindingStride) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001027 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 -06001028 "VUID-VkVertexInputBindingDescription-stride-00619",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001029 "vkCreateGraphicsPipelines: parameter "
1030 "pCreateInfos[%u].pVertexInputState->pVertexBindingDescriptions[%u].stride (%u) is greater "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001031 "than VkPhysicalDeviceLimits::maxVertexInputBindingStride (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001032 i, d, vertex_bind_desc.stride, device_limits.maxVertexInputBindingStride);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001033 }
1034 }
1035
Peter Kohautc7d9d392018-07-15 00:34:07 +02001036 std::unordered_set<uint32_t> attribute_locations(vertex_input_state->vertexAttributeDescriptionCount);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001037 for (uint32_t d = 0; d < vertex_input_state->vertexAttributeDescriptionCount; ++d) {
1038 auto const &vertex_attrib_desc = vertex_input_state->pVertexAttributeDescriptions[d];
Peter Kohautc7d9d392018-07-15 00:34:07 +02001039 auto const &location_it = attribute_locations.find(vertex_attrib_desc.location);
1040 if (location_it != attribute_locations.cend()) {
1041 skip |= log_msg(
1042 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1043 "VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-00617",
1044 "vkCreateGraphicsPipelines: parameter "
1045 "pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].location (%u) is not distinct.",
1046 i, d, vertex_attrib_desc.location);
1047 }
1048 attribute_locations.insert(vertex_attrib_desc.location);
1049
1050 auto const &binding_it = vertex_bindings.find(vertex_attrib_desc.binding);
1051 if (binding_it == vertex_bindings.cend()) {
1052 skip |= log_msg(
1053 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1054 "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615",
1055 "vkCreateGraphicsPipelines: parameter "
1056 " pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].binding (%u) does not exist "
1057 "in any pCreateInfo[%d].pVertexInputState->pVertexBindingDescription.",
1058 i, d, vertex_attrib_desc.binding, i);
1059 }
1060
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001061 if (vertex_attrib_desc.location >= device_limits.maxVertexInputAttributes) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001062 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 -06001063 "VUID-VkVertexInputAttributeDescription-location-00620",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001064 "vkCreateGraphicsPipelines: parameter "
1065 "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].location (%u) is "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001066 "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001067 i, d, vertex_attrib_desc.location, device_limits.maxVertexInputAttributes);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001068 }
1069
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001070 if (vertex_attrib_desc.binding >= device_limits.maxVertexInputBindings) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001071 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 -06001072 "VUID-VkVertexInputAttributeDescription-binding-00621",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001073 "vkCreateGraphicsPipelines: parameter "
1074 "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].binding (%u) is "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001075 "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001076 i, d, vertex_attrib_desc.binding, device_limits.maxVertexInputBindings);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001077 }
1078
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001079 if (vertex_attrib_desc.offset > device_limits.maxVertexInputAttributeOffset) {
Mark Lobodzinski88529492018-04-01 10:38:15 -06001080 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 -06001081 "VUID-VkVertexInputAttributeDescription-offset-00622",
Mark Lobodzinski88529492018-04-01 10:38:15 -06001082 "vkCreateGraphicsPipelines: parameter "
1083 "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].offset (%u) is "
1084 "greater than VkPhysicalDeviceLimits::maxVertexInputAttributeOffset (%u).",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001085 i, d, vertex_attrib_desc.offset, device_limits.maxVertexInputAttributeOffset);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001086 }
1087 }
1088 }
1089
1090 if (pCreateInfos[i].pStages != nullptr) {
1091 bool has_control = false;
1092 bool has_eval = false;
1093
1094 for (uint32_t stage_index = 0; stage_index < pCreateInfos[i].stageCount; ++stage_index) {
1095 if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
1096 has_control = true;
1097 } else if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
1098 has_eval = true;
1099 }
1100 }
1101
1102 // pTessellationState is ignored without both tessellation control and tessellation evaluation shaders stages
1103 if (has_control && has_eval) {
1104 if (pCreateInfos[i].pTessellationState == nullptr) {
1105 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 -06001106 "VUID-VkGraphicsPipelineCreateInfo-pStages-00731",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001107 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pStages includes a tessellation control "
1108 "shader stage and a tessellation evaluation shader stage, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001109 "pCreateInfos[%d].pTessellationState must not be NULL.",
1110 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001111 } else {
1112 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001113 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001114 ParameterName("pCreateInfos[%i].pTessellationState->pNext", ParameterName::IndexVector{i}), NULL,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001115 pCreateInfos[i].pTessellationState->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06001116 "VUID-VkGraphicsPipelineCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001117
1118 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001119 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001120 ParameterName("pCreateInfos[%i].pTessellationState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001121 pCreateInfos[i].pTessellationState->flags,
1122 "VUID-VkPipelineTessellationStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001123
1124 if (pCreateInfos[i].pTessellationState->sType !=
1125 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) {
1126 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 -06001127 "VUID-VkPipelineTessellationStateCreateInfo-sType-sType",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001128 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pTessellationState->sType must "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001129 "be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO.",
1130 i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001131 }
1132
1133 if (pCreateInfos[i].pTessellationState->patchControlPoints == 0 ||
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001134 pCreateInfos[i].pTessellationState->patchControlPoints > device_limits.maxTessellationPatchSize) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001135 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 -06001136 "VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001137 "vkCreateGraphicsPipelines: invalid parameter "
1138 "pCreateInfos[%d].pTessellationState->patchControlPoints value %u. patchControlPoints "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001139 "should be >0 and <=%u.",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001140 i, pCreateInfos[i].pTessellationState->patchControlPoints,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001141 device_limits.maxTessellationPatchSize);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001142 }
1143 }
1144 }
1145 }
1146
1147 // pViewportState, pMultisampleState, pDepthStencilState, and pColorBlendState ignored when rasterization is disabled
1148 if ((pCreateInfos[i].pRasterizationState != nullptr) &&
1149 (pCreateInfos[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
1150 if (pCreateInfos[i].pViewportState == nullptr) {
Petr Krausa6103552017-11-16 21:21:58 +01001151 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 -06001152 VK_NULL_HANDLE, "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750",
Petr Krausa6103552017-11-16 21:21:58 +01001153 "vkCreateGraphicsPipelines: Rasterization is enabled (pCreateInfos[%" PRIu32
1154 "].pRasterizationState->rasterizerDiscardEnable is VK_FALSE), but pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001155 "].pViewportState (=NULL) is not a valid pointer.",
1156 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001157 } else {
Petr Krausa6103552017-11-16 21:21:58 +01001158 const auto &viewport_state = *pCreateInfos[i].pViewportState;
1159
1160 if (viewport_state.sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) {
1161 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 -06001162 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-sType-sType",
Petr Krausa6103552017-11-16 21:21:58 +01001163 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001164 "].pViewportState->sType is not VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO.",
1165 i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001166 }
1167
Petr Krausa6103552017-11-16 21:21:58 +01001168 const VkStructureType allowed_structs_VkPipelineViewportStateCreateInfo[] = {
1169 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV,
Jeff Bolz3e71f782018-08-29 23:15:45 -05001170 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV,
1171 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV,
Jeff Bolz9af91c52018-09-01 21:53:57 -05001172 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV,
1173 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV,
Jeff Bolz3e71f782018-08-29 23:15:45 -05001174 };
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001175 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001176 "vkCreateGraphicsPipelines",
Petr Krausa6103552017-11-16 21:21:58 +01001177 ParameterName("pCreateInfos[%i].pViewportState->pNext", ParameterName::IndexVector{i}),
Jeff Bolz9af91c52018-09-01 21:53:57 -05001178 "VkPipelineViewportSwizzleStateCreateInfoNV, VkPipelineViewportWScalingStateCreateInfoNV, "
Jeff Bolzb8a8dd02018-09-18 02:39:24 -05001179 "VkPipelineViewportExclusiveScissorStateCreateInfoNV, VkPipelineViewportShadingRateImageStateCreateInfoNV, "
1180 "VkPipelineViewportCoarseSampleOrderStateCreateInfoNV",
Petr Krausa6103552017-11-16 21:21:58 +01001181 viewport_state.pNext, ARRAY_SIZE(allowed_structs_VkPipelineViewportStateCreateInfo),
Dave Houlton413a6782018-05-22 13:01:54 -06001182 allowed_structs_VkPipelineViewportStateCreateInfo, 65,
1183 "VUID-VkPipelineViewportStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001184
1185 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001186 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001187 ParameterName("pCreateInfos[%i].pViewportState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001188 viewport_state.flags, "VUID-VkPipelineViewportStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001189
Dave Houlton142c4cb2018-10-17 15:04:41 -06001190 auto exclusive_scissor_struct = lvl_find_in_chain<VkPipelineViewportExclusiveScissorStateCreateInfoNV>(
1191 pCreateInfos[i].pViewportState->pNext);
1192 auto shading_rate_image_struct = lvl_find_in_chain<VkPipelineViewportShadingRateImageStateCreateInfoNV>(
1193 pCreateInfos[i].pViewportState->pNext);
1194 auto coarse_sample_order_struct = lvl_find_in_chain<VkPipelineViewportCoarseSampleOrderStateCreateInfoNV>(
1195 pCreateInfos[i].pViewportState->pNext);
Chris Mayer328d8212018-12-11 14:16:18 +01001196 const auto vp_swizzle_struct =
1197 lvl_find_in_chain<VkPipelineViewportSwizzleStateCreateInfoNV>(pCreateInfos[i].pViewportState->pNext);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001198
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001199 if (!physical_device_features.multiViewport) {
Petr Krausa6103552017-11-16 21:21:58 +01001200 if (viewport_state.viewportCount != 1) {
1201 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 -06001202 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
Petr Krausa6103552017-11-16 21:21:58 +01001203 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1204 "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001205 ") is not 1.",
1206 i, viewport_state.viewportCount);
Petr Krausa6103552017-11-16 21:21:58 +01001207 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001208
Petr Krausa6103552017-11-16 21:21:58 +01001209 if (viewport_state.scissorCount != 1) {
1210 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 -06001211 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
Petr Krausa6103552017-11-16 21:21:58 +01001212 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1213 "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->scissorCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001214 ") is not 1.",
1215 i, viewport_state.scissorCount);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001216 }
Jeff Bolz3e71f782018-08-29 23:15:45 -05001217
Dave Houlton142c4cb2018-10-17 15:04:41 -06001218 if (exclusive_scissor_struct && (exclusive_scissor_struct->exclusiveScissorCount != 0 &&
1219 exclusive_scissor_struct->exclusiveScissorCount != 1)) {
1220 skip |=
1221 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1222 VK_NULL_HANDLE,
1223 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
1224 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1225 "disabled, but pCreateInfos[%" PRIu32
1226 "] VkPipelineViewportExclusiveScissorStateCreateInfoNV::exclusiveScissorCount (=%" PRIu32
1227 ") is not 1.",
1228 i, exclusive_scissor_struct->exclusiveScissorCount);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001229 }
1230
Jeff Bolz9af91c52018-09-01 21:53:57 -05001231 if (shading_rate_image_struct &&
1232 (shading_rate_image_struct->viewportCount != 0 && shading_rate_image_struct->viewportCount != 1)) {
1233 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 -06001234 VK_NULL_HANDLE,
1235 "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054",
Jeff Bolz9af91c52018-09-01 21:53:57 -05001236 "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
Dave Houlton142c4cb2018-10-17 15:04:41 -06001237 "disabled, but pCreateInfos[%" PRIu32
1238 "] VkPipelineViewportShadingRateImageStateCreateInfoNV::viewportCount (=%" PRIu32
Jeff Bolzb8a8dd02018-09-18 02:39:24 -05001239 ") is neither 0 nor 1.",
Jeff Bolz9af91c52018-09-01 21:53:57 -05001240 i, shading_rate_image_struct->viewportCount);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001241 }
1242
Petr Krausa6103552017-11-16 21:21:58 +01001243 } else { // multiViewport enabled
1244 if (viewport_state.viewportCount == 0) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001245 skip |= log_msg(
1246 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001247 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001248 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->viewportCount is 0.", i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001249 } else if (viewport_state.viewportCount > device_limits.maxViewports) {
Petr Krausa6103552017-11-16 21:21:58 +01001250 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 -06001251 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
Petr Krausa6103552017-11-16 21:21:58 +01001252 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1253 "].pViewportState->viewportCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001254 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001255 i, viewport_state.viewportCount, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001256 }
Petr Krausa6103552017-11-16 21:21:58 +01001257
1258 if (viewport_state.scissorCount == 0) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001259 skip |= log_msg(
1260 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001261 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001262 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->scissorCount is 0.", i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001263 } else if (viewport_state.scissorCount > device_limits.maxViewports) {
Petr Krausa6103552017-11-16 21:21:58 +01001264 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 -06001265 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219",
Petr Krausa6103552017-11-16 21:21:58 +01001266 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1267 "].pViewportState->scissorCount (=%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001268 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001269 i, viewport_state.scissorCount, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001270 }
1271 }
1272
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001273 if (exclusive_scissor_struct && exclusive_scissor_struct->exclusiveScissorCount > device_limits.maxViewports) {
1274 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1275 VK_NULL_HANDLE,
1276 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
1277 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "] exclusiveScissorCount (=%" PRIu32
1278 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
1279 i, exclusive_scissor_struct->exclusiveScissorCount, device_limits.maxViewports);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001280 }
1281
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001282 if (shading_rate_image_struct && shading_rate_image_struct->viewportCount > device_limits.maxViewports) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001283 skip |=
1284 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1285 VK_NULL_HANDLE, "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02055",
1286 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1287 "] VkPipelineViewportShadingRateImageStateCreateInfoNV viewportCount (=%" PRIu32
1288 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001289 i, shading_rate_image_struct->viewportCount, device_limits.maxViewports);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001290 }
1291
Petr Krausa6103552017-11-16 21:21:58 +01001292 if (viewport_state.scissorCount != viewport_state.viewportCount) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001293 skip |=
1294 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
Dave Houlton413a6782018-05-22 13:01:54 -06001295 VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001296 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->scissorCount (=%" PRIu32
1297 ") is not identical to pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32 ").",
1298 i, viewport_state.scissorCount, i, viewport_state.viewportCount);
Petr Krausa6103552017-11-16 21:21:58 +01001299 }
1300
Dave Houlton142c4cb2018-10-17 15:04:41 -06001301 if (exclusive_scissor_struct && exclusive_scissor_struct->exclusiveScissorCount != 0 &&
Jeff Bolz3e71f782018-08-29 23:15:45 -05001302 exclusive_scissor_struct->exclusiveScissorCount != viewport_state.viewportCount) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001303 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1304 VK_NULL_HANDLE,
1305 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029",
1306 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "] exclusiveScissorCount (=%" PRIu32
1307 ") must be zero or identical to pCreateInfos[%" PRIu32
1308 "].pViewportState->viewportCount (=%" PRIu32 ").",
1309 i, exclusive_scissor_struct->exclusiveScissorCount, i, viewport_state.viewportCount);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001310 }
1311
Dave Houlton142c4cb2018-10-17 15:04:41 -06001312 if (shading_rate_image_struct && shading_rate_image_struct->shadingRateImageEnable &&
Jeff Bolz9af91c52018-09-01 21:53:57 -05001313 shading_rate_image_struct->viewportCount != viewport_state.viewportCount) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001314 skip |= log_msg(
1315 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1316 "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056",
1317 "vkCreateGraphicsPipelines: If shadingRateImageEnable is enabled, pCreateInfos[%" PRIu32
1318 "] "
1319 "VkPipelineViewportShadingRateImageStateCreateInfoNV viewportCount (=%" PRIu32
1320 ") must identical to pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32 ").",
1321 i, shading_rate_image_struct->viewportCount, i, viewport_state.viewportCount);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001322 }
1323
Petr Krausa6103552017-11-16 21:21:58 +01001324 if (!has_dynamic_viewport && viewport_state.viewportCount > 0 && viewport_state.pViewports == nullptr) {
1325 skip |= log_msg(
1326 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 -06001327 "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747",
Petr Krausa6103552017-11-16 21:21:58 +01001328 "vkCreateGraphicsPipelines: The viewport state is static (pCreateInfos[%" PRIu32
1329 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_VIEWPORT), but pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001330 "].pViewportState->pViewports (=NULL) is an invalid pointer.",
1331 i, i);
Petr Krausa6103552017-11-16 21:21:58 +01001332 }
1333
1334 if (!has_dynamic_scissor && viewport_state.scissorCount > 0 && viewport_state.pScissors == nullptr) {
1335 skip |= log_msg(
1336 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 -06001337 "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748",
Petr Krausa6103552017-11-16 21:21:58 +01001338 "vkCreateGraphicsPipelines: The scissor state is static (pCreateInfos[%" PRIu32
1339 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_SCISSOR), but pCreateInfos[%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001340 "].pViewportState->pScissors (=NULL) is an invalid pointer.",
1341 i, i);
Petr Krausa6103552017-11-16 21:21:58 +01001342 }
1343
Jeff Bolz3e71f782018-08-29 23:15:45 -05001344 if (!has_dynamic_exclusive_scissor_nv && exclusive_scissor_struct &&
Dave Houlton142c4cb2018-10-17 15:04:41 -06001345 exclusive_scissor_struct->exclusiveScissorCount > 0 &&
1346 exclusive_scissor_struct->pExclusiveScissors == nullptr) {
1347 skip |=
1348 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1349 VK_NULL_HANDLE, "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-pDynamicStates-02030",
1350 "vkCreateGraphicsPipelines: The exclusive scissor state is static (pCreateInfos[%" PRIu32
1351 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV), but "
1352 "pCreateInfos[%" PRIu32 "] pExclusiveScissors (=NULL) is an invalid pointer.",
1353 i, i);
Jeff Bolz3e71f782018-08-29 23:15:45 -05001354 }
1355
Jeff Bolz9af91c52018-09-01 21:53:57 -05001356 if (!has_dynamic_shading_rate_palette_nv && shading_rate_image_struct &&
Dave Houlton142c4cb2018-10-17 15:04:41 -06001357 shading_rate_image_struct->viewportCount > 0 &&
1358 shading_rate_image_struct->pShadingRatePalettes == nullptr) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05001359 skip |= log_msg(
1360 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1361 "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-pDynamicStates-02057",
1362 "vkCreateGraphicsPipelines: The shading rate palette state is static (pCreateInfos[%" PRIu32
Dave Houlton142c4cb2018-10-17 15:04:41 -06001363 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV), "
1364 "but pCreateInfos[%" PRIu32 "] pShadingRatePalettes (=NULL) is an invalid pointer.",
Jeff Bolz9af91c52018-09-01 21:53:57 -05001365 i, i);
1366 }
1367
Chris Mayer328d8212018-12-11 14:16:18 +01001368 if (vp_swizzle_struct) {
1369 if (vp_swizzle_struct->viewportCount != viewport_state.viewportCount) {
1370 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1371 VK_NULL_HANDLE, "VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215",
1372 "vkCreateGraphicsPipelines: The viewport swizzle state vieport count of %" PRIu32
1373 " does "
1374 "not match the viewport count of %" PRIu32 " in VkPipelineViewportStateCreateInfo.",
1375 vp_swizzle_struct->viewportCount, viewport_state.viewportCount);
1376 }
1377 }
1378
Petr Krausb3fcdb42018-01-09 22:09:09 +01001379 // validate the VkViewports
1380 if (!has_dynamic_viewport && viewport_state.pViewports) {
1381 for (uint32_t viewport_i = 0; viewport_i < viewport_state.viewportCount; ++viewport_i) {
1382 const auto &viewport = viewport_state.pViewports[viewport_i]; // will crash on invalid ptr
1383 const char fn_name[] = "vkCreateGraphicsPipelines";
1384 const std::string param_name = "pCreateInfos[" + std::to_string(i) + "].pViewportState->pViewports[" +
1385 std::to_string(viewport_i) + "]";
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001386 skip |= manual_PreCallValidateViewport(viewport, fn_name, param_name.c_str(),
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001387 VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
Petr Krausb3fcdb42018-01-09 22:09:09 +01001388 }
1389 }
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001390
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001391 if (has_dynamic_viewport_w_scaling_nv && !device_extensions.vk_nv_clip_space_w_scaling) {
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001392 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 -06001393 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001394 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -07001395 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, but "
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001396 "VK_NV_clip_space_w_scaling extension is not enabled.",
1397 i);
1398 }
1399
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001400 if (has_dynamic_discard_rectangle_ext && !device_extensions.vk_ext_discard_rectangles) {
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001401 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 -06001402 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001403 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -07001404 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, but "
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001405 "VK_EXT_discard_rectangles extension is not enabled.",
1406 i);
1407 }
1408
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001409 if (has_dynamic_sample_locations_ext && !device_extensions.vk_ext_sample_locations) {
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001410 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 -06001411 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001412 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
Dave Houltona9df0ce2018-02-07 10:51:23 -07001413 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, but "
Jeremy Kniager71fd5f02017-11-15 13:27:03 -07001414 "VK_EXT_sample_locations extension is not enabled.",
1415 i);
1416 }
Jeff Bolz3e71f782018-08-29 23:15:45 -05001417
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001418 if (has_dynamic_exclusive_scissor_nv && !device_extensions.vk_nv_scissor_exclusive) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05001419 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1420 VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
1421 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1422 "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV, but "
1423 "VK_NV_scissor_exclusive extension is not enabled.",
1424 i);
1425 }
Jeff Bolz9af91c52018-09-01 21:53:57 -05001426
1427 if (coarse_sample_order_struct &&
1428 coarse_sample_order_struct->sampleOrderType != VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV &&
1429 coarse_sample_order_struct->customSampleOrderCount != 0) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06001430 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1431 VK_NULL_HANDLE,
1432 "VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-sampleOrderType-02072",
1433 "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1434 "] "
1435 "VkPipelineViewportCoarseSampleOrderStateCreateInfoNV sampleOrderType is not "
1436 "VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV and customSampleOrderCount is not 0.",
1437 i);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001438 }
1439
1440 if (coarse_sample_order_struct) {
1441 for (uint32_t order_i = 0; order_i < coarse_sample_order_struct->customSampleOrderCount; ++order_i) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001442 skip |= ValidateCoarseSampleOrderCustomNV(&coarse_sample_order_struct->pCustomSampleOrders[order_i]);
Jeff Bolz9af91c52018-09-01 21:53:57 -05001443 }
1444 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001445 }
1446
1447 if (pCreateInfos[i].pMultisampleState == nullptr) {
1448 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 -06001449 "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001450 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pRasterizationState->rasterizerDiscardEnable "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001451 "is VK_FALSE, pCreateInfos[%d].pMultisampleState must not be NULL.",
1452 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001453 } else {
Dave Houltonb3bbec72018-01-17 10:13:33 -07001454 const VkStructureType valid_next_stypes[] = {LvlTypeMap<VkPipelineCoverageModulationStateCreateInfoNV>::kSType,
1455 LvlTypeMap<VkPipelineCoverageToColorStateCreateInfoNV>::kSType,
1456 LvlTypeMap<VkPipelineSampleLocationsStateCreateInfoEXT>::kSType};
Mike Schuchardt97662b02017-12-06 13:31:29 -07001457 const char *valid_struct_names =
Dave Houltona9df0ce2018-02-07 10:51:23 -07001458 "VkPipelineCoverageModulationStateCreateInfoNV, VkPipelineCoverageToColorStateCreateInfoNV, "
John Zulauf96b0e422017-11-14 11:43:19 -07001459 "VkPipelineSampleLocationsStateCreateInfoEXT";
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001460 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001461 "vkCreateGraphicsPipelines",
John Zulauf96b0e422017-11-14 11:43:19 -07001462 ParameterName("pCreateInfos[%i].pMultisampleState->pNext", ParameterName::IndexVector{i}),
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001463 valid_struct_names, pCreateInfos[i].pMultisampleState->pNext, 3, valid_next_stypes,
1464 GeneratedVulkanHeaderVersion, "VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001465
1466 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001467 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001468 ParameterName("pCreateInfos[%i].pMultisampleState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001469 pCreateInfos[i].pMultisampleState->flags, "VUID-VkPipelineMultisampleStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001470
1471 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001472 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001473 ParameterName("pCreateInfos[%i].pMultisampleState->sampleShadingEnable", ParameterName::IndexVector{i}),
1474 pCreateInfos[i].pMultisampleState->sampleShadingEnable);
1475
1476 skip |= validate_array(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001477 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001478 ParameterName("pCreateInfos[%i].pMultisampleState->rasterizationSamples", ParameterName::IndexVector{i}),
1479 ParameterName("pCreateInfos[%i].pMultisampleState->pSampleMask", ParameterName::IndexVector{i}),
Gabríel Arthúr Pétursson092b29b2018-03-21 22:44:11 +00001480 pCreateInfos[i].pMultisampleState->rasterizationSamples, &pCreateInfos[i].pMultisampleState->pSampleMask,
Dave Houlton413a6782018-05-22 13:01:54 -06001481 true, false, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001482
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->alphaToCoverageEnable", ParameterName::IndexVector{i}),
1486 pCreateInfos[i].pMultisampleState->alphaToCoverageEnable);
1487
1488 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001489 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001490 ParameterName("pCreateInfos[%i].pMultisampleState->alphaToOneEnable", ParameterName::IndexVector{i}),
1491 pCreateInfos[i].pMultisampleState->alphaToOneEnable);
1492
1493 if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) {
1494 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 -06001495 kVUID_PVError_InvalidStructSType,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001496 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pMultisampleState->sType must be "
1497 "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO",
1498 i);
1499 }
John Zulauf7acac592017-11-06 11:15:53 -07001500 if (pCreateInfos[i].pMultisampleState->sampleShadingEnable == VK_TRUE) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001501 if (!physical_device_features.sampleRateShading) {
John Zulauf7acac592017-11-06 11:15:53 -07001502 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 -06001503 "VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784",
John Zulauf7acac592017-11-06 11:15:53 -07001504 "vkCreateGraphicsPipelines(): parameter "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001505 "pCreateInfos[%d].pMultisampleState->sampleShadingEnable.",
1506 i);
John Zulauf7acac592017-11-06 11:15:53 -07001507 }
1508 // TODO Add documentation issue about when minSampleShading must be in range and when it is ignored
1509 // For now a "least noise" test *only* when sampleShadingEnable is VK_TRUE.
1510 if (!in_inclusive_range(pCreateInfos[i].pMultisampleState->minSampleShading, 0.F, 1.0F)) {
1511 skip |= log_msg(
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001512 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06001513 "VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786",
Mark Lobodzinski88529492018-04-01 10:38:15 -06001514 "vkCreateGraphicsPipelines(): parameter pCreateInfos[%d].pMultisampleState->minSampleShading.", i);
John Zulauf7acac592017-11-06 11:15:53 -07001515 }
1516 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001517 }
1518
Petr Krause91f7a12017-12-14 20:57:36 +01001519 bool uses_color_attachment = false;
1520 bool uses_depthstencil_attachment = false;
1521 {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001522 const auto subpasses_uses_it = renderpasses_states.find(pCreateInfos[i].renderPass);
1523 if (subpasses_uses_it != renderpasses_states.end()) {
Petr Krause91f7a12017-12-14 20:57:36 +01001524 const auto &subpasses_uses = subpasses_uses_it->second;
1525 if (subpasses_uses.subpasses_using_color_attachment.count(pCreateInfos[i].subpass))
1526 uses_color_attachment = true;
1527 if (subpasses_uses.subpasses_using_depthstencil_attachment.count(pCreateInfos[i].subpass))
1528 uses_depthstencil_attachment = true;
1529 }
1530 }
1531
1532 if (pCreateInfos[i].pDepthStencilState != nullptr && uses_depthstencil_attachment) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001533 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001534 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001535 ParameterName("pCreateInfos[%i].pDepthStencilState->pNext", ParameterName::IndexVector{i}), NULL,
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001536 pCreateInfos[i].pDepthStencilState->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06001537 "VUID-VkPipelineDepthStencilStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001538
1539 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001540 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001541 ParameterName("pCreateInfos[%i].pDepthStencilState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001542 pCreateInfos[i].pDepthStencilState->flags, "VUID-VkPipelineDepthStencilStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001543
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->depthTestEnable", ParameterName::IndexVector{i}),
1547 pCreateInfos[i].pDepthStencilState->depthTestEnable);
1548
1549 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001550 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001551 ParameterName("pCreateInfos[%i].pDepthStencilState->depthWriteEnable", ParameterName::IndexVector{i}),
1552 pCreateInfos[i].pDepthStencilState->depthWriteEnable);
1553
1554 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001555 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001556 ParameterName("pCreateInfos[%i].pDepthStencilState->depthCompareOp", ParameterName::IndexVector{i}),
1557 "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->depthCompareOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001558 "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001559
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->depthBoundsTestEnable", ParameterName::IndexVector{i}),
1563 pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable);
1564
1565 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001566 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001567 ParameterName("pCreateInfos[%i].pDepthStencilState->stencilTestEnable", ParameterName::IndexVector{i}),
1568 pCreateInfos[i].pDepthStencilState->stencilTestEnable);
1569
1570 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001571 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001572 ParameterName("pCreateInfos[%i].pDepthStencilState->front.failOp", ParameterName::IndexVector{i}),
1573 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.failOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001574 "VUID-VkStencilOpState-failOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001575
1576 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001577 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001578 ParameterName("pCreateInfos[%i].pDepthStencilState->front.passOp", ParameterName::IndexVector{i}),
1579 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.passOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001580 "VUID-VkStencilOpState-passOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001581
1582 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001583 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001584 ParameterName("pCreateInfos[%i].pDepthStencilState->front.depthFailOp", ParameterName::IndexVector{i}),
1585 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.depthFailOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001586 "VUID-VkStencilOpState-depthFailOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001587
1588 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001589 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001590 ParameterName("pCreateInfos[%i].pDepthStencilState->front.compareOp", ParameterName::IndexVector{i}),
1591 "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->front.compareOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001592 "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001593
1594 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001595 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001596 ParameterName("pCreateInfos[%i].pDepthStencilState->back.failOp", ParameterName::IndexVector{i}),
1597 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.failOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001598 "VUID-VkStencilOpState-failOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001599
1600 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001601 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001602 ParameterName("pCreateInfos[%i].pDepthStencilState->back.passOp", ParameterName::IndexVector{i}),
1603 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.passOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001604 "VUID-VkStencilOpState-passOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001605
1606 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001607 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001608 ParameterName("pCreateInfos[%i].pDepthStencilState->back.depthFailOp", ParameterName::IndexVector{i}),
1609 "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.depthFailOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001610 "VUID-VkStencilOpState-depthFailOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001611
1612 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001613 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001614 ParameterName("pCreateInfos[%i].pDepthStencilState->back.compareOp", ParameterName::IndexVector{i}),
1615 "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->back.compareOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001616 "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001617
1618 if (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) {
1619 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 -06001620 kVUID_PVError_InvalidStructSType,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001621 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pDepthStencilState->sType must be "
1622 "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO",
1623 i);
1624 }
1625 }
1626
Shannon McPherson9b9532b2018-10-24 12:00:09 -06001627 const VkStructureType allowed_structs_VkPipelineColorBlendStateCreateInfo[] = {
1628 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT};
1629
Petr Krause91f7a12017-12-14 20:57:36 +01001630 if (pCreateInfos[i].pColorBlendState != nullptr && uses_color_attachment) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001631 skip |= validate_struct_pnext(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001632 "vkCreateGraphicsPipelines",
Shannon McPherson9b9532b2018-10-24 12:00:09 -06001633 ParameterName("pCreateInfos[%i].pColorBlendState->pNext", ParameterName::IndexVector{i}),
1634 "VkPipelineColorBlendAdvancedStateCreateInfoEXT", pCreateInfos[i].pColorBlendState->pNext,
1635 ARRAY_SIZE(allowed_structs_VkPipelineColorBlendStateCreateInfo),
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001636 allowed_structs_VkPipelineColorBlendStateCreateInfo, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06001637 "VUID-VkPipelineColorBlendStateCreateInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001638
1639 skip |= validate_reserved_flags(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001640 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001641 ParameterName("pCreateInfos[%i].pColorBlendState->flags", ParameterName::IndexVector{i}),
Dave Houlton413a6782018-05-22 13:01:54 -06001642 pCreateInfos[i].pColorBlendState->flags, "VUID-VkPipelineColorBlendStateCreateInfo-flags-zerobitmask");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001643
1644 skip |= validate_bool32(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001645 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001646 ParameterName("pCreateInfos[%i].pColorBlendState->logicOpEnable", ParameterName::IndexVector{i}),
1647 pCreateInfos[i].pColorBlendState->logicOpEnable);
1648
1649 skip |= validate_array(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001650 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001651 ParameterName("pCreateInfos[%i].pColorBlendState->attachmentCount", ParameterName::IndexVector{i}),
1652 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments", ParameterName::IndexVector{i}),
Gabríel Arthúr Pétursson092b29b2018-03-21 22:44:11 +00001653 pCreateInfos[i].pColorBlendState->attachmentCount, &pCreateInfos[i].pColorBlendState->pAttachments, false,
Dave Houlton413a6782018-05-22 13:01:54 -06001654 true, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001655
1656 if (pCreateInfos[i].pColorBlendState->pAttachments != NULL) {
1657 for (uint32_t attachmentIndex = 0; attachmentIndex < pCreateInfos[i].pColorBlendState->attachmentCount;
1658 ++attachmentIndex) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001659 skip |= validate_bool32("vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001660 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].blendEnable",
1661 ParameterName::IndexVector{i, attachmentIndex}),
1662 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].blendEnable);
1663
1664 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001665 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001666 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].srcColorBlendFactor",
1667 ParameterName::IndexVector{i, attachmentIndex}),
1668 "VkBlendFactor", AllVkBlendFactorEnums,
1669 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcColorBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001670 "VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001671
1672 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001673 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001674 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].dstColorBlendFactor",
1675 ParameterName::IndexVector{i, attachmentIndex}),
1676 "VkBlendFactor", AllVkBlendFactorEnums,
1677 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstColorBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001678 "VUID-VkPipelineColorBlendAttachmentState-dstColorBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001679
1680 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001681 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001682 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].colorBlendOp",
1683 ParameterName::IndexVector{i, attachmentIndex}),
1684 "VkBlendOp", AllVkBlendOpEnums,
1685 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorBlendOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001686 "VUID-VkPipelineColorBlendAttachmentState-colorBlendOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001687
1688 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001689 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001690 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].srcAlphaBlendFactor",
1691 ParameterName::IndexVector{i, attachmentIndex}),
1692 "VkBlendFactor", AllVkBlendFactorEnums,
1693 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcAlphaBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001694 "VUID-VkPipelineColorBlendAttachmentState-srcAlphaBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001695
1696 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001697 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001698 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].dstAlphaBlendFactor",
1699 ParameterName::IndexVector{i, attachmentIndex}),
1700 "VkBlendFactor", AllVkBlendFactorEnums,
1701 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstAlphaBlendFactor,
Dave Houlton413a6782018-05-22 13:01:54 -06001702 "VUID-VkPipelineColorBlendAttachmentState-dstAlphaBlendFactor-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001703
1704 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001705 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001706 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].alphaBlendOp",
1707 ParameterName::IndexVector{i, attachmentIndex}),
1708 "VkBlendOp", AllVkBlendOpEnums,
1709 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].alphaBlendOp,
Dave Houlton413a6782018-05-22 13:01:54 -06001710 "VUID-VkPipelineColorBlendAttachmentState-alphaBlendOp-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001711
1712 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001713 validate_flags("vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001714 ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].colorWriteMask",
1715 ParameterName::IndexVector{i, attachmentIndex}),
1716 "VkColorComponentFlagBits", AllVkColorComponentFlagBits,
1717 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorWriteMask,
Dave Houlton413a6782018-05-22 13:01:54 -06001718 false, false, "VUID-VkPipelineColorBlendAttachmentState-colorWriteMask-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001719 }
1720 }
1721
1722 if (pCreateInfos[i].pColorBlendState->sType != VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO) {
1723 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 -06001724 kVUID_PVError_InvalidStructSType,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001725 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pColorBlendState->sType must be "
1726 "VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO",
1727 i);
1728 }
1729
1730 // If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value
1731 if (pCreateInfos[i].pColorBlendState->logicOpEnable == VK_TRUE) {
1732 skip |= validate_ranged_enum(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001733 "vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001734 ParameterName("pCreateInfos[%i].pColorBlendState->logicOp", ParameterName::IndexVector{i}), "VkLogicOp",
Dave Houlton413a6782018-05-22 13:01:54 -06001735 AllVkLogicOpEnums, pCreateInfos[i].pColorBlendState->logicOp,
1736 "VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001737 }
1738 }
1739 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001740
Petr Kraus9752aae2017-11-24 03:05:50 +01001741 if (pCreateInfos[i].flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) {
1742 if (pCreateInfos[i].basePipelineIndex != -1) {
1743 if (pCreateInfos[i].basePipelineHandle != VK_NULL_HANDLE) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001744 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 -06001745 "VUID-VkGraphicsPipelineCreateInfo-flags-00724",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001746 "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineHandle, must be "
1747 "VK_NULL_HANDLE if pCreateInfos->flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001748 "and pCreateInfos->basePipelineIndex is not -1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001749 }
1750 }
1751
Petr Kraus9752aae2017-11-24 03:05:50 +01001752 if (pCreateInfos[i].basePipelineHandle != VK_NULL_HANDLE) {
1753 if (pCreateInfos[i].basePipelineIndex != -1) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001754 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 -06001755 "VUID-VkGraphicsPipelineCreateInfo-flags-00725",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001756 "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineIndex, must be -1 if "
1757 "pCreateInfos->flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag and "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001758 "pCreateInfos->basePipelineHandle is not VK_NULL_HANDLE.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001759 }
1760 }
1761 }
1762
Petr Kraus9752aae2017-11-24 03:05:50 +01001763 if (pCreateInfos[i].pRasterizationState) {
1764 if ((pCreateInfos[i].pRasterizationState->polygonMode != VK_POLYGON_MODE_FILL) &&
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001765 (physical_device_features.fillModeNonSolid == false)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001766 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 -06001767 kVUID_PVError_DeviceFeature,
Dave Houltona9df0ce2018-02-07 10:51:23 -07001768 "vkCreateGraphicsPipelines parameter, VkPolygonMode "
1769 "pCreateInfos->pRasterizationState->polygonMode cannot be VK_POLYGON_MODE_POINT or "
1770 "VK_POLYGON_MODE_LINE if VkPhysicalDeviceFeatures->fillModeNonSolid is false.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001771 }
Petr Kraus299ba622017-11-24 03:09:03 +01001772
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001773 if (!has_dynamic_line_width && !physical_device_features.wideLines &&
Petr Kraus299ba622017-11-24 03:09:03 +01001774 (pCreateInfos[i].pRasterizationState->lineWidth != 1.0f)) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001775 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 0,
1776 "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00749",
1777 "The line width state is static (pCreateInfos[%" PRIu32
1778 "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_LINE_WIDTH) and "
1779 "VkPhysicalDeviceFeatures::wideLines is disabled, but pCreateInfos[%" PRIu32
1780 "].pRasterizationState->lineWidth (=%f) is not 1.0.",
1781 i, i, pCreateInfos[i].pRasterizationState->lineWidth);
Petr Kraus299ba622017-11-24 03:09:03 +01001782 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001783 }
1784
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001785 for (size_t j = 0; j < pCreateInfos[i].stageCount; j++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001786 skip |= validate_string("vkCreateGraphicsPipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001787 ParameterName("pCreateInfos[%i].pStages[%i].pName", ParameterName::IndexVector{i, j}),
Mark Lobodzinskiebee3552018-05-29 09:55:54 -06001788 "VUID-VkGraphicsPipelineCreateInfo-pStages-parameter", pCreateInfos[i].pStages[j].pName);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001789 }
1790 }
1791 }
1792
1793 return skip;
1794}
1795
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001796bool StatelessValidation::manual_PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache,
1797 uint32_t createInfoCount,
1798 const VkComputePipelineCreateInfo *pCreateInfos,
1799 const VkAllocationCallbacks *pAllocator,
1800 VkPipeline *pPipelines) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001801 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001802 for (uint32_t i = 0; i < createInfoCount; i++) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001803 skip |= validate_string("vkCreateComputePipelines",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001804 ParameterName("pCreateInfos[%i].stage.pName", ParameterName::IndexVector{i}),
Mark Lobodzinskiebee3552018-05-29 09:55:54 -06001805 "VUID-VkPipelineShaderStageCreateInfo-pName-parameter", pCreateInfos[i].stage.pName);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001806 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001807 return skip;
1808}
1809
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001810bool StatelessValidation::manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001811 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001812 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001813
1814 if (pCreateInfo != nullptr) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001815 const auto &features = physical_device_features;
1816 const auto &limits = device_limits;
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001817
John Zulauf71968502017-10-26 13:51:15 -06001818 if (pCreateInfo->anisotropyEnable == VK_TRUE) {
1819 if (!in_inclusive_range(pCreateInfo->maxAnisotropy, 1.0F, limits.maxSamplerAnisotropy)) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001820 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 -06001821 "VUID-VkSamplerCreateInfo-anisotropyEnable-01071",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001822 "vkCreateSampler(): value of %s must be in range [1.0, %f] %s, but %f found.",
John Zulauf71968502017-10-26 13:51:15 -06001823 "pCreateInfo->maxAnisotropy", limits.maxSamplerAnisotropy,
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001824 "VkPhysicalDeviceLimits::maxSamplerAnistropy", pCreateInfo->maxAnisotropy);
John Zulauf71968502017-10-26 13:51:15 -06001825 }
1826
1827 // Anistropy cannot be enabled in sampler unless enabled as a feature
1828 if (features.samplerAnisotropy == VK_FALSE) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001829 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 -06001830 "VUID-VkSamplerCreateInfo-anisotropyEnable-01070",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001831 "vkCreateSampler(): Anisotropic sampling feature is not enabled, %s must be VK_FALSE.",
1832 "pCreateInfo->anisotropyEnable");
John Zulauf71968502017-10-26 13:51:15 -06001833 }
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001834 }
John Zulauf71968502017-10-26 13:51:15 -06001835
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001836 if (pCreateInfo->unnormalizedCoordinates == VK_TRUE) {
1837 if (pCreateInfo->minFilter != pCreateInfo->magFilter) {
1838 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1839 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01072",
1840 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1841 "pCreateInfo->minFilter (%s) and pCreateInfo->magFilter (%s) must be equal.",
1842 string_VkFilter(pCreateInfo->minFilter), string_VkFilter(pCreateInfo->magFilter));
1843 }
1844 if (pCreateInfo->mipmapMode != VK_SAMPLER_MIPMAP_MODE_NEAREST) {
1845 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1846 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01073",
1847 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1848 "pCreateInfo->mipmapMode (%s) must be VK_SAMPLER_MIPMAP_MODE_NEAREST.",
1849 string_VkSamplerMipmapMode(pCreateInfo->mipmapMode));
1850 }
1851 if (pCreateInfo->minLod != 0.0f || pCreateInfo->maxLod != 0.0f) {
1852 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1853 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01074",
1854 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1855 "pCreateInfo->minLod (%f) and pCreateInfo->maxLod (%f) must both be zero.",
1856 pCreateInfo->minLod, pCreateInfo->maxLod);
1857 }
1858 if ((pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
1859 pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1860 (pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
1861 pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
1862 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1863 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01075",
1864 "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
1865 "pCreateInfo->addressModeU (%s) and pCreateInfo->addressModeV (%s) must both be "
1866 "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER.",
1867 string_VkSamplerAddressMode(pCreateInfo->addressModeU),
1868 string_VkSamplerAddressMode(pCreateInfo->addressModeV));
1869 }
1870 if (pCreateInfo->anisotropyEnable == VK_TRUE) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001871 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 -06001872 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01076",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001873 "vkCreateSampler(): pCreateInfo->anisotropyEnable and pCreateInfo->unnormalizedCoordinates must "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001874 "not both be VK_TRUE.");
John Zulauf71968502017-10-26 13:51:15 -06001875 }
Jesse Hallcc1fbef2018-06-03 15:58:56 -07001876 if (pCreateInfo->compareEnable == VK_TRUE) {
1877 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1878 "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01077",
1879 "vkCreateSampler(): pCreateInfo->compareEnable and pCreateInfo->unnormalizedCoordinates must "
1880 "not both be VK_TRUE.");
1881 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001882 }
1883
1884 // If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value
1885 if (pCreateInfo->compareEnable == VK_TRUE) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001886 skip |= validate_ranged_enum("vkCreateSampler", "pCreateInfo->compareOp", "VkCompareOp", AllVkCompareOpEnums,
1887 pCreateInfo->compareOp, "VUID-VkSamplerCreateInfo-compareEnable-01080");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001888 }
1889
1890 // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor must be a
1891 // valid VkBorderColor value
1892 if ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1893 (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1894 (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001895 skip |= validate_ranged_enum("vkCreateSampler", "pCreateInfo->borderColor", "VkBorderColor", AllVkBorderColorEnums,
1896 pCreateInfo->borderColor, "VUID-VkSamplerCreateInfo-addressModeU-01078");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001897 }
1898
1899 // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, the
1900 // VK_KHR_sampler_mirror_clamp_to_edge extension must be enabled
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001901 if (!device_extensions.vk_khr_sampler_mirror_clamp_to_edge &&
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001902 ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) ||
1903 (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) ||
1904 (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE))) {
Dave Houlton413a6782018-05-22 13:01:54 -06001905 skip |=
1906 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1907 "VUID-VkSamplerCreateInfo-addressModeU-01079",
1908 "vkCreateSampler(): A VkSamplerAddressMode value is set to VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE "
1909 "but the VK_KHR_sampler_mirror_clamp_to_edge extension has not been enabled.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001910 }
John Zulauf275805c2017-10-26 15:34:49 -06001911
1912 // Checks for the IMG cubic filtering extension
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001913 if (device_extensions.vk_img_filter_cubic) {
John Zulauf275805c2017-10-26 15:34:49 -06001914 if ((pCreateInfo->anisotropyEnable == VK_TRUE) &&
1915 ((pCreateInfo->minFilter == VK_FILTER_CUBIC_IMG) || (pCreateInfo->magFilter == VK_FILTER_CUBIC_IMG))) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001916 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 -06001917 "VUID-VkSamplerCreateInfo-magFilter-01081",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001918 "vkCreateSampler(): Anisotropic sampling must not be VK_TRUE when either minFilter or magFilter "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001919 "are VK_FILTER_CUBIC_IMG.");
John Zulauf275805c2017-10-26 15:34:49 -06001920 }
1921 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001922 }
1923
1924 return skip;
1925}
1926
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001927bool StatelessValidation::manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device,
1928 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
1929 const VkAllocationCallbacks *pAllocator,
1930 VkDescriptorSetLayout *pSetLayout) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001931 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001932
1933 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
1934 if ((pCreateInfo != nullptr) && (pCreateInfo->pBindings != nullptr)) {
1935 for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
1936 if (pCreateInfo->pBindings[i].descriptorCount != 0) {
1937 // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and descriptorCount
1938 // is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a pointer to an array of descriptorCount
1939 // valid VkSampler handles
1940 if (((pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
1941 (pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) &&
1942 (pCreateInfo->pBindings[i].pImmutableSamplers != nullptr)) {
1943 for (uint32_t descriptor_index = 0; descriptor_index < pCreateInfo->pBindings[i].descriptorCount;
1944 ++descriptor_index) {
1945 if (pCreateInfo->pBindings[i].pImmutableSamplers[descriptor_index] == VK_NULL_HANDLE) {
1946 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 -06001947 kVUID_PVError_RequiredParameter,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001948 "vkCreateDescriptorSetLayout: required parameter "
Dave Houltona9df0ce2018-02-07 10:51:23 -07001949 "pCreateInfo->pBindings[%d].pImmutableSamplers[%d] specified as VK_NULL_HANDLE",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001950 i, descriptor_index);
1951 }
1952 }
1953 }
1954
1955 // If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values
1956 if ((pCreateInfo->pBindings[i].stageFlags != 0) &&
1957 ((pCreateInfo->pBindings[i].stageFlags & (~AllVkShaderStageFlagBits)) != 0)) {
Dave Houltona9df0ce2018-02-07 10:51:23 -07001958 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 -06001959 "VUID-VkDescriptorSetLayoutBinding-descriptorCount-00283",
Dave Houltona9df0ce2018-02-07 10:51:23 -07001960 "vkCreateDescriptorSetLayout(): if pCreateInfo->pBindings[%d].descriptorCount is not 0, "
1961 "pCreateInfo->pBindings[%d].stageFlags must be a valid combination of VkShaderStageFlagBits "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001962 "values.",
1963 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001964 }
1965 }
1966 }
1967 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001968 return skip;
1969}
1970
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001971bool StatelessValidation::manual_PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
1972 uint32_t descriptorSetCount,
1973 const VkDescriptorSet *pDescriptorSets) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001974 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
1975 // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
1976 // validate_array()
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001977 return validate_array("vkFreeDescriptorSets", "descriptorSetCount", "pDescriptorSets", descriptorSetCount, &pDescriptorSets,
1978 true, true, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001979}
1980
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001981bool StatelessValidation::manual_PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001982 const VkWriteDescriptorSet *pDescriptorWrites,
1983 uint32_t descriptorCopyCount,
1984 const VkCopyDescriptorSet *pDescriptorCopies) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001985 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001986 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
1987 if (pDescriptorWrites != NULL) {
1988 for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
1989 // descriptorCount must be greater than 0
1990 if (pDescriptorWrites[i].descriptorCount == 0) {
1991 skip |=
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06001992 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 -06001993 "VUID-VkWriteDescriptorSet-descriptorCount-arraylength",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06001994 "vkUpdateDescriptorSets(): parameter pDescriptorWrites[%d].descriptorCount must be greater than 0.", i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001995 }
1996
1997 // dstSet must be a valid VkDescriptorSet handle
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001998 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06001999 ParameterName("pDescriptorWrites[%i].dstSet", ParameterName::IndexVector{i}),
2000 pDescriptorWrites[i].dstSet);
2001
2002 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
2003 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
2004 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2005 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
2006 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
2007 // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
2008 // VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2009 // pImageInfo must be a pointer to an array of descriptorCount valid VkDescriptorImageInfo structures
2010 if (pDescriptorWrites[i].pImageInfo == nullptr) {
2011 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 -06002012 "VUID-VkWriteDescriptorSet-descriptorType-00322",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002013 "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2014 "VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "
2015 "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002016 "VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pDescriptorWrites[%d].pImageInfo must not be NULL.",
2017 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002018 } else if (pDescriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER) {
2019 // If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
2020 // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout
2021 // members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively
2022 for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount;
2023 ++descriptor_index) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002024 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002025 ParameterName("pDescriptorWrites[%i].pImageInfo[%i].imageView",
2026 ParameterName::IndexVector{i, descriptor_index}),
2027 pDescriptorWrites[i].pImageInfo[descriptor_index].imageView);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002028 skip |= validate_ranged_enum("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002029 ParameterName("pDescriptorWrites[%i].pImageInfo[%i].imageLayout",
2030 ParameterName::IndexVector{i, descriptor_index}),
2031 "VkImageLayout", AllVkImageLayoutEnums,
Dave Houlton413a6782018-05-22 13:01:54 -06002032 pDescriptorWrites[i].pImageInfo[descriptor_index].imageLayout, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002033 }
2034 }
2035 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
2036 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
2037 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
2038 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
2039 // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2040 // VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a
2041 // pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures
2042 if (pDescriptorWrites[i].pBufferInfo == nullptr) {
2043 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 -06002044 "VUID-VkWriteDescriptorSet-descriptorType-00324",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002045 "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2046 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "
2047 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002048 "pDescriptorWrites[%d].pBufferInfo must not be NULL.",
2049 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002050 } else {
2051 for (uint32_t descriptorIndex = 0; descriptorIndex < pDescriptorWrites[i].descriptorCount; ++descriptorIndex) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002052 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002053 ParameterName("pDescriptorWrites[%i].pBufferInfo[%i].buffer",
2054 ParameterName::IndexVector{i, descriptorIndex}),
2055 pDescriptorWrites[i].pBufferInfo[descriptorIndex].buffer);
2056 }
2057 }
2058 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
2059 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
2060 // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
2061 // pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles
2062 if (pDescriptorWrites[i].pTexelBufferView == nullptr) {
2063 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 -06002064 "VUID-VkWriteDescriptorSet-descriptorType-00323",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002065 "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2066 "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002067 "pDescriptorWrites[%d].pTexelBufferView must not be NULL.",
2068 i, i);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002069 } else {
2070 for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount;
2071 ++descriptor_index) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002072 skip |= validate_required_handle("vkUpdateDescriptorSets",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002073 ParameterName("pDescriptorWrites[%i].pTexelBufferView[%i]",
2074 ParameterName::IndexVector{i, descriptor_index}),
2075 pDescriptorWrites[i].pTexelBufferView[descriptor_index]);
2076 }
2077 }
2078 }
2079
2080 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
2081 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002082 VkDeviceSize uniformAlignment = device_limits.minUniformBufferOffsetAlignment;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002083 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
2084 if (pDescriptorWrites[i].pBufferInfo != NULL) {
2085 if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
Mark Lobodzinski88529492018-04-01 10:38:15 -06002086 skip |=
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002087 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
2088 0, "VUID-VkWriteDescriptorSet-descriptorType-00327",
Mark Lobodzinski88529492018-04-01 10:38:15 -06002089 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
2090 ") must be a multiple of device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64 ".",
2091 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002092 }
2093 }
2094 }
2095 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
2096 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002097 VkDeviceSize storageAlignment = device_limits.minStorageBufferOffsetAlignment;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002098 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
2099 if (pDescriptorWrites[i].pBufferInfo != NULL) {
2100 if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
Mark Lobodzinski88529492018-04-01 10:38:15 -06002101 skip |=
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002102 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
2103 0, "VUID-VkWriteDescriptorSet-descriptorType-00328",
Mark Lobodzinski88529492018-04-01 10:38:15 -06002104 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
2105 ") must be a multiple of device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64 ".",
2106 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002107 }
2108 }
2109 }
2110 }
2111 }
2112 }
2113 return skip;
2114}
2115
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002116bool StatelessValidation::manual_PreCallValidateCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002117 const VkAllocationCallbacks *pAllocator,
2118 VkRenderPass *pRenderPass) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002119 return CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_1);
2120}
2121
2122bool StatelessValidation::manual_PreCallValidateCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002123 const VkAllocationCallbacks *pAllocator,
2124 VkRenderPass *pRenderPass) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002125 return CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_2);
2126}
2127
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002128bool StatelessValidation::manual_PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
2129 uint32_t commandBufferCount,
2130 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002131 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002132
2133 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2134 // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
2135 // validate_array()
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002136 skip |= validate_array("vkFreeCommandBuffers", "commandBufferCount", "pCommandBuffers", commandBufferCount, &pCommandBuffers,
2137 true, true, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002138 return skip;
2139}
2140
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002141bool StatelessValidation::manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer,
2142 const VkCommandBufferBeginInfo *pBeginInfo) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002143 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002144 const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
2145
2146 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2147 // TODO: pBeginInfo->pInheritanceInfo must not be NULL if commandBuffer is a secondary command buffer
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002148 skip |= validate_struct_type("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002149 "VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO", pBeginInfo->pInheritanceInfo,
Mark Lobodzinskia16ebc72018-06-15 14:47:39 -06002150 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, false,
2151 "VUID_vkBeginCommandBuffer-pBeginInfo-parameter", "VUID_VkCommandBufferBeginInfo-sType-sType");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002152
2153 if (pBeginInfo->pInheritanceInfo != NULL) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002154 skip |= validate_struct_pnext("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pNext", NULL,
2155 pBeginInfo->pInheritanceInfo->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
Dave Houlton413a6782018-05-22 13:01:54 -06002156 "VUID-VkCommandBufferBeginInfo-pNext-pNext");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002157
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002158 skip |= validate_bool32("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->occlusionQueryEnable",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002159 pBeginInfo->pInheritanceInfo->occlusionQueryEnable);
2160
2161 // TODO: This only needs to be validated when the inherited queries feature is enabled
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002162 // skip |= validate_flags("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->queryFlags",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002163 // "VkQueryControlFlagBits", AllVkQueryControlFlagBits, pBeginInfo->pInheritanceInfo->queryFlags, false);
2164
2165 // TODO: This must be 0 if the pipeline statistics queries feature is not enabled
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002166 skip |= validate_flags("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pipelineStatistics",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002167 "VkQueryPipelineStatisticFlagBits", AllVkQueryPipelineStatisticFlagBits,
Dave Houlton413a6782018-05-22 13:01:54 -06002168 pBeginInfo->pInheritanceInfo->pipelineStatistics, false, false, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002169 }
2170
2171 if (pInfo != NULL) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002172 if ((physical_device_features.inheritedQueries == VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE)) {
2173 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 -06002174 HandleToUint64(commandBuffer), "VUID-VkCommandBufferInheritanceInfo-occlusionQueryEnable-00056",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002175 "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002176 "inheritedQueries.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002177 }
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002178 if ((physical_device_features.inheritedQueries != VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE)) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002179 skip |= validate_flags("vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->queryFlags", "VkQueryControlFlagBits",
2180 AllVkQueryControlFlagBits, pInfo->queryFlags, false, false,
Dave Houlton413a6782018-05-22 13:01:54 -06002181 "VUID-VkCommandBufferInheritanceInfo-queryFlags-00057");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002182 }
2183 }
2184
2185 return skip;
2186}
2187
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002188bool StatelessValidation::manual_PreCallValidateCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2189 uint32_t viewportCount, const VkViewport *pViewports) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002190 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002191
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002192 if (!physical_device_features.multiViewport) {
Petr Krausd55e77c2018-01-09 22:09:25 +01002193 if (firstViewport != 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002194 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 -06002195 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-firstViewport-01224",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002196 "vkCmdSetViewport: The multiViewport feature is disabled, but firstViewport (=%" PRIu32 ") is not 0.",
2197 firstViewport);
Petr Krausd55e77c2018-01-09 22:09:25 +01002198 }
2199 if (viewportCount > 1) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002200 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 -06002201 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-viewportCount-01225",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002202 "vkCmdSetViewport: The multiViewport feature is disabled, but viewportCount (=%" PRIu32 ") is not 1.",
2203 viewportCount);
Petr Krausd55e77c2018-01-09 22:09:25 +01002204 }
2205 } else { // multiViewport enabled
Petr Kraus7dfeed12018-02-27 20:51:20 +01002206 const uint64_t sum = static_cast<uint64_t>(firstViewport) + static_cast<uint64_t>(viewportCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002207 if (sum > device_limits.maxViewports) {
2208 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 -06002209 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-firstViewport-01223",
Petr Krausd55e77c2018-01-09 22:09:25 +01002210 "vkCmdSetViewport: firstViewport + viewportCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002211 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002212 firstViewport, viewportCount, sum, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002213 }
2214 }
Petr Krausb3fcdb42018-01-09 22:09:09 +01002215
2216 if (pViewports) {
2217 for (uint32_t viewport_i = 0; viewport_i < viewportCount; ++viewport_i) {
2218 const auto &viewport = pViewports[viewport_i]; // will crash on invalid ptr
2219 const char fn_name[] = "vkCmdSetViewport";
2220 const std::string param_name = "pViewports[" + std::to_string(viewport_i) + "]";
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002221 skip |= manual_PreCallValidateViewport(viewport, fn_name, param_name.c_str(),
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002222 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer));
Petr Krausb3fcdb42018-01-09 22:09:09 +01002223 }
2224 }
2225
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002226 return skip;
2227}
2228
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002229bool StatelessValidation::manual_PreCallValidateCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
2230 uint32_t scissorCount, const VkRect2D *pScissors) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002231 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002232
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002233 if (!physical_device_features.multiViewport) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002234 if (firstScissor != 0) {
Petr Kraus6260f0a2018-02-27 21:15:55 +01002235 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 -06002236 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-firstScissor-00593",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002237 "vkCmdSetScissor: The multiViewport feature is disabled, but firstScissor (=%" PRIu32 ") is not 0.",
2238 firstScissor);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002239 }
2240 if (scissorCount > 1) {
2241 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 -06002242 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-scissorCount-00594",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002243 "vkCmdSetScissor: The multiViewport feature is disabled, but scissorCount (=%" PRIu32 ") is not 1.",
2244 scissorCount);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002245 }
2246 } else { // multiViewport enabled
2247 const uint64_t sum = static_cast<uint64_t>(firstScissor) + static_cast<uint64_t>(scissorCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002248 if (sum > device_limits.maxViewports) {
2249 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 -06002250 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-firstScissor-00592",
Petr Kraus6260f0a2018-02-27 21:15:55 +01002251 "vkCmdSetScissor: firstScissor + scissorCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002252 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002253 firstScissor, scissorCount, sum, device_limits.maxViewports);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002254 }
2255 }
2256
Petr Kraus6260f0a2018-02-27 21:15:55 +01002257 if (pScissors) {
2258 for (uint32_t scissor_i = 0; scissor_i < scissorCount; ++scissor_i) {
2259 const auto &scissor = pScissors[scissor_i]; // will crash on invalid ptr
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002260
Petr Kraus6260f0a2018-02-27 21:15:55 +01002261 if (scissor.offset.x < 0) {
2262 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 -06002263 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-x-00595",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002264 "vkCmdSetScissor: pScissors[%" PRIu32 "].offset.x (=%" PRIi32 ") is negative.", scissor_i,
2265 scissor.offset.x);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002266 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002267
Petr Kraus6260f0a2018-02-27 21:15:55 +01002268 if (scissor.offset.y < 0) {
2269 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 -06002270 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-x-00595",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002271 "vkCmdSetScissor: pScissors[%" PRIu32 "].offset.y (=%" PRIi32 ") is negative.", scissor_i,
2272 scissor.offset.y);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002273 }
2274
2275 const int64_t x_sum = static_cast<int64_t>(scissor.offset.x) + static_cast<int64_t>(scissor.extent.width);
2276 if (x_sum > INT32_MAX) {
2277 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 -06002278 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-offset-00596",
Petr Kraus6260f0a2018-02-27 21:15:55 +01002279 "vkCmdSetScissor: offset.x + extent.width (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002280 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2281 scissor.offset.x, scissor.extent.width, x_sum, scissor_i);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002282 }
2283
2284 const int64_t y_sum = static_cast<int64_t>(scissor.offset.y) + static_cast<int64_t>(scissor.extent.height);
2285 if (y_sum > INT32_MAX) {
2286 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 -06002287 HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-offset-00597",
Petr Kraus6260f0a2018-02-27 21:15:55 +01002288 "vkCmdSetScissor: offset.y + extent.height (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002289 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2290 scissor.offset.y, scissor.extent.height, y_sum, scissor_i);
Petr Kraus6260f0a2018-02-27 21:15:55 +01002291 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002292 }
2293 }
Petr Kraus6260f0a2018-02-27 21:15:55 +01002294
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002295 return skip;
2296}
2297
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002298bool StatelessValidation::manual_PreCallValidateCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
Petr Kraus299ba622017-11-24 03:09:03 +01002299 bool skip = false;
Petr Kraus299ba622017-11-24 03:09:03 +01002300
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002301 if (!physical_device_features.wideLines && (lineWidth != 1.0f)) {
Petr Kraus299ba622017-11-24 03:09:03 +01002302 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 -06002303 HandleToUint64(commandBuffer), "VUID-vkCmdSetLineWidth-lineWidth-00788",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002304 "VkPhysicalDeviceFeatures::wideLines is disabled, but lineWidth (=%f) is not 1.0.", lineWidth);
Petr Kraus299ba622017-11-24 03:09:03 +01002305 }
2306
2307 return skip;
2308}
2309
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002310bool StatelessValidation::manual_PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002311 uint32_t firstVertex, uint32_t firstInstance) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002312 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002313 if (vertexCount == 0) {
2314 // TODO: Verify against Valid Usage section. I don't see a non-zero vertexCount listed, may need to add that and make
2315 // this an error or leave as is.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002316 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 -06002317 kVUID_PVError_RequiredParameter, "vkCmdDraw parameter, uint32_t vertexCount, is 0");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002318 }
2319
2320 if (instanceCount == 0) {
2321 // TODO: Verify against Valid Usage section. I don't see a non-zero instanceCount listed, may need to add that and make
2322 // this an error or leave as is.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002323 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 -06002324 kVUID_PVError_RequiredParameter, "vkCmdDraw parameter, uint32_t instanceCount, is 0");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002325 }
2326 return skip;
2327}
2328
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002329bool StatelessValidation::manual_PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
2330 uint32_t count, uint32_t stride) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002331 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002332
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002333 if (!physical_device_features.multiDrawIndirect && ((count > 1))) {
2334 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 -06002335 kVUID_PVError_DeviceFeature,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002336 "CmdDrawIndirect(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d", count);
2337 }
2338 return skip;
2339}
2340
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002341bool StatelessValidation::manual_PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2342 VkDeviceSize offset, uint32_t count, uint32_t stride) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002343 bool skip = false;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002344 if (!physical_device_features.multiDrawIndirect && ((count > 1))) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002345 skip |= log_msg(
2346 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_PVError_DeviceFeature,
2347 "CmdDrawIndexedIndirect(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d", count);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002348 }
2349 return skip;
2350}
2351
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002352bool StatelessValidation::manual_PreCallValidateCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2353 VkImageLayout srcImageLayout, VkImage dstImage,
2354 VkImageLayout dstImageLayout, uint32_t regionCount,
2355 const VkImageCopy *pRegions) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002356 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002357
Dave Houltonf5217612018-02-02 16:18:52 -07002358 VkImageAspectFlags legal_aspect_flags =
2359 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 -07002360 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002361 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2362 }
2363
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002364 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002365 if ((pRegions->srcSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002366 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002367 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002368 "VUID-VkImageSubresourceLayers-aspectMask-parameter",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002369 "vkCmdCopyImage() parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002370 }
Dave Houltonf5217612018-02-02 16:18:52 -07002371 if ((pRegions->dstSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002372 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002373 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002374 "VUID-VkImageSubresourceLayers-aspectMask-parameter",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002375 "vkCmdCopyImage() parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002376 }
2377 }
2378 return skip;
2379}
2380
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002381bool StatelessValidation::manual_PreCallValidateCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2382 VkImageLayout srcImageLayout, VkImage dstImage,
2383 VkImageLayout dstImageLayout, uint32_t regionCount,
2384 const VkImageBlit *pRegions, VkFilter filter) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002385 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002386
Dave Houltonf5217612018-02-02 16:18:52 -07002387 VkImageAspectFlags legal_aspect_flags =
2388 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 -07002389 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002390 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2391 }
2392
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002393 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002394 if ((pRegions->srcSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002395 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002396 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002397 kVUID_PVError_UnrecognizedValue,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002398 "vkCmdBlitImage() parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator");
2399 }
Dave Houltonf5217612018-02-02 16:18:52 -07002400 if ((pRegions->dstSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002401 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002402 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
Dave Houlton413a6782018-05-22 13:01:54 -06002403 kVUID_PVError_UnrecognizedValue,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002404 "vkCmdBlitImage() parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator");
2405 }
2406 }
2407 return skip;
2408}
2409
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002410bool StatelessValidation::manual_PreCallValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
2411 VkImage dstImage, VkImageLayout dstImageLayout,
2412 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002413 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002414
Dave Houltonf5217612018-02-02 16:18:52 -07002415 VkImageAspectFlags legal_aspect_flags =
2416 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 -07002417 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002418 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2419 }
2420
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002421 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002422 if ((pRegions->imageSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002423 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 -06002424 kVUID_PVError_UnrecognizedValue,
Dave Houltona9df0ce2018-02-07 10:51:23 -07002425 "vkCmdCopyBufferToImage() parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an "
2426 "unrecognized enumerator");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002427 }
2428 }
2429 return skip;
2430}
2431
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002432bool StatelessValidation::manual_PreCallValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
2433 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
2434 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002435 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002436
Dave Houltonf5217612018-02-02 16:18:52 -07002437 VkImageAspectFlags legal_aspect_flags =
2438 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 -07002439 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
Dave Houltonf5217612018-02-02 16:18:52 -07002440 legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2441 }
2442
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002443 if (pRegions != nullptr) {
Dave Houltonf5217612018-02-02 16:18:52 -07002444 if ((pRegions->imageSubresource.aspectMask & legal_aspect_flags) == 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002445 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 -06002446 kVUID_PVError_UnrecognizedValue,
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002447 "vkCmdCopyImageToBuffer parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an unrecognized "
2448 "enumerator");
2449 }
2450 }
2451 return skip;
2452}
2453
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002454bool StatelessValidation::manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
2455 VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002456 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002457
2458 if (dstOffset & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002459 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 -06002460 "VUID-vkCmdUpdateBuffer-dstOffset-00036",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002461 "vkCmdUpdateBuffer() parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
2462 dstOffset);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002463 }
2464
2465 if ((dataSize <= 0) || (dataSize > 65536)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002466 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 -06002467 "VUID-vkCmdUpdateBuffer-dataSize-00037",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002468 "vkCmdUpdateBuffer() parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002469 "), must be greater than zero and less than or equal to 65536.",
2470 dataSize);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002471 } else if (dataSize & 3) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002472 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002473 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 -06002474 "VUID-vkCmdUpdateBuffer-dataSize-00038",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002475 "vkCmdUpdateBuffer() parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 "), is not a multiple of 4.", dataSize);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002476 }
2477 return skip;
2478}
2479
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002480bool StatelessValidation::manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
2481 VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002482 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002483
2484 if (dstOffset & 3) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002485 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002486 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-dstOffset-00025",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002488 "vkCmdFillBuffer() parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4.", dstOffset);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002489 }
2490
2491 if (size != VK_WHOLE_SIZE) {
2492 if (size <= 0) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002493 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002494 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 -06002495 "VUID-vkCmdFillBuffer-size-00026",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002496 "vkCmdFillBuffer() parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), must be greater than zero.", size);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002497 } else if (size & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002498 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 -06002499 "VUID-vkCmdFillBuffer-size-00028",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002500 "vkCmdFillBuffer() parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), is not a multiple of 4.", size);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002501 }
2502 }
2503 return skip;
2504}
2505
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002506bool StatelessValidation::manual_PreCallValidateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002507 const VkAllocationCallbacks *pAllocator,
2508 VkSwapchainKHR *pSwapchain) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002509 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002510
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002511 const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, VK_NULL_HANDLE, "vkCreateSwapchainKHR"};
Petr Krause5c37652018-01-05 04:05:12 +01002512
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002513 if (pCreateInfo != nullptr) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002514 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2515 if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
2516 // If imageSharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
2517 if (pCreateInfo->queueFamilyIndexCount <= 1) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06002518 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 -06002519 "VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002520 "vkCreateSwapchainKHR(): if pCreateInfo->imageSharingMode is VK_SHARING_MODE_CONCURRENT, "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002521 "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002522 }
2523
2524 // If imageSharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
2525 // queueFamilyIndexCount uint32_t values
2526 if (pCreateInfo->pQueueFamilyIndices == nullptr) {
Mark Lobodzinskib1fd9d12018-03-30 14:26:00 -06002527 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 -06002528 "VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01277",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002529 "vkCreateSwapchainKHR(): if pCreateInfo->imageSharingMode is VK_SHARING_MODE_CONCURRENT, "
2530 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002531 "pCreateInfo->queueFamilyIndexCount uint32_t values.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002532 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002533 skip |= ValidateQueueFamilies(pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices,
Dave Houlton413a6782018-05-22 13:01:54 -06002534 "vkCreateSwapchainKHR", "pCreateInfo->pQueueFamilyIndices",
2535 kVUID_PVError_InvalidUsage, kVUID_PVError_InvalidUsage, false);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002536 }
2537 }
2538
Dave Houlton413a6782018-05-22 13:01:54 -06002539 skip |= ValidateGreaterThanZero(pCreateInfo->imageArrayLayers, "pCreateInfo->imageArrayLayers",
2540 "VUID-VkSwapchainCreateInfoKHR-imageArrayLayers-01275", log_misc);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002541 }
2542
2543 return skip;
2544}
2545
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002546bool StatelessValidation::manual_PreCallValidateQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002547 bool skip = false;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002548
2549 if (pPresentInfo && pPresentInfo->pNext) {
John Zulaufde972ac2017-10-26 12:07:05 -06002550 const auto *present_regions = lvl_find_in_chain<VkPresentRegionsKHR>(pPresentInfo->pNext);
2551 if (present_regions) {
2552 // TODO: This and all other pNext extension dependencies should be added to code-generation
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002553 skip |= require_device_extension(device_extensions.vk_khr_incremental_present, "vkQueuePresentKHR",
John Zulaufde972ac2017-10-26 12:07:05 -06002554 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
2555 if (present_regions->swapchainCount != pPresentInfo->swapchainCount) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002556 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 -06002557 kVUID_PVError_InvalidUsage,
Dave Houltona9df0ce2018-02-07 10:51:23 -07002558 "QueuePresentKHR(): pPresentInfo->swapchainCount has a value of %i but VkPresentRegionsKHR "
2559 "extension swapchainCount is %i. These values must be equal.",
John Zulaufde972ac2017-10-26 12:07:05 -06002560 pPresentInfo->swapchainCount, present_regions->swapchainCount);
2561 }
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002562 skip |= validate_struct_pnext("QueuePresentKHR", "pCreateInfo->pNext->pNext", NULL, present_regions->pNext, 0, NULL,
2563 GeneratedVulkanHeaderVersion, "VUID-VkPresentInfoKHR-pNext-pNext");
2564 skip |= validate_array("QueuePresentKHR", "pCreateInfo->pNext->swapchainCount", "pCreateInfo->pNext->pRegions",
2565 present_regions->swapchainCount, &present_regions->pRegions, true, false, kVUIDUndefined,
2566 kVUIDUndefined);
John Zulaufde972ac2017-10-26 12:07:05 -06002567 for (uint32_t i = 0; i < present_regions->swapchainCount; ++i) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002568 skip |= validate_array("QueuePresentKHR", "pCreateInfo->pNext->pRegions[].rectangleCount",
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002569 "pCreateInfo->pNext->pRegions[].pRectangles", present_regions->pRegions[i].rectangleCount,
Dave Houlton413a6782018-05-22 13:01:54 -06002570 &present_regions->pRegions[i].pRectangles, true, false, kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002571 }
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002572 }
2573 }
2574
2575 return skip;
2576}
2577
2578#ifdef VK_USE_PLATFORM_WIN32_KHR
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002579bool StatelessValidation::manual_PreCallValidateCreateWin32SurfaceKHR(VkInstance instance,
2580 const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
2581 const VkAllocationCallbacks *pAllocator,
2582 VkSurfaceKHR *pSurface) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002583 bool skip = false;
2584
2585 if (pCreateInfo->hwnd == nullptr) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002586 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 -06002587 "VUID-VkWin32SurfaceCreateInfoKHR-hwnd-01308",
2588 "vkCreateWin32SurfaceKHR(): hwnd must be a valid Win32 HWND but hwnd is NULL.");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002589 }
2590
2591 return skip;
2592}
2593#endif // VK_USE_PLATFORM_WIN32_KHR
2594
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002595bool StatelessValidation::manual_PreCallValidateDebugMarkerSetObjectNameEXT(VkDevice device,
2596 const VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002597 if (pNameInfo->pObjectName) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002598 report_data->debugObjectNameMap->insert(
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002599 std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->object, pNameInfo->pObjectName));
2600 } else {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002601 report_data->debugObjectNameMap->erase(pNameInfo->object);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002602 }
2603 return false;
2604}
2605
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002606bool StatelessValidation::manual_PreCallValidateCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002607 const VkAllocationCallbacks *pAllocator,
2608 VkDescriptorPool *pDescriptorPool) {
Petr Krausc8655be2017-09-27 18:56:51 +02002609 bool skip = false;
2610
2611 if (pCreateInfo) {
2612 if (pCreateInfo->maxSets <= 0) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002613 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
2614 VK_NULL_HANDLE, "VUID-VkDescriptorPoolCreateInfo-maxSets-00301",
2615 "vkCreateDescriptorPool(): pCreateInfo->maxSets is not greater than 0.");
Petr Krausc8655be2017-09-27 18:56:51 +02002616 }
2617
2618 if (pCreateInfo->pPoolSizes) {
2619 for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; ++i) {
2620 if (pCreateInfo->pPoolSizes[i].descriptorCount <= 0) {
2621 skip |= log_msg(
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002622 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, VK_NULL_HANDLE,
2623 "VUID-VkDescriptorPoolSize-descriptorCount-00302",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002624 "vkCreateDescriptorPool(): pCreateInfo->pPoolSizes[%" PRIu32 "].descriptorCount is not greater than 0.", i);
Petr Krausc8655be2017-09-27 18:56:51 +02002625 }
Jeff Bolze54ae892018-09-08 12:16:29 -05002626 if (pCreateInfo->pPoolSizes[i].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
2627 (pCreateInfo->pPoolSizes[i].descriptorCount % 4) != 0) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002628 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
2629 VK_NULL_HANDLE, "VUID-VkDescriptorPoolSize-type-02218",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002630 "vkCreateDescriptorPool(): pCreateInfo->pPoolSizes[%" PRIu32
2631 "].type is VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT "
2632 " and pCreateInfo->pPoolSizes[%" PRIu32 "].descriptorCount is not a multiple of 4.",
2633 i, i);
Jeff Bolze54ae892018-09-08 12:16:29 -05002634 }
Petr Krausc8655be2017-09-27 18:56:51 +02002635 }
2636 }
2637 }
2638
2639 return skip;
2640}
2641
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002642bool StatelessValidation::manual_PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX,
2643 uint32_t groupCountY, uint32_t groupCountZ) {
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002644 bool skip = false;
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002645
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002646 if (groupCountX > device_limits.maxComputeWorkGroupCount[0]) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002647 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002648 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 -06002649 HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountX-00386",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002650 "vkCmdDispatch(): groupCountX (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002651 groupCountX, device_limits.maxComputeWorkGroupCount[0]);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002652 }
2653
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002654 if (groupCountY > device_limits.maxComputeWorkGroupCount[1]) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002655 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002656 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 -06002657 HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountY-00387",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002658 "vkCmdDispatch(): groupCountY (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002659 groupCountY, device_limits.maxComputeWorkGroupCount[1]);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002660 }
2661
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002662 if (groupCountZ > device_limits.maxComputeWorkGroupCount[2]) {
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002663 skip |=
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002664 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 -06002665 HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountZ-00388",
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002666 "vkCmdDispatch(): groupCountZ (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002667 groupCountZ, device_limits.maxComputeWorkGroupCount[2]);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002668 }
2669
2670 return skip;
2671}
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002672
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002673bool StatelessValidation::manual_PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2674 VkDeviceSize offset) {
John Zulaufa999d1b2018-11-29 13:38:40 -07002675 bool skip = false;
John Zulaufa999d1b2018-11-29 13:38:40 -07002676
2677 if ((offset % 4) != 0) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002678 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 -07002679 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchIndirect-offset-00406",
2680 "vkCmdDispatchIndirect(): offset (%" PRIu64 ") must be a multiple of 4.", offset);
2681 }
2682 return skip;
2683}
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002684
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002685bool StatelessValidation::manual_PreCallValidateCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX,
2686 uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX,
2687 uint32_t groupCountY, uint32_t groupCountZ) {
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002688 bool skip = false;
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002689
2690 // Paired if {} else if {} tests used to avoid any possible uint underflow
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002691 uint32_t limit = device_limits.maxComputeWorkGroupCount[0];
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002692 if (baseGroupX >= limit) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002693 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 -06002694 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupX-00421",
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002695 "vkCmdDispatch(): baseGroupX (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002696 ") equals or exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
2697 baseGroupX, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002698 } else if (groupCountX > (limit - baseGroupX)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002699 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 -06002700 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountX-00424",
Mark Lobodzinskibf973a12018-03-01 08:50:21 -07002701 "vkCmdDispatchBaseKHR(): baseGroupX (%" PRIu32 ") + groupCountX (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002702 ") exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
2703 baseGroupX, groupCountX, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002704 }
2705
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002706 limit = device_limits.maxComputeWorkGroupCount[1];
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002707 if (baseGroupY >= limit) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002708 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 -06002709 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupX-00422",
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002710 "vkCmdDispatch(): baseGroupY (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002711 ") equals or exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
2712 baseGroupY, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002713 } else if (groupCountY > (limit - baseGroupY)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002714 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 -06002715 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountY-00425",
Mark Lobodzinskibf973a12018-03-01 08:50:21 -07002716 "vkCmdDispatchBaseKHR(): baseGroupY (%" PRIu32 ") + groupCountY (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002717 ") exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
2718 baseGroupY, groupCountY, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002719 }
2720
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002721 limit = device_limits.maxComputeWorkGroupCount[2];
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002722 if (baseGroupZ >= limit) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002723 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 -06002724 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupZ-00423",
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002725 "vkCmdDispatch(): baseGroupZ (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002726 ") equals or exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
2727 baseGroupZ, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002728 } else if (groupCountZ > (limit - baseGroupZ)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002729 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 -06002730 HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountZ-00426",
Mark Lobodzinskibf973a12018-03-01 08:50:21 -07002731 "vkCmdDispatchBaseKHR(): baseGroupZ (%" PRIu32 ") + groupCountZ (%" PRIu32
Mark Lobodzinski487a0d12018-03-30 10:09:03 -06002732 ") exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
2733 baseGroupZ, groupCountZ, limit);
Dave Houltonbb7d3fe2018-01-11 17:09:16 -07002734 }
2735
2736 return skip;
2737}
2738
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002739bool StatelessValidation::manual_PreCallValidateCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer,
2740 uint32_t firstExclusiveScissor,
2741 uint32_t exclusiveScissorCount,
2742 const VkRect2D *pExclusiveScissors) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05002743 bool skip = false;
2744
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002745 if (!physical_device_features.multiViewport) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05002746 if (firstExclusiveScissor != 0) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002747 skip |=
2748 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2749 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035",
2750 "vkCmdSetExclusiveScissorNV: The multiViewport feature is disabled, but firstExclusiveScissor (=%" PRIu32
2751 ") is not 0.",
2752 firstExclusiveScissor);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002753 }
2754 if (exclusiveScissorCount > 1) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002755 skip |=
2756 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2757 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036",
2758 "vkCmdSetExclusiveScissorNV: The multiViewport feature is disabled, but exclusiveScissorCount (=%" PRIu32
2759 ") is not 1.",
2760 exclusiveScissorCount);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002761 }
2762 } else { // multiViewport enabled
2763 const uint64_t sum = static_cast<uint64_t>(firstExclusiveScissor) + static_cast<uint64_t>(exclusiveScissorCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002764 if (sum > device_limits.maxViewports) {
2765 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 -05002766 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02034",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002767 "vkCmdSetExclusiveScissorNV: firstExclusiveScissor + exclusiveScissorCount (=%" PRIu32 " + %" PRIu32
2768 " = %" PRIu64 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002769 firstExclusiveScissor, exclusiveScissorCount, sum, device_limits.maxViewports);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002770 }
2771 }
2772
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002773 if (firstExclusiveScissor >= device_limits.maxViewports) {
Jeff Bolz3e71f782018-08-29 23:15:45 -05002774 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2775 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02033",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002776 "vkCmdSetExclusiveScissorNV: firstExclusiveScissor (=%" PRIu32 ") must be less than maxViewports (=%" PRIu32
2777 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002778 firstExclusiveScissor, device_limits.maxViewports);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002779 }
2780
2781 if (pExclusiveScissors) {
2782 for (uint32_t scissor_i = 0; scissor_i < exclusiveScissorCount; ++scissor_i) {
2783 const auto &scissor = pExclusiveScissors[scissor_i]; // will crash on invalid ptr
2784
2785 if (scissor.offset.x < 0) {
2786 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2787 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-x-02037",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002788 "vkCmdSetExclusiveScissorNV: pScissors[%" PRIu32 "].offset.x (=%" PRIi32 ") is negative.",
2789 scissor_i, scissor.offset.x);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002790 }
2791
2792 if (scissor.offset.y < 0) {
2793 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2794 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-x-02037",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002795 "vkCmdSetExclusiveScissorNV: pScissors[%" PRIu32 "].offset.y (=%" PRIi32 ") is negative.",
2796 scissor_i, scissor.offset.y);
Jeff Bolz3e71f782018-08-29 23:15:45 -05002797 }
2798
2799 const int64_t x_sum = static_cast<int64_t>(scissor.offset.x) + static_cast<int64_t>(scissor.extent.width);
2800 if (x_sum > INT32_MAX) {
2801 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2802 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-offset-02038",
2803 "vkCmdSetExclusiveScissorNV: offset.x + extent.width (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
2804 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2805 scissor.offset.x, scissor.extent.width, x_sum, scissor_i);
2806 }
2807
2808 const int64_t y_sum = static_cast<int64_t>(scissor.offset.y) + static_cast<int64_t>(scissor.extent.height);
2809 if (y_sum > INT32_MAX) {
2810 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2811 HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-offset-02039",
2812 "vkCmdSetExclusiveScissorNV: offset.y + extent.height (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
2813 ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2814 scissor.offset.y, scissor.extent.height, y_sum, scissor_i);
2815 }
2816 }
2817 }
2818
2819 return skip;
2820}
2821
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002822bool StatelessValidation::manual_PreCallValidateCmdSetViewportShadingRatePaletteNV(
2823 VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
2824 const VkShadingRatePaletteNV *pShadingRatePalettes) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002825 bool skip = false;
2826
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002827 if (!physical_device_features.multiViewport) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002828 if (firstViewport != 0) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002829 skip |=
2830 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2831 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068",
2832 "vkCmdSetViewportShadingRatePaletteNV: The multiViewport feature is disabled, but firstViewport (=%" PRIu32
2833 ") is not 0.",
2834 firstViewport);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002835 }
2836 if (viewportCount > 1) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002837 skip |=
2838 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2839 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069",
2840 "vkCmdSetViewportShadingRatePaletteNV: The multiViewport feature is disabled, but viewportCount (=%" PRIu32
2841 ") is not 1.",
2842 viewportCount);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002843 }
2844 }
2845
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002846 if (firstViewport >= device_limits.maxViewports) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002847 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2848 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02066",
Dave Houlton142c4cb2018-10-17 15:04:41 -06002849 "vkCmdSetViewportShadingRatePaletteNV: firstViewport (=%" PRIu32
2850 ") must be less than maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002851 firstViewport, device_limits.maxViewports);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002852 }
2853
2854 const uint64_t sum = static_cast<uint64_t>(firstViewport) + static_cast<uint64_t>(viewportCount);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002855 if (sum > device_limits.maxViewports) {
2856 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 -05002857 HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067",
2858 "vkCmdSetViewportShadingRatePaletteNV: firstViewport + viewportCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
2859 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002860 firstViewport, viewportCount, sum, device_limits.maxViewports);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002861 }
2862
2863 return skip;
2864}
2865
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002866bool StatelessValidation::manual_PreCallValidateCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer,
2867 VkCoarseSampleOrderTypeNV sampleOrderType,
2868 uint32_t customSampleOrderCount,
2869 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002870 bool skip = false;
2871
Dave Houlton142c4cb2018-10-17 15:04:41 -06002872 if (sampleOrderType != VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV && customSampleOrderCount != 0) {
Jeff Bolz9af91c52018-09-01 21:53:57 -05002873 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2874 HandleToUint64(commandBuffer), "VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081",
2875 "vkCmdSetCoarseSampleOrderNV: If sampleOrderType is not VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, "
2876 "customSampleOrderCount must be 0.");
2877 }
2878
2879 for (uint32_t order_i = 0; order_i < customSampleOrderCount; ++order_i) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002880 skip |= ValidateCoarseSampleOrderCustomNV(&pCustomSampleOrders[order_i]);
Jeff Bolz9af91c52018-09-01 21:53:57 -05002881 }
2882
2883 return skip;
2884}
2885
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002886bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount,
2887 uint32_t firstTask) {
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002888 bool skip = false;
2889
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002890 if (taskCount > phys_dev_ext_props.mesh_shader_props.maxDrawMeshTasksCount) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002891 skip |= log_msg(
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002892 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Dave Houlton142c4cb2018-10-17 15:04:41 -06002893 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksNV-taskCount-02119",
2894 "vkCmdDrawMeshTasksNV() parameter, uint32_t taskCount (0x%" PRIxLEAST32
2895 "), must be less than or equal to VkPhysicalDeviceMeshShaderPropertiesNV::maxDrawMeshTasksCount (0x%" PRIxLEAST32 ").",
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002896 taskCount, phys_dev_ext_props.mesh_shader_props.maxDrawMeshTasksCount);
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002897 }
2898
2899 return skip;
2900}
2901
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002902bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
2903 VkDeviceSize offset, uint32_t drawCount,
2904 uint32_t stride) {
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002905 bool skip = false;
2906
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002907 if (offset & 3) {
Dave Houlton142c4cb2018-10-17 15:04:41 -06002908 skip |= log_msg(
2909 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2910 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-offset-02145",
2911 "vkCmdDrawMeshTasksIndirectNV() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.", offset);
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002912 }
2913
2914 if (drawCount > 1 && ((stride & 3) || stride < sizeof(VkDrawMeshTasksIndirectCommandNV))) {
2915 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2916 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146",
2917 "vkCmdDrawMeshTasksIndirectNV() parameter, uint32_t stride (0x%" PRIxLEAST32
2918 "), is not a multiple of 4 or smaller than sizeof (VkDrawMeshTasksIndirectCommandNV).",
2919 stride);
2920 }
2921
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002922 if (!physical_device_features.multiDrawIndirect && ((drawCount > 1))) {
Jeff Bolzb574c342018-11-08 15:36:57 -06002923 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2924 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02147",
2925 "vkCmdDrawMeshTasksIndirectNV(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d",
2926 drawCount);
2927 }
2928
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002929 return skip;
2930}
2931
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002932bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
2933 VkDeviceSize offset, VkBuffer countBuffer,
2934 VkDeviceSize countBufferOffset,
2935 uint32_t maxDrawCount, uint32_t stride) {
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002936 bool skip = false;
2937
Jeff Bolz45bf7d62018-09-18 15:39:58 -05002938 if (offset & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002939 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 -05002940 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-offset-02180",
2941 "vkCmdDrawMeshTasksIndirectCountNV() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
2942 "), is not a multiple of 4.",
2943 offset);
2944 }
2945
2946 if (countBufferOffset & 3) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002947 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 -05002948 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBufferOffset-02181",
2949 "vkCmdDrawMeshTasksIndirectCountNV() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
2950 "), is not a multiple of 4.",
2951 countBufferOffset);
2952 }
2953
2954 if ((stride & 3) || stride < sizeof(VkDrawMeshTasksIndirectCommandNV)) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002955 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 -05002956 HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-stride-02182",
2957 "vkCmdDrawMeshTasksIndirectCountNV() parameter, uint32_t stride (0x%" PRIxLEAST32
2958 "), is not a multiple of 4 or smaller than sizeof (VkDrawMeshTasksIndirectCommandNV).",
2959 stride);
2960 }
2961
2962 return skip;
2963}
2964
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002965bool StatelessValidation::manual_PreCallValidateCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002966 const VkAllocationCallbacks *pAllocator,
2967 VkCommandPool *pCommandPool) {
2968 return ValidateDeviceQueueFamily(pCreateInfo->queueFamilyIndex, "vkCreateCommandPool", "pCreateInfo->queueFamilyIndex",
2969 "VUID-vkCreateCommandPool-queueFamilyIndex-01937");
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002970}
2971
2972bool StatelessValidation::manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002973 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002974 bool skip = false;
2975
2976 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2977 if (pCreateInfo != nullptr) {
2978 // If queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, pipelineStatistics must be a valid combination of
2979 // VkQueryPipelineStatisticFlagBits values
2980 if ((pCreateInfo->queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) && (pCreateInfo->pipelineStatistics != 0) &&
2981 ((pCreateInfo->pipelineStatistics & (~AllVkQueryPipelineStatisticFlagBits)) != 0)) {
2982 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2983 "VUID-VkQueryPoolCreateInfo-queryType-00792",
2984 "vkCreateQueryPool(): if pCreateInfo->queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, "
2985 "pCreateInfo->pipelineStatistics must be a valid combination of VkQueryPipelineStatisticFlagBits "
2986 "values.");
2987 }
Mark Lobodzinskib7a26382018-07-02 13:14:26 -06002988 }
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002989 return skip;
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002990}
2991
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07002992bool StatelessValidation::manual_PreCallValidateEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
2993 const char *pLayerName, uint32_t *pPropertyCount,
2994 VkExtensionProperties *pProperties) {
2995 return validate_array("vkEnumerateDeviceExtensionProperties", "pPropertyCount", "pProperties", pPropertyCount, &pProperties,
2996 true, false, false, kVUIDUndefined, "VUID-vkEnumerateDeviceExtensionProperties-pProperties-parameter");
Mark Lobodzinskid4950072017-08-01 13:02:20 -06002997}
2998
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07002999void StatelessValidation::PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07003000 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3001 VkResult result) {
3002 if (result != VK_SUCCESS) return;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07003003 RecordRenderPass(*pRenderPass, pCreateInfo);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06003004}
3005
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07003006void StatelessValidation::PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07003007 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3008 VkResult result) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07003009 // Track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments)
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07003010 if (result != VK_SUCCESS) return;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07003011 RecordRenderPass(*pRenderPass, pCreateInfo);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06003012}
3013
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07003014void StatelessValidation::PostCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
3015 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07003016 // Track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments)
3017 renderpasses_states.erase(renderPass);
Mark Lobodzinskid4950072017-08-01 13:02:20 -06003018}
Jeff Bolz7e7e6e02019-01-11 22:53:41 -06003019
3020bool StatelessValidation::manual_PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
3021 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
3022 bool skip = false;
3023
3024 if (pAllocateInfo) {
3025 auto chained_prio_struct = lvl_find_in_chain<VkMemoryPriorityAllocateInfoEXT>(pAllocateInfo->pNext);
3026 if (chained_prio_struct && (chained_prio_struct->priority < 0.0f || chained_prio_struct->priority > 1.0f)) {
3027 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
3028 "VUID-VkMemoryPriorityAllocateInfoEXT-priority-02602",
3029 "priority (=%f) must be between `0` and `1`, inclusive.", chained_prio_struct->priority);
3030 }
3031 }
3032 return skip;
3033}